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 %#lx.\n", hr
);
126 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
127 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#lx.\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_amd(IDirectDraw2
*ddraw
)
153 return ddraw_is_vendor(ddraw
, 0x1002);
156 static BOOL
ddraw_is_intel(IDirectDraw2
*ddraw
)
158 return ddraw_is_vendor(ddraw
, 0x8086);
161 static BOOL
ddraw_is_nvidia(IDirectDraw2
*ddraw
)
163 return ddraw_is_vendor(ddraw
, 0x10de);
166 static BOOL
ddraw_is_vmware(IDirectDraw2
*ddraw
)
168 return ddraw_is_vendor(ddraw
, 0x15ad);
171 static BOOL
is_software_device_type(const GUID
*device_guid
)
173 return device_guid
!= &IID_IDirect3DHALDevice
;
176 static IDirectDrawSurface
*create_overlay(IDirectDraw2
*ddraw
,
177 unsigned int width
, unsigned int height
, DWORD format
)
179 IDirectDrawSurface
*surface
;
182 memset(&desc
, 0, sizeof(desc
));
183 desc
.dwSize
= sizeof(desc
);
184 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
185 desc
.dwWidth
= width
;
186 desc
.dwHeight
= height
;
187 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
188 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
189 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
190 desc
.ddpfPixelFormat
.dwFourCC
= format
;
192 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
197 static HWND
create_window(void)
199 RECT r
= {0, 0, 640, 480};
201 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
203 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
204 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
207 static DWORD WINAPI
create_window_thread_proc(void *param
)
209 struct create_window_thread_param
*p
= param
;
213 p
->window
= create_window();
214 ret
= SetEvent(p
->window_created
);
215 ok(ret
, "SetEvent failed, last error %lu.\n", GetLastError());
221 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
222 DispatchMessageA(&msg
);
223 res
= WaitForSingleObject(p
->destroy_window
, 100);
224 if (res
== WAIT_OBJECT_0
)
226 if (res
!= WAIT_TIMEOUT
)
228 ok(0, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
233 DestroyWindow(p
->window
);
238 static void create_window_thread(struct create_window_thread_param
*p
)
242 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
243 ok(!!p
->window_created
, "CreateEvent failed, last error %lu.\n", GetLastError());
244 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
245 ok(!!p
->destroy_window
, "CreateEvent failed, last error %lu.\n", GetLastError());
246 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
247 ok(!!p
->thread
, "Failed to create thread, last error %lu.\n", GetLastError());
248 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
249 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
252 static void destroy_window_thread(struct create_window_thread_param
*p
)
254 SetEvent(p
->destroy_window
);
255 WaitForSingleObject(p
->thread
, INFINITE
);
256 CloseHandle(p
->destroy_window
);
257 CloseHandle(p
->window_created
);
258 CloseHandle(p
->thread
);
261 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
263 IDirectDrawSurface
*rt
, *ret
;
264 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
267 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
268 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
269 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
270 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#lx.\n", hr
);
271 IDirectDrawSurface_Release(rt
);
275 /* Free original_modes after finished using it */
276 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
278 unsigned int number
, size
= 2, count
= 0, index
= 0;
279 DISPLAY_DEVICEW display_device
;
280 DEVMODEW
*modes
, *tmp
;
282 if (!(modes
= heap_alloc(size
* sizeof(*modes
))))
285 display_device
.cb
= sizeof(display_device
);
286 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
288 /* Skip software devices */
289 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
292 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
298 if (!(tmp
= heap_realloc(modes
, size
* sizeof(*modes
))))
306 memset(&modes
[count
], 0, sizeof(modes
[count
]));
307 modes
[count
].dmSize
= sizeof(modes
[count
]);
308 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
314 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
317 *original_modes
= modes
;
318 *display_count
= count
;
322 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
327 for (index
= 0; index
< count
; ++index
)
329 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
330 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
331 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
334 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
335 return ret
== DISP_CHANGE_SUCCESSFUL
;
338 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
340 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
342 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
345 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
347 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
348 DDSURFACEDESC surface_desc
;
352 memset(&surface_desc
, 0, sizeof(surface_desc
));
353 surface_desc
.dwSize
= sizeof(surface_desc
);
355 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
356 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
360 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
362 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
363 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
368 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
370 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
375 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
376 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
378 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
380 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
381 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
387 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
388 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
391 static void check_rect(IDirectDrawSurface
*surface
, RECT r
)
393 LONG x_coords
[2][2] =
395 {r
.left
- 1, r
.left
+ 1},
396 {r
.right
+ 1, r
.right
- 1},
398 LONG y_coords
[2][2] =
400 {r
.top
- 1, r
.top
+ 1},
401 {r
.bottom
+ 1, r
.bottom
- 1}
403 unsigned int i
, j
, x_side
, y_side
, color
;
406 for (i
= 0; i
< 2; ++i
)
408 for (j
= 0; j
< 2; ++j
)
410 for (x_side
= 0; x_side
< 2; ++x_side
)
412 for (y_side
= 0; y_side
< 2; ++y_side
)
414 unsigned int expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
416 x
= x_coords
[i
][x_side
];
417 y
= y_coords
[j
][y_side
];
418 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
420 color
= get_surface_color(surface
, x
, y
);
421 ok(color
== expected
, "Pixel (%ld, %ld) has color %08x, expected %08x.\n", x
, y
, color
, expected
);
428 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
430 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
431 IDirectDrawSurface
*ds
, *rt
;
435 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
438 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
439 IDirectDrawSurface_Release(rt
);
443 desc
.dwSize
= sizeof(desc
);
444 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
445 IDirectDrawSurface_Release(ds
);
449 return U2(desc
).dwZBufferBitDepth
;
452 static IDirectDraw2
*create_ddraw(void)
454 IDirectDraw2
*ddraw2
;
458 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
461 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
462 IDirectDraw_Release(ddraw1
);
469 static IDirect3DDevice2
*create_device_ex(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
, const GUID
*device_guid
)
471 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
472 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
473 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
475 static const DWORD z_depths
[] = {16, 32, 24};
476 IDirectDrawSurface
*surface
, *ds
;
477 IDirect3DDevice2
*device
= NULL
;
478 DDSURFACEDESC surface_desc
;
483 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
484 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
486 memset(&surface_desc
, 0, sizeof(surface_desc
));
487 surface_desc
.dwSize
= sizeof(surface_desc
);
488 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
489 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
490 if (is_software_device_type(device_guid
))
491 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
492 surface_desc
.dwWidth
= 640;
493 surface_desc
.dwHeight
= 480;
495 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
496 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
498 if (coop_level
& DDSCL_NORMAL
)
500 IDirectDrawClipper
*clipper
;
502 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
503 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
504 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
505 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
506 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
507 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#lx.\n", hr
);
508 IDirectDrawClipper_Release(clipper
);
511 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
514 IDirectDrawSurface_Release(surface
);
518 /* We used to use EnumDevices() for this, but it seems
519 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
520 * relationship with reality. */
521 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
523 memset(&surface_desc
, 0, sizeof(surface_desc
));
524 surface_desc
.dwSize
= sizeof(surface_desc
);
525 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
526 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
527 if (is_software_device_type(device_guid
))
528 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
529 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
530 surface_desc
.dwWidth
= 640;
531 surface_desc
.dwHeight
= 480;
532 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
535 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
536 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
537 IDirectDrawSurface_Release(ds
);
541 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
)))
544 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
547 IDirect3D2_Release(d3d
);
548 IDirectDrawSurface_Release(surface
);
552 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
554 return create_device_ex(ddraw
, window
, coop_level
, &IID_IDirect3DHALDevice
);
557 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
559 IDirect3DViewport2
*viewport
;
564 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
565 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
566 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
567 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
568 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
569 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
570 memset(&vp
, 0, sizeof(vp
));
571 vp
.dwSize
= sizeof(vp
);
578 vp
.dvClipWidth
= 2.0f
;
579 vp
.dvClipHeight
= 2.0f
;
582 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
583 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
584 IDirect3D2_Release(d3d
);
589 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
590 IDirect3DMaterial2
*material
)
592 D3DMATERIALHANDLE material_handle
;
595 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
596 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
597 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
598 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
601 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
605 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
606 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
607 IDirect3DViewport2_Release(viewport
);
610 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
612 IDirect3DMaterial2
*material
;
616 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
617 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
618 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
619 ok(SUCCEEDED(hr
), "Failed to create material, hr %#lx.\n", hr
);
620 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
621 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
622 IDirect3D2_Release(d3d
);
627 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
631 memset(&mat
, 0, sizeof(mat
));
632 mat
.dwSize
= sizeof(mat
);
633 U1(U(mat
).diffuse
).r
= r
;
634 U2(U(mat
).diffuse
).g
= g
;
635 U3(U(mat
).diffuse
).b
= b
;
636 U4(U(mat
).diffuse
).a
= a
;
638 return create_material(device
, &mat
);
641 static IDirect3DMaterial2
*create_diffuse_and_ambient_material(IDirect3DDevice2
*device
,
642 float r
, float g
, float b
, float a
)
646 memset(&mat
, 0, sizeof(mat
));
647 mat
.dwSize
= sizeof(mat
);
648 U1(U(mat
).diffuse
).r
= r
;
649 U2(U(mat
).diffuse
).g
= g
;
650 U3(U(mat
).diffuse
).b
= b
;
651 U4(U(mat
).diffuse
).a
= a
;
653 U1(U(mat
).ambient
).r
= r
;
654 U2(U(mat
).ambient
).g
= g
;
655 U3(U(mat
).ambient
).b
= b
;
656 U4(U(mat
).ambient
).a
= a
;
658 return create_material(device
, &mat
);
661 static IDirect3DMaterial2
*create_specular_material(IDirect3DDevice2
*device
,
662 float r
, float g
, float b
, float a
, float power
)
666 memset(&mat
, 0, sizeof(mat
));
667 mat
.dwSize
= sizeof(mat
);
668 U1(U2(mat
).specular
).r
= r
;
669 U2(U2(mat
).specular
).g
= g
;
670 U3(U2(mat
).specular
).b
= b
;
671 U4(U2(mat
).specular
).a
= a
;
672 U4(mat
).power
= power
;
674 return create_material(device
, &mat
);
677 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
681 memset(&mat
, 0, sizeof(mat
));
682 mat
.dwSize
= sizeof(mat
);
683 U1(U3(mat
).emissive
).r
= r
;
684 U2(U3(mat
).emissive
).g
= g
;
685 U3(U3(mat
).emissive
).b
= b
;
686 U4(U3(mat
).emissive
).a
= a
;
688 return create_material(device
, &mat
);
691 static void destroy_material(IDirect3DMaterial2
*material
)
693 IDirect3DMaterial2_Release(material
);
700 WPARAM expect_wparam
;
703 static const struct message
*expect_messages
;
705 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
707 if (expect_messages
&& message
== expect_messages
->message
)
709 if (expect_messages
->check_wparam
)
710 ok (wparam
== expect_messages
->expect_wparam
,
711 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
712 wparam
, message
, expect_messages
->expect_wparam
);
717 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
720 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
721 * interface. This prevents subsequent SetCooperativeLevel() calls on a
722 * different window from failing with DDERR_HWNDALREADYSET. */
723 static void fix_wndproc(HWND window
, LONG_PTR proc
)
728 if (!(ddraw
= create_ddraw()))
731 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
732 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
733 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
734 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
735 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
737 IDirectDraw2_Release(ddraw
);
740 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
742 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
743 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#lx.\n", hr
);
744 IDirectDrawSurface_Release(surface
);
749 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
751 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
752 NULL
, NULL
, restore_callback
);
755 static void test_coop_level_create_device_window(void)
757 HWND focus_window
, device_window
;
761 focus_window
= create_window();
762 ddraw
= create_ddraw();
763 ok(!!ddraw
, "Failed to create a ddraw object.\n");
765 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
766 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
767 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
768 ok(!device_window
, "Unexpected device window found.\n");
769 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
770 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
771 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
772 ok(!device_window
, "Unexpected device window found.\n");
773 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
774 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
775 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
776 ok(!device_window
, "Unexpected device window found.\n");
777 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
778 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
779 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
780 ok(!device_window
, "Unexpected device window found.\n");
781 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
782 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#lx.\n", hr
);
783 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
784 ok(!device_window
, "Unexpected device window found.\n");
786 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
787 if (broken(hr
== DDERR_INVALIDPARAMS
))
789 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
790 IDirectDraw2_Release(ddraw
);
791 DestroyWindow(focus_window
);
795 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
796 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
797 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
798 ok(!device_window
, "Unexpected device window found.\n");
799 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
800 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
801 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
802 ok(!device_window
, "Unexpected device window found.\n");
804 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
805 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
806 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
807 ok(!device_window
, "Unexpected device window found.\n");
808 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
809 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
810 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#lx.\n", hr
);
811 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
812 ok(!!device_window
, "Device window not found.\n");
814 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
815 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
816 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
817 ok(!device_window
, "Unexpected device window found.\n");
818 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
819 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
820 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
821 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
822 ok(!!device_window
, "Device window not found.\n");
824 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
825 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
826 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
827 ok(!device_window
, "Unexpected device window found.\n");
828 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
829 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#lx.\n", hr
);
830 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
831 ok(!device_window
, "Unexpected device window found.\n");
832 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
833 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
834 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
835 ok(!device_window
, "Unexpected device window found.\n");
836 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
837 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
838 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
839 ok(!!device_window
, "Device window not found.\n");
841 IDirectDraw2_Release(ddraw
);
842 DestroyWindow(focus_window
);
845 static void test_clipper_blt(void)
847 IDirectDrawSurface
*src_surface
, *dst_surface
;
848 unsigned int color
, i
, j
, x
, y
;
849 RECT client_rect
, src_rect
;
850 IDirectDrawClipper
*clipper
;
851 DDSURFACEDESC surface_desc
;
862 static const DWORD src_data
[] =
864 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
865 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
866 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
868 static const unsigned int expected1
[] =
870 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
871 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
872 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
873 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
875 /* Nvidia on Windows seems to have an off-by-one error
876 * when processing source rectangles. Our left = 1 and
877 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
878 * read as well, but only for the edge pixels on the
879 * output image. The bug happens on the y axis as well,
880 * but we only read one row there, and all source rows
881 * contain the same data. This bug is not dependent on
882 * the presence of a clipper. */
883 static const D3DCOLOR expected1_broken
[] =
885 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
886 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
887 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
888 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
890 static const unsigned int expected2
[] =
892 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
893 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
894 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
895 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
898 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
899 10, 10, 640, 480, 0, 0, 0, 0);
900 ShowWindow(window
, SW_SHOW
);
901 ddraw
= create_ddraw();
902 ok(!!ddraw
, "Failed to create a ddraw object.\n");
904 ret
= GetClientRect(window
, &client_rect
);
905 ok(ret
, "Failed to get client rect.\n");
906 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
907 ok(ret
, "Failed to map client rect.\n");
909 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
910 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
912 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
913 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
914 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
915 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
916 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
917 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
918 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
919 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
920 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
921 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
922 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#lx.\n", hr
);
923 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#lx.\n", rgn_data
->rdh
.dwSize
);
924 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#lx.\n", rgn_data
->rdh
.iType
);
925 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %lu.\n", rgn_data
->rdh
.nCount
);
926 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
927 "Got unexpected bounding rect %s, expected %s.\n",
928 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
929 HeapFree(GetProcessHeap(), 0, rgn_data
);
931 r1
= CreateRectRgn(0, 0, 320, 240);
932 ok(!!r1
, "Failed to create region.\n");
933 r2
= CreateRectRgn(320, 240, 640, 480);
934 ok(!!r2
, "Failed to create region.\n");
935 CombineRgn(r1
, r1
, r2
, RGN_OR
);
936 ret
= GetRegionData(r1
, 0, NULL
);
937 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
938 ret
= GetRegionData(r1
, ret
, rgn_data
);
939 ok(!!ret
, "Failed to get region data.\n");
944 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
945 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#lx.\n", hr
);
946 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
947 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
948 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
949 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
951 HeapFree(GetProcessHeap(), 0, rgn_data
);
953 memset(&surface_desc
, 0, sizeof(surface_desc
));
954 surface_desc
.dwSize
= sizeof(surface_desc
);
955 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
956 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
957 surface_desc
.dwWidth
= 640;
958 surface_desc
.dwHeight
= 480;
959 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
960 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
961 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
962 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
963 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
964 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
966 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
967 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
968 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
969 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
971 memset(&fx
, 0, sizeof(fx
));
972 fx
.dwSize
= sizeof(fx
);
973 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
974 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
975 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
976 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
978 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
979 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
980 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %lu.\n", U1(surface_desc
).lPitch
);
981 ptr
= surface_desc
.lpSurface
;
982 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
983 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
984 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
985 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
986 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
988 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
989 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
991 SetRect(&src_rect
, 1, 1, 5, 2);
992 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
993 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
994 for (i
= 0; i
< 4; ++i
)
996 for (j
= 0; j
< 4; ++j
)
998 x
= 80 * ((2 * j
) + 1);
999 y
= 60 * ((2 * i
) + 1);
1000 color
= get_surface_color(dst_surface
, x
, y
);
1001 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1002 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1003 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1007 U5(fx
).dwFillColor
= 0xff0000ff;
1008 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1009 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1010 for (i
= 0; i
< 4; ++i
)
1012 for (j
= 0; j
< 4; ++j
)
1014 x
= 80 * ((2 * j
) + 1);
1015 y
= 60 * ((2 * i
) + 1);
1016 color
= get_surface_color(dst_surface
, x
, y
);
1017 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1018 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1022 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1023 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#lx.\n", hr
);
1025 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1026 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1027 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1028 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1029 DestroyWindow(window
);
1030 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1031 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
1032 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1033 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1034 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1035 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1036 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1037 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1038 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1039 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1040 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1041 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1043 IDirectDrawSurface_Release(dst_surface
);
1044 IDirectDrawSurface_Release(src_surface
);
1045 refcount
= IDirectDrawClipper_Release(clipper
);
1046 ok(!refcount
, "Clipper has %lu references left.\n", refcount
);
1047 IDirectDraw2_Release(ddraw
);
1050 static void test_coop_level_d3d_state(void)
1052 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1053 IDirectDrawSurface
*rt
, *surface
;
1054 IDirect3DMaterial2
*background
;
1055 IDirect3DViewport2
*viewport
;
1056 IDirect3DDevice2
*device
;
1057 D3DMATERIAL material
;
1058 IDirectDraw2
*ddraw
;
1065 static D3DLVERTEX quad
[] =
1067 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0x800000ff}},
1068 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0x800000ff}},
1069 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0x800000ff}},
1070 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0x800000ff}},
1073 window
= create_window();
1074 ddraw
= create_ddraw();
1075 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1077 if (ddraw_is_warp(ddraw
))
1079 /* ddraw2 crashes in EndScene, and if it doesn't crash it fails with
1080 * DDERR_SURFACELOST on WARP. */
1081 win_skip("Skipping test that crashes WARP occasionally.\n");
1082 IDirectDraw2_Release(ddraw
);
1083 DestroyWindow(window
);
1087 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1089 skip("Failed to create a 3D device, skipping test.\n");
1090 IDirectDraw2_Release(ddraw
);
1091 DestroyWindow(window
);
1095 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1096 viewport
= create_viewport(device
, 0, 0, 640, 480);
1097 viewport_set_background(device
, viewport
, background
);
1099 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1100 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1101 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
1102 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1104 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1105 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1106 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1107 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1108 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1109 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1110 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1111 ok(!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1112 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1113 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1114 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1115 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1116 color
= get_surface_color(rt
, 320, 240);
1117 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1119 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1120 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1121 hr
= IDirectDrawSurface_IsLost(rt
);
1122 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1124 memset(&lock
, 0, sizeof(lock
));
1125 lock
.dwSize
= sizeof(lock
);
1126 lock
.lpSurface
= (void *)0xdeadbeef;
1127 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1128 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1129 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1131 hr
= restore_surfaces(ddraw
);
1132 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1134 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1135 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1136 hr
= IDirectDrawSurface2_Unlock(rt
, NULL
);
1137 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1139 memset(&material
, 0, sizeof(material
));
1140 material
.dwSize
= sizeof(material
);
1141 U1(U(material
).diffuse
).r
= 0.0f
;
1142 U2(U(material
).diffuse
).g
= 1.0f
;
1143 U3(U(material
).diffuse
).b
= 0.0f
;
1144 U4(U(material
).diffuse
).a
= 1.0f
;
1145 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
1146 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1148 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
1149 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1150 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1151 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1152 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1153 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1154 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1155 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1156 ok(!!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1157 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1158 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1159 color
= get_surface_color(rt
, 320, 240);
1160 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1161 "Got unexpected color 0x%08x.\n", color
);
1163 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1164 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1165 hr
= IDirect3DDevice2_BeginScene(device
);
1166 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1167 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
1168 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1169 hr
= IDirect3DDevice2_EndScene(device
);
1170 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1171 color
= get_surface_color(rt
, 320, 240);
1172 ok(compare_color(color
, 0x0000ff80, 1), "Got unexpected color 0x%08x.\n", color
);
1174 destroy_viewport(device
, viewport
);
1175 destroy_material(background
);
1176 IDirectDrawSurface_Release(surface
);
1177 IDirectDrawSurface_Release(rt
);
1178 IDirect3DDevice2_Release(device
);
1179 IDirectDraw2_Release(ddraw
);
1180 DestroyWindow(window
);
1183 static void test_surface_interface_mismatch(void)
1185 IDirectDraw2
*ddraw
= NULL
;
1186 IDirect3D2
*d3d
= NULL
;
1187 IDirectDrawSurface
*surface
= NULL
, *ds
;
1188 IDirectDrawSurface3
*surface3
= NULL
;
1189 IDirect3DDevice2
*device
= NULL
;
1190 IDirect3DViewport2
*viewport
= NULL
;
1191 IDirect3DMaterial2
*background
= NULL
;
1192 DDSURFACEDESC surface_desc
;
1198 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1200 window
= create_window();
1201 ddraw
= create_ddraw();
1202 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1203 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1205 skip("Failed to create a 3D device, skipping test.\n");
1206 IDirectDraw2_Release(ddraw
);
1207 DestroyWindow(window
);
1210 z_depth
= get_device_z_depth(device
);
1211 ok(!!z_depth
, "Failed to get device z depth.\n");
1212 IDirect3DDevice2_Release(device
);
1215 memset(&surface_desc
, 0, sizeof(surface_desc
));
1216 surface_desc
.dwSize
= sizeof(surface_desc
);
1217 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1218 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1219 surface_desc
.dwWidth
= 640;
1220 surface_desc
.dwHeight
= 480;
1222 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1223 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
1225 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1228 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1232 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
1234 skip("D3D interface is not available, skipping test.\n");
1238 memset(&surface_desc
, 0, sizeof(surface_desc
));
1239 surface_desc
.dwSize
= sizeof(surface_desc
);
1240 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1241 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1242 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
1243 surface_desc
.dwWidth
= 640;
1244 surface_desc
.dwHeight
= 480;
1245 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1246 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
1250 /* Using a different surface interface version still works */
1251 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1252 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
1253 refcount
= IDirectDrawSurface_Release(ds
);
1254 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
1259 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
1260 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1264 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1265 viewport
= create_viewport(device
, 0, 0, 640, 480);
1266 viewport_set_background(device
, viewport
, background
);
1268 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1269 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
1270 color
= get_surface_color(surface
, 320, 240);
1271 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1275 destroy_viewport(device
, viewport
);
1277 destroy_material(background
);
1278 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1279 if (surface
) IDirectDrawSurface_Release(surface
);
1280 if (device
) IDirect3DDevice2_Release(device
);
1281 if (d3d
) IDirect3D2_Release(d3d
);
1282 if (ddraw
) IDirectDraw2_Release(ddraw
);
1283 DestroyWindow(window
);
1286 static void test_coop_level_threaded(void)
1288 struct create_window_thread_param p
;
1289 IDirectDraw2
*ddraw
;
1292 ddraw
= create_ddraw();
1293 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1294 create_window_thread(&p
);
1296 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1297 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1299 destroy_window_thread(&p
);
1300 IDirectDraw2_Release(ddraw
);
1303 static void test_depth_blit(const GUID
*device_guid
)
1305 static D3DLVERTEX quad1
[] =
1307 {{-1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1308 {{ 1.0}, { 1.0}, {0.50f
}, 0, {0xff00ff00}},
1309 {{-1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1310 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1312 static const unsigned int expected_colors
[4][4] =
1314 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1315 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1316 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1317 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1319 DDSURFACEDESC ddsd_new
, ddsd_existing
;
1321 IDirect3DDevice2
*device
;
1322 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
1323 BOOL depth_fill_broken
= FALSE
;
1324 IDirect3DViewport2
*viewport
;
1325 RECT src_rect
, dst_rect
;
1326 unsigned int color
, i
, j
;
1328 IDirectDraw2
*ddraw
;
1332 IDirect3DMaterial2
*background
;
1334 window
= create_window();
1335 ddraw
= create_ddraw();
1336 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1337 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1339 skip("Failed to create a 3D device, skipping test.\n");
1340 IDirectDraw2_Release(ddraw
);
1341 DestroyWindow(window
);
1345 ds1
= get_depth_stencil(device
);
1347 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1348 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1349 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1350 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1351 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
1352 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1353 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1354 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1355 if (is_software_device_type(device_guid
))
1356 ddsd_new
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1357 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1358 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1359 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
1360 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1361 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1362 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1363 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1365 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1366 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1367 viewport_set_background(device
, viewport
, background
);
1368 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1369 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
1371 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1372 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#lx.\n", hr
);
1373 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1374 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#lx.\n", hr
);
1376 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1377 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1378 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
1379 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#lx.\n", hr
);
1382 SetRect(&src_rect
, 0, 0, 320, 240);
1383 SetRect(&dst_rect
, 0, 0, 320, 240);
1384 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1385 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1386 /* Different locations. */
1387 SetRect(&src_rect
, 0, 0, 320, 240);
1388 SetRect(&dst_rect
, 320, 240, 640, 480);
1389 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1390 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1392 SetRect(&src_rect
, 0, 0, 320, 240);
1393 SetRect(&dst_rect
, 0, 0, 640, 480);
1394 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1395 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1397 SetRect(&src_rect
, 0, 480, 640, 0);
1398 SetRect(&dst_rect
, 0, 0, 640, 480);
1399 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1400 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1401 SetRect(&src_rect
, 0, 0, 640, 480);
1402 SetRect(&dst_rect
, 0, 480, 640, 0);
1403 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1404 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1405 /* Full, explicit. */
1406 SetRect(&src_rect
, 0, 0, 640, 480);
1407 SetRect(&dst_rect
, 0, 0, 640, 480);
1408 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1409 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1410 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1412 /* Depth blit inside a BeginScene / EndScene pair */
1413 hr
= IDirect3DDevice2_BeginScene(device
);
1414 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#lx.\n", hr
);
1415 /* From the current depth stencil */
1416 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1417 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1418 /* To the current depth stencil */
1419 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1420 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1421 /* Between unbound surfaces */
1422 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1423 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1424 hr
= IDirect3DDevice2_EndScene(device
);
1425 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#lx.\n", hr
);
1427 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1428 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1429 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1430 * a reliable result(z = 0.0) */
1431 memset(&fx
, 0, sizeof(fx
));
1432 fx
.dwSize
= sizeof(fx
);
1433 U5(fx
).dwFillDepth
= 0;
1434 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1435 ok(hr
== D3D_OK
|| broken(is_software_device_type(device_guid
)
1436 && hr
== 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#lx.\n", hr
);
1438 depth_fill_broken
= TRUE
;
1440 /* This clears the Z buffer with 1.0 */
1441 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1442 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1444 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1445 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1447 color
= get_surface_color(rt
, 80, 60);
1448 /* For some reason clears and colour fill blits randomly fail with software render target. */
1449 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1450 "Got unexpected colour 0x%08x.\n", color
);
1453 fill_surface(rt
, 0xffff0000);
1455 color
= get_surface_color(rt
, 80, 60);
1456 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1459 SetRect(&dst_rect
, 0, 0, 320, 240);
1460 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1461 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1462 IDirectDrawSurface_Release(ds3
);
1463 IDirectDrawSurface_Release(ds2
);
1464 IDirectDrawSurface_Release(ds1
);
1466 hr
= IDirect3DDevice2_BeginScene(device
);
1467 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1468 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1469 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1470 hr
= IDirect3DDevice2_EndScene(device
);
1471 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1473 for (i
= 0; i
< 4; ++i
)
1475 for (j
= 0; j
< 4; ++j
)
1477 unsigned int x
= 80 * ((2 * j
) + 1);
1478 unsigned int y
= 60 * ((2 * i
) + 1);
1479 color
= get_surface_color(rt
, x
, y
);
1480 ok(compare_color(color
, expected_colors
[i
][j
], 1) || broken(depth_fill_broken
&& color
== 0x0000ff00),
1481 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1484 IDirectDrawSurface_Release(rt
);
1486 destroy_viewport(device
, viewport
);
1487 destroy_material(background
);
1488 IDirect3DDevice2_Release(device
);
1489 IDirectDraw2_Release(ddraw
);
1490 DestroyWindow(window
);
1493 static void test_texture_load_ckey(void)
1495 IDirectDraw2
*ddraw
= NULL
;
1496 IDirectDrawSurface
*src
= NULL
;
1497 IDirectDrawSurface
*dst
= NULL
;
1498 IDirect3DTexture
*src_tex
= NULL
;
1499 IDirect3DTexture
*dst_tex
= NULL
;
1504 ddraw
= create_ddraw();
1505 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1506 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1507 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1509 memset(&ddsd
, 0, sizeof(ddsd
));
1510 ddsd
.dwSize
= sizeof(ddsd
);
1511 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1512 ddsd
.dwHeight
= 128;
1514 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1515 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1516 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#lx.\n", hr
);
1517 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1518 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1519 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#lx.\n", hr
);
1521 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1522 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#lx.\n", hr
);
1525 /* 64 bit ddraw does not support d3d */
1526 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1529 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1530 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#lx.\n", hr
);
1532 /* No surface has a color key */
1533 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1534 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#lx.\n", hr
);
1537 /* Testbot Windows NT VMs */
1538 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1542 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1543 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1544 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1545 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1546 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1548 /* Source surface has a color key */
1549 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1550 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1551 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1552 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1553 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1554 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1555 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1556 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1557 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1559 /* Both surfaces have a color key: Dest ckey is overwritten */
1560 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1561 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1562 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1563 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1564 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1565 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1566 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1567 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1568 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1570 /* Only the destination has a color key: It is not deleted */
1571 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1572 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1573 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1574 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1575 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1576 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1577 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1578 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1579 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1580 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1583 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1584 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1585 if (dst
) IDirectDrawSurface_Release(dst
);
1586 if (src
) IDirectDrawSurface_Release(src
);
1587 if (ddraw
) IDirectDraw2_Release(ddraw
);
1590 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1592 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1593 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1594 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1595 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1598 static ULONG
get_refcount(IUnknown
*test_iface
)
1600 IUnknown_AddRef(test_iface
);
1601 return IUnknown_Release(test_iface
);
1604 static void test_viewport_object(void)
1606 IDirectDraw2
*ddraw
;
1609 ULONG ref
, old_d3d_ref
;
1612 IDirect3DViewport
*viewport
;
1613 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1614 IDirect3DViewport3
*viewport3
;
1615 IDirectDrawGammaControl
*gamma
;
1617 IDirect3DDevice2
*device
;
1626 window
= create_window();
1627 ddraw
= create_ddraw();
1628 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1629 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1631 skip("Failed to create a 3D device, skipping test.\n");
1632 IDirectDraw2_Release(ddraw
);
1633 DestroyWindow(window
);
1637 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1638 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#lx.\n", hr
);
1641 skip("D3D interface is not available, skipping test.\n");
1642 IDirectDraw2_Release(ddraw
);
1645 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1647 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1648 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
1649 ref
= get_refcount((IUnknown
*)viewport2
);
1650 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1651 ref
= get_refcount((IUnknown
*)d3d
);
1652 ok(ref
== old_d3d_ref
, "Got unexpected refcount %lu.\n", ref
);
1654 memset(&desc
, 0, sizeof(desc
));
1655 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1656 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1657 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1658 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1659 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1660 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1661 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1662 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1663 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1664 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1665 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1666 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %lu.\n", desc
.vp1
.dwSize
);
1667 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1668 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1669 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %lu.\n", desc
.vp2
.dwSize
);
1670 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1671 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1672 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1674 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1675 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1676 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
1677 ok(!gamma
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1678 /* NULL iid: Segfaults */
1680 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1681 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#lx.\n", hr
);
1682 ref
= get_refcount((IUnknown
*)viewport
);
1683 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1684 ref
= get_refcount((IUnknown
*)viewport2
);
1685 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1686 IDirect3DViewport_Release(viewport
);
1689 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1690 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#lx.\n", hr
);
1693 ref
= get_refcount((IUnknown
*)viewport2
);
1694 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1695 ref
= get_refcount((IUnknown
*)viewport3
);
1696 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1697 IDirect3DViewport3_Release(viewport3
);
1700 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1701 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#lx.\n", hr
);
1702 ref
= get_refcount((IUnknown
*)viewport2
);
1703 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1704 ref
= get_refcount(unknown
);
1705 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1706 IUnknown_Release(unknown
);
1708 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1709 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1710 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1711 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1713 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1714 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
1716 /* Setting a viewport not in the viewport list fails */
1717 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1718 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1720 /* AddViewport(NULL): Segfault */
1721 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1722 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#lx.\n", hr
);
1723 ref
= get_refcount((IUnknown
*) viewport2
);
1724 ok(ref
== 2, "viewport2 refcount is %lu.\n", ref
);
1725 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1726 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#lx.\n", hr
);
1727 ref
= get_refcount((IUnknown
*) another_vp
);
1728 ok(ref
== 2, "another_vp refcount is %lu.\n", ref
);
1730 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1731 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1732 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1733 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1735 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1736 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1737 ref
= get_refcount((IUnknown
*) viewport2
);
1738 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1739 ref
= get_refcount((IUnknown
*) device
);
1740 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1743 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1744 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1745 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1746 ref
= get_refcount((IUnknown
*) viewport2
);
1747 ok(ref
== 4, "Got unexpected refcount %lu.\n", ref
);
1749 IDirect3DViewport2_Release(test_vp
);
1751 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1753 /* Cannot set the viewport to NULL */
1754 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1755 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#lx.\n", hr
);
1757 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1758 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1759 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1761 IDirect3DViewport2_Release(test_vp
);
1763 /* SetCurrentViewport properly releases the old viewport's reference */
1764 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1765 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1766 ref
= get_refcount((IUnknown
*) viewport2
);
1767 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1768 ref
= get_refcount((IUnknown
*) another_vp
);
1769 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1771 /* Deleting the viewport removes the reference added by AddViewport, but not
1772 * the one added by SetCurrentViewport. */
1773 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1774 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#lx.\n", hr
);
1775 ref
= get_refcount((IUnknown
*) another_vp
);
1776 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1778 /* GetCurrentViewport fails though */
1780 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1781 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1782 ok(!test_vp
, "Got unexpected viewport %p\n", test_vp
);
1784 /* Setting a different viewport does not free the leaked reference. How
1785 * do I get rid of it? Leak the viewport for now. */
1786 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1787 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1788 ref
= get_refcount((IUnknown
*) viewport2
);
1789 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1790 ref
= get_refcount((IUnknown
*) another_vp
);
1791 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1793 memset(&vp
, 0, sizeof(vp
));
1794 memset(&vp
, 0, sizeof(vp2
));
1795 vp
.dwX
= vp2
.dwX
= 0;
1796 vp
.dwY
= vp2
.dwY
= 0;
1797 vp
.dwWidth
= vp2
.dwWidth
= 640;
1798 vp
.dwHeight
= vp2
.dwHeight
= 480;
1799 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1800 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1801 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1802 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1805 vp2
.dvClipX
= -1.0f
;
1807 vp2
.dvClipWidth
= 2.0f
;
1808 vp2
.dvClipHeight
= 2.0f
;
1809 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1810 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1811 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1812 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1814 vp
.dwSize
= sizeof(vp
);
1815 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1816 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
1817 vp2
.dwSize
= sizeof(vp2
);
1818 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1819 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
1821 /* Destroying the device removes the viewport, but does not free the reference
1822 * added by SetCurrentViewport. */
1823 IDirect3DDevice2_Release(device
);
1824 ref
= get_refcount((IUnknown
*) viewport2
);
1825 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1827 vp
.dwSize
= sizeof(vp
);
1828 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1829 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1830 vp2
.dwSize
= sizeof(vp2
);
1831 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1832 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1834 IDirect3DViewport2_Release(another_vp
);
1835 IDirect3DViewport2_Release(viewport2
);
1836 IDirect3D2_Release(d3d
);
1837 DestroyWindow(window
);
1838 IDirectDraw2_Release(ddraw
);
1841 static void test_zenable(const GUID
*device_guid
)
1843 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1844 static D3DTLVERTEX tquad
[] =
1846 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1847 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1848 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1849 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1851 IDirect3DMaterial2
*background
;
1852 unsigned int color
, x
, y
, i
, j
;
1853 IDirect3DViewport2
*viewport
;
1854 IDirect3DDevice2
*device
;
1855 IDirectDrawSurface
*rt
;
1856 IDirectDraw2
*ddraw
;
1860 window
= create_window();
1861 ddraw
= create_ddraw();
1862 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1863 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1865 skip("Failed to create a 3D device, skipping test.\n");
1866 IDirectDraw2_Release(ddraw
);
1867 DestroyWindow(window
);
1871 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1872 viewport
= create_viewport(device
, 0, 0, 640, 480);
1873 viewport_set_background(device
, viewport
, background
);
1874 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1875 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1877 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1878 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1880 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1881 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1883 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1884 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1886 color
= get_surface_color(rt
, 80, 60);
1887 /* For some reason clears and colour fill blits randomly fail with software render target. */
1888 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1889 "Got unexpected colour 0x%08x.\n", color
);
1892 fill_surface(rt
, 0xffff0000);
1894 color
= get_surface_color(rt
, 80, 60);
1895 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1898 hr
= IDirect3DDevice2_BeginScene(device
);
1899 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1900 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1901 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1902 hr
= IDirect3DDevice2_EndScene(device
);
1903 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1905 for (i
= 0; i
< 4; ++i
)
1907 for (j
= 0; j
< 4; ++j
)
1909 x
= 80 * ((2 * j
) + 1);
1910 y
= 60 * ((2 * i
) + 1);
1911 color
= get_surface_color(rt
, x
, y
);
1912 ok(compare_color(color
, 0x0000ff00, 1),
1913 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1916 IDirectDrawSurface_Release(rt
);
1918 destroy_viewport(device
, viewport
);
1919 destroy_material(background
);
1920 IDirect3DDevice2_Release(device
);
1921 IDirectDraw2_Release(ddraw
);
1922 DestroyWindow(window
);
1925 static void test_ck_rgba(const GUID
*device_guid
)
1927 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1928 static D3DTLVERTEX tquad
[] =
1930 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1931 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1932 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1933 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1934 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1935 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1936 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1937 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1941 D3DCOLOR fill_color
;
1944 unsigned int result1
, result1_broken
;
1945 unsigned int result2
, result2_broken
;
1949 /* r200 on Windows doesn't check the alpha component when applying the color
1950 * key, so the key matches on every texel. */
1951 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1952 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1953 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1954 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1955 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1956 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1957 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1958 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1961 D3DTEXTUREHANDLE texture_handle
;
1962 IDirect3DMaterial2
*background
;
1963 IDirectDrawSurface
*surface
;
1964 IDirect3DViewport2
*viewport
;
1965 IDirect3DTexture2
*texture
;
1966 DDSURFACEDESC surface_desc
;
1967 IDirect3DDevice2
*device
;
1968 IDirectDrawSurface
*rt
;
1969 unsigned int color
, i
;
1970 IDirectDraw2
*ddraw
;
1975 window
= create_window();
1976 ddraw
= create_ddraw();
1977 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1978 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1980 skip("Failed to create a 3D device, skipping test.\n");
1981 IDirectDraw2_Release(ddraw
);
1982 DestroyWindow(window
);
1986 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1987 viewport
= create_viewport(device
, 0, 0, 640, 480);
1988 viewport_set_background(device
, viewport
, background
);
1989 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1990 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1992 memset(&surface_desc
, 0, sizeof(surface_desc
));
1993 surface_desc
.dwSize
= sizeof(surface_desc
);
1994 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1995 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1996 if (is_software_device_type(device_guid
))
1997 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1998 surface_desc
.dwWidth
= 256;
1999 surface_desc
.dwHeight
= 256;
2000 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2001 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
2002 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
2003 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2004 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2005 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2006 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
2007 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
2008 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
2009 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2010 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2011 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2012 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2013 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
2014 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2015 IDirect3DTexture2_Release(texture
);
2017 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2018 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2019 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
2020 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2021 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2022 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2024 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2025 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2027 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2029 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
2030 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2031 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
2032 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2034 memset(&fx
, 0, sizeof(fx
));
2035 fx
.dwSize
= sizeof(fx
);
2036 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
2037 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2038 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2040 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
2041 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2042 /* RT clears are broken on Windows for software render target. */
2043 if (is_software_device_type(device_guid
))
2044 fill_surface(rt
, 0xffff0000);
2046 hr
= IDirect3DDevice2_BeginScene(device
);
2047 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2048 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2049 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2050 hr
= IDirect3DDevice2_EndScene(device
);
2051 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2053 color
= get_surface_color(rt
, 320, 240);
2054 ok(compare_color(color
, tests
[i
].result1
, 2) || compare_color(color
, tests
[i
].result1_broken
, 1),
2055 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2056 tests
[i
].result1
, i
, color
);
2058 U5(fx
).dwFillColor
= 0xff0000ff;
2059 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2060 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2062 hr
= IDirect3DDevice2_BeginScene(device
);
2063 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2064 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
2065 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2066 hr
= IDirect3DDevice2_EndScene(device
);
2067 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2069 /* This tests that fragments that are masked out by the color key are
2070 * discarded, instead of just fully transparent. */
2071 color
= get_surface_color(rt
, 320, 240);
2072 ok(compare_color(color
, tests
[i
].result2
, 2) || compare_color(color
, tests
[i
].result2_broken
, 1),
2073 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2074 tests
[i
].result2
, i
, color
);
2077 IDirectDrawSurface_Release(rt
);
2078 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2079 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2080 IDirectDrawSurface_Release(surface
);
2081 destroy_viewport(device
, viewport
);
2082 destroy_material(background
);
2083 IDirect3DDevice2_Release(device
);
2084 IDirectDraw2_Release(ddraw
);
2085 DestroyWindow(window
);
2088 static void test_ck_default(void)
2090 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2091 static D3DTLVERTEX tquad
[] =
2093 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
2094 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
2095 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
2096 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
2098 IDirectDrawSurface
*surface
, *rt
;
2099 D3DTEXTUREHANDLE texture_handle
;
2100 IDirect3DMaterial2
*background
;
2101 IDirect3DViewport2
*viewport
;
2102 DDSURFACEDESC surface_desc
;
2103 IDirect3DTexture2
*texture
;
2104 IDirect3DDevice2
*device
;
2105 IDirectDraw2
*ddraw
;
2112 window
= create_window();
2113 ddraw
= create_ddraw();
2114 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2115 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2117 skip("Failed to create a 3D device, skipping test.\n");
2118 IDirectDraw2_Release(ddraw
);
2119 DestroyWindow(window
);
2123 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2124 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
2126 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
2127 viewport
= create_viewport(device
, 0, 0, 640, 480);
2128 viewport_set_background(device
, viewport
, background
);
2129 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
2130 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
2132 memset(&surface_desc
, 0, sizeof(surface_desc
));
2133 surface_desc
.dwSize
= sizeof(surface_desc
);
2134 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2135 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2136 surface_desc
.dwWidth
= 256;
2137 surface_desc
.dwHeight
= 256;
2138 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2139 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2140 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
2141 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2142 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2143 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2144 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2145 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2146 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2147 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2148 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2149 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
2150 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
2151 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
2152 IDirect3DTexture_Release(texture
);
2154 memset(&fx
, 0, sizeof(fx
));
2155 fx
.dwSize
= sizeof(fx
);
2156 U5(fx
).dwFillColor
= 0x000000ff;
2157 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2158 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
2160 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2161 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2162 hr
= IDirect3DDevice2_BeginScene(device
);
2163 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2164 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2165 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
2166 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2167 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2168 ok(!value
, "Got unexpected color keying state %#lx.\n", value
);
2169 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2170 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2171 hr
= IDirect3DDevice2_EndScene(device
);
2172 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2173 color
= get_surface_color(rt
, 320, 240);
2174 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2176 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2177 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2178 hr
= IDirect3DDevice2_BeginScene(device
);
2179 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2180 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2181 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
2182 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2183 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2184 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2185 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2186 ok(!!value
, "Got unexpected color keying state %#lx.\n", value
);
2187 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2188 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
2189 hr
= IDirect3DDevice2_EndScene(device
);
2190 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2191 color
= get_surface_color(rt
, 320, 240);
2192 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2194 IDirectDrawSurface_Release(surface
);
2195 destroy_viewport(device
, viewport
);
2196 destroy_material(background
);
2197 IDirectDrawSurface_Release(rt
);
2198 IDirect3DDevice2_Release(device
);
2199 IDirectDraw2_Release(ddraw
);
2200 DestroyWindow(window
);
2203 static void test_ck_complex(void)
2205 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
2206 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
2207 DDSURFACEDESC surface_desc
;
2208 IDirect3DDevice2
*device
;
2209 DDCOLORKEY color_key
;
2210 IDirectDraw2
*ddraw
;
2216 window
= create_window();
2217 ddraw
= create_ddraw();
2218 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2219 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2221 skip("Failed to create a 3D device, skipping test.\n");
2222 DestroyWindow(window
);
2223 IDirectDraw2_Release(ddraw
);
2226 IDirect3DDevice2_Release(device
);
2228 memset(&surface_desc
, 0, sizeof(surface_desc
));
2229 surface_desc
.dwSize
= sizeof(surface_desc
);
2230 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2231 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2232 surface_desc
.dwWidth
= 128;
2233 surface_desc
.dwHeight
= 128;
2234 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2235 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2237 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2238 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2239 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2240 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2241 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2242 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2243 memset(&color_key
, 0, sizeof(color_key
));
2244 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2245 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2246 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2247 color_key
.dwColorSpaceLowValue
);
2248 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2249 color_key
.dwColorSpaceHighValue
);
2252 IDirectDrawSurface_AddRef(mipmap
);
2253 for (i
= 0; i
< 7; ++i
)
2255 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2256 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
2258 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2259 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2260 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2261 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2262 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2263 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx, i %u.\n", hr
, i
);
2264 memset(&color_key
, 0, sizeof(color_key
));
2265 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2266 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx, i %u.\n", hr
, i
);
2267 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2268 color_key
.dwColorSpaceLowValue
, i
);
2269 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2270 color_key
.dwColorSpaceHighValue
, i
);
2272 IDirectDrawSurface_Release(mipmap
);
2276 memset(&color_key
, 0, sizeof(color_key
));
2277 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2278 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2279 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2280 color_key
.dwColorSpaceLowValue
);
2281 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2282 color_key
.dwColorSpaceHighValue
);
2284 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2285 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
2286 IDirectDrawSurface_Release(mipmap
);
2287 refcount
= IDirectDrawSurface_Release(surface
);
2288 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2290 memset(&surface_desc
, 0, sizeof(surface_desc
));
2291 surface_desc
.dwSize
= sizeof(surface_desc
);
2292 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2293 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2294 surface_desc
.dwBackBufferCount
= 1;
2295 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2296 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2298 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2299 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2300 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2301 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2302 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2303 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2304 memset(&color_key
, 0, sizeof(color_key
));
2305 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2306 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2307 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2308 color_key
.dwColorSpaceLowValue
);
2309 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2310 color_key
.dwColorSpaceHighValue
);
2312 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2313 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
2315 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2316 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2317 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2318 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2319 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2320 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2321 memset(&color_key
, 0, sizeof(color_key
));
2322 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2323 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2324 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2325 color_key
.dwColorSpaceLowValue
);
2326 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2327 color_key
.dwColorSpaceHighValue
);
2329 IDirectDrawSurface_Release(tmp
);
2331 refcount
= IDirectDrawSurface_Release(surface
);
2332 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2333 refcount
= IDirectDraw2_Release(ddraw
);
2334 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2335 DestroyWindow(window
);
2341 REFIID refcount_iid
;
2345 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2346 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2348 ULONG refcount
, expected_refcount
;
2349 IUnknown
*iface1
, *iface2
;
2353 for (i
= 0; i
< entry_count
; ++i
)
2355 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2356 ok(hr
== tests
[i
].hr
, "Got hr %#lx for test \"%s\" %u.\n", hr
, test_name
, i
);
2359 for (j
= 0; j
< entry_count
; ++j
)
2361 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2362 ok(hr
== tests
[j
].hr
, "Got hr %#lx for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2365 expected_refcount
= 0;
2366 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2367 ++expected_refcount
;
2368 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2369 ++expected_refcount
;
2370 refcount
= IUnknown_Release(iface2
);
2371 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
2372 refcount
, test_name
, i
, j
, expected_refcount
);
2376 expected_refcount
= 0;
2377 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2378 ++expected_refcount
;
2379 refcount
= IUnknown_Release(iface1
);
2380 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
2381 refcount
, test_name
, i
, expected_refcount
);
2386 static void test_surface_qi(void)
2388 static const struct qi_test tests
[] =
2390 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2391 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2392 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2393 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2394 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2395 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2396 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2397 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2398 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2399 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2400 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2401 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2402 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2403 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2404 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2405 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2406 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2407 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2408 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2409 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2410 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2411 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2412 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2413 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2414 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2415 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2416 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2417 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2418 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2419 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2420 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2421 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2422 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2423 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2424 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2425 {NULL
, NULL
, E_INVALIDARG
},
2428 IDirectDrawSurface
*surface
;
2429 DDSURFACEDESC surface_desc
;
2430 IDirect3DDevice2
*device
;
2431 IDirectDraw2
*ddraw
;
2435 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2437 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2441 window
= create_window();
2442 ddraw
= create_ddraw();
2443 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2444 /* Try to create a D3D device to see if the ddraw implementation supports
2445 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2446 * doesn't support e.g. the IDirect3DTexture interfaces. */
2447 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2449 skip("Failed to create a 3D device, skipping test.\n");
2450 IDirectDraw2_Release(ddraw
);
2451 DestroyWindow(window
);
2454 IDirect3DDevice_Release(device
);
2456 memset(&surface_desc
, 0, sizeof(surface_desc
));
2457 surface_desc
.dwSize
= sizeof(surface_desc
);
2458 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2459 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2460 surface_desc
.dwWidth
= 512;
2461 surface_desc
.dwHeight
= 512;
2462 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2463 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
2464 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2465 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2467 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2469 IDirectDrawSurface_Release(surface
);
2470 IDirectDraw2_Release(ddraw
);
2471 DestroyWindow(window
);
2474 static void test_device_qi(void)
2476 static const struct qi_test tests
[] =
2478 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2479 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2480 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2481 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2482 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2483 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2484 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2485 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2486 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2487 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2488 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2489 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2490 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2491 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2492 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2493 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2494 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2495 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2496 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2497 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2498 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2499 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2500 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2501 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2502 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2503 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2504 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2505 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2506 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2507 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2508 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2509 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2510 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2511 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2512 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2513 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2514 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2515 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2516 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2517 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2518 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2519 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2522 IDirect3DDevice2
*device
;
2523 IDirectDraw2
*ddraw
;
2526 window
= create_window();
2527 ddraw
= create_ddraw();
2528 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2529 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2531 skip("Failed to create a 3D device, skipping test.\n");
2532 IDirectDraw2_Release(ddraw
);
2533 DestroyWindow(window
);
2537 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, ARRAY_SIZE(tests
));
2539 IDirect3DDevice2_Release(device
);
2540 IDirectDraw2_Release(ddraw
);
2541 DestroyWindow(window
);
2544 static void test_wndproc(void)
2546 LONG_PTR proc
, ddraw_proc
;
2547 IDirectDraw2
*ddraw
;
2553 static struct message messages
[] =
2555 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2556 {WM_MOVE
, FALSE
, 0},
2557 {WM_SIZE
, FALSE
, 0},
2558 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2559 {WM_ACTIVATE
, FALSE
, 0},
2560 {WM_SETFOCUS
, FALSE
, 0},
2564 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2565 ddraw
= create_ddraw();
2566 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2568 wc
.lpfnWndProc
= test_proc
;
2569 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2570 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2572 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2573 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2575 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2576 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2577 (LONG_PTR
)test_proc
, proc
);
2578 expect_messages
= messages
;
2579 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2580 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2581 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2582 expect_messages
= NULL
;
2583 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2584 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2585 (LONG_PTR
)test_proc
, proc
);
2586 ref
= IDirectDraw2_Release(ddraw
);
2587 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2588 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2589 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2590 (LONG_PTR
)test_proc
, proc
);
2592 /* DDSCL_NORMAL doesn't. */
2593 ddraw
= create_ddraw();
2594 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2595 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2596 (LONG_PTR
)test_proc
, proc
);
2597 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2598 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2599 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2600 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2601 (LONG_PTR
)test_proc
, proc
);
2602 ref
= IDirectDraw2_Release(ddraw
);
2603 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2604 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2605 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2606 (LONG_PTR
)test_proc
, proc
);
2608 /* The original window proc is only restored by ddraw if the current
2609 * window proc matches the one ddraw set. This also affects switching
2610 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2611 ddraw
= create_ddraw();
2612 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2613 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2614 (LONG_PTR
)test_proc
, proc
);
2615 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2616 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2617 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2618 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2619 (LONG_PTR
)test_proc
, proc
);
2621 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2622 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2623 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2624 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2625 (LONG_PTR
)test_proc
, proc
);
2626 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2627 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2628 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2629 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2630 (LONG_PTR
)test_proc
, proc
);
2631 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2632 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2633 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2634 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2635 (LONG_PTR
)DefWindowProcA
, proc
);
2636 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2637 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2638 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2639 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2640 (LONG_PTR
)DefWindowProcA
, proc
);
2641 ref
= IDirectDraw2_Release(ddraw
);
2642 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2643 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2644 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2645 (LONG_PTR
)test_proc
, proc
);
2647 ddraw
= create_ddraw();
2648 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2649 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2650 (LONG_PTR
)test_proc
, proc
);
2651 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2652 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2653 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2654 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2655 (LONG_PTR
)test_proc
, proc
);
2656 ref
= IDirectDraw2_Release(ddraw
);
2657 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2658 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2659 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2660 (LONG_PTR
)DefWindowProcA
, proc
);
2662 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2663 expect_messages
= NULL
;
2664 DestroyWindow(window
);
2665 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2668 static void test_window_style(void)
2670 LONG style
, exstyle
, tmp
, expected_style
;
2671 RECT fullscreen_rect
, r
;
2672 HWND window
, window2
;
2673 IDirectDraw2
*ddraw
;
2678 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2679 0, 0, 100, 100, 0, 0, 0, 0);
2680 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2681 0, 0, 50, 50, 0, 0, 0, 0);
2682 ddraw
= create_ddraw();
2683 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2685 style
= GetWindowLongA(window
, GWL_STYLE
);
2686 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2687 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2689 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2690 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2692 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2693 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2694 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2695 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2697 GetWindowRect(window
, &r
);
2698 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2699 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2700 GetClientRect(window
, &r
);
2701 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2703 ret
= SetForegroundWindow(GetDesktopWindow());
2704 ok(ret
, "Failed to set foreground window.\n");
2706 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2707 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2708 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2709 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2711 ret
= SetForegroundWindow(window
);
2712 ok(ret
, "Failed to set foreground window.\n");
2713 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2714 * the next tests expect this. */
2715 ShowWindow(window
, SW_HIDE
);
2717 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2718 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2720 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2721 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2722 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2723 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2725 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2726 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2728 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2729 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2730 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2731 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2733 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2734 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2736 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2737 expected_style
= style
| WS_VISIBLE
;
2738 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2739 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2740 expected_style
= exstyle
| WS_EX_TOPMOST
;
2741 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2743 ShowWindow(window
, SW_HIDE
);
2744 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2745 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2746 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2747 expected_style
= exstyle
| WS_EX_TOPMOST
;
2748 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2750 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2751 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2753 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2754 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2755 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2756 expected_style
= exstyle
| WS_EX_TOPMOST
;
2757 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2759 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2760 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2762 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2763 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2764 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2765 expected_style
= exstyle
| WS_EX_TOPMOST
;
2766 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2768 ret
= SetForegroundWindow(window
);
2769 ok(ret
, "Failed to set foreground window.\n");
2771 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2772 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2774 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2775 expected_style
= style
| WS_VISIBLE
;
2776 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2777 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2778 expected_style
= exstyle
| WS_EX_TOPMOST
;
2779 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2781 ShowWindow(window
, SW_HIDE
);
2782 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2783 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2785 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2786 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2787 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2788 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2790 ShowWindow(window
, SW_SHOW
);
2791 ret
= SetForegroundWindow(GetDesktopWindow());
2792 ok(ret
, "Failed to set foreground window.\n");
2793 SetActiveWindow(window
);
2794 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
2795 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2796 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2798 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2799 expected_style
= style
| WS_VISIBLE
;
2800 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2801 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2802 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2804 GetWindowRect(window
, &r
);
2805 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2806 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2808 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2809 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2811 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
2812 GetWindowRect(window
, &r
);
2813 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
2814 wine_dbgstr_rect(&r
));
2816 ret
= SetForegroundWindow(window2
);
2817 ok(ret
, "Failed to set foreground window.\n");
2818 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2819 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2821 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2822 expected_style
= style
| WS_VISIBLE
;
2823 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2824 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2825 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2827 GetWindowRect(window
, &r
);
2828 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2829 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2831 ret
= SetForegroundWindow(window
);
2832 ok(ret
, "Failed to set foreground window.\n");
2833 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2834 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2836 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2837 expected_style
= style
| WS_VISIBLE
;
2838 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2839 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2840 expected_style
= exstyle
| WS_EX_TOPMOST
;
2841 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2843 ShowWindow(window
, SW_HIDE
);
2844 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2845 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2847 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2848 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2849 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2850 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2852 ShowWindow(window
, SW_SHOW
);
2853 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2854 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2856 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2857 expected_style
= style
| WS_VISIBLE
;
2858 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2859 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2860 expected_style
= exstyle
| WS_EX_TOPMOST
;
2861 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2863 ret
= SetForegroundWindow(GetDesktopWindow());
2864 ok(ret
, "Failed to set foreground window.\n");
2865 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2866 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2867 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2868 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2869 expected_style
= exstyle
| WS_EX_TOPMOST
;
2870 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2872 ref
= IDirectDraw2_Release(ddraw
);
2873 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2875 DestroyWindow(window2
);
2876 DestroyWindow(window
);
2879 static void test_redundant_mode_set(void)
2881 DDSURFACEDESC surface_desc
= {0};
2882 IDirectDraw2
*ddraw
;
2888 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2889 0, 0, 100, 100, 0, 0, 0, 0);
2890 ddraw
= create_ddraw();
2891 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2893 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2894 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2896 surface_desc
.dwSize
= sizeof(surface_desc
);
2897 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2898 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
2900 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2901 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2902 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2904 GetWindowRect(window
, &q
);
2908 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2909 GetWindowRect(window
, &s
);
2910 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2912 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2913 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2914 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2916 GetWindowRect(window
, &s
);
2917 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2918 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2920 ref
= IDirectDraw2_Release(ddraw
);
2921 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2923 DestroyWindow(window
);
2926 static SIZE screen_size
, screen_size2
;
2928 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2930 if (message
== WM_SIZE
)
2932 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2933 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2936 return test_proc(hwnd
, message
, wparam
, lparam
);
2939 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2941 if (message
== WM_SIZE
)
2943 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2944 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2947 return test_proc(hwnd
, message
, wparam
, lparam
);
2950 struct test_coop_level_mode_set_enum_param
2952 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2955 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2957 struct test_coop_level_mode_set_enum_param
*param
= context
;
2959 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2960 return DDENUMRET_OK
;
2961 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2962 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2963 return DDENUMRET_OK
;
2965 if (!param
->ddraw_width
)
2967 param
->ddraw_width
= surface_desc
->dwWidth
;
2968 param
->ddraw_height
= surface_desc
->dwHeight
;
2969 return DDENUMRET_OK
;
2971 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2972 return DDENUMRET_OK
;
2974 /* The docs say the DDENUMRET_CANCEL below cancels the enumeration, so the check should be
2975 * redundant. However, since Windows 10 this no longer works and the enumeration continues
2976 * until all supported modes are enumerated. Win8 and earlier do cancel.
2978 * Unrelatedly, some testbot machines report high res modes like 1920x1080, but suffer from
2979 * some problems when we actually try to set them (w10pro64 and its localization siblings).
2980 * Try to stay below the registry mode if possible. */
2981 if (!param
->user32_width
|| (surface_desc
->dwWidth
< registry_mode
.dmPelsWidth
2982 && surface_desc
->dwHeight
< registry_mode
.dmPelsHeight
))
2984 param
->user32_width
= surface_desc
->dwWidth
;
2985 param
->user32_height
= surface_desc
->dwHeight
;
2987 return DDENUMRET_CANCEL
;
2990 static void test_coop_level_mode_set(void)
2992 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2993 unsigned int display_count
= 0;
2994 IDirectDrawSurface
*primary
;
2995 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2996 IDirectDraw2
*ddraw
;
2999 HWND window
, window2
;
3003 struct test_coop_level_mode_set_enum_param param
;
3007 static const struct message exclusive_messages
[] =
3009 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3010 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3011 {WM_SIZE
, FALSE
, 0},
3012 {WM_DISPLAYCHANGE
, FALSE
, 0},
3015 static const struct message exclusive_focus_loss_messages
[] =
3017 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
3018 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
3019 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3020 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
3021 {WM_DISPLAYCHANGE
, FALSE
, 0},
3022 {WM_KILLFOCUS
, FALSE
, 0},
3023 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
3024 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
3025 * SW_MINIMIZED, causing a recursive window activation that does not
3026 * produce the same result in Wine yet. Ignore the difference for now.
3027 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
3028 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3029 {WM_MOVE
, FALSE
, 0},
3030 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3031 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
3034 static const struct message exclusive_focus_restore_messages
[] =
3036 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
3037 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
3038 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
3039 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
3040 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
3041 /* Native redundantly sets the window size here. */
3042 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
3043 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
3044 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
3045 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
3048 static const struct message sc_restore_messages
[] =
3050 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
3051 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3052 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3053 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
3056 static const struct message sc_minimize_messages
[] =
3058 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
3059 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3060 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3061 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3064 static const struct message sc_maximize_messages
[] =
3066 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
3067 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3068 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3069 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
3073 static const struct message normal_messages
[] =
3075 {WM_DISPLAYCHANGE
, FALSE
, 0},
3079 memset(&devmode
, 0, sizeof(devmode
));
3080 devmode
.dmSize
= sizeof(devmode
);
3081 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3082 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3083 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3084 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3085 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3086 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3088 ret
= save_display_modes(&original_modes
, &display_count
);
3089 ok(ret
, "Failed to save original display modes.\n");
3091 ddraw
= create_ddraw();
3092 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3094 memset(¶m
, 0, sizeof(param
));
3095 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
3096 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3097 ref
= IDirectDraw2_Release(ddraw
);
3098 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3100 if (!param
.user32_height
)
3102 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
3103 heap_free(original_modes
);
3107 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3108 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
3109 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
3111 memset(&devmode
, 0, sizeof(devmode
));
3112 devmode
.dmSize
= sizeof(devmode
);
3113 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3114 devmode
.dmPelsWidth
= param
.user32_width
;
3115 devmode
.dmPelsHeight
= param
.user32_height
;
3116 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3117 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3119 ddraw
= create_ddraw();
3120 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3122 wc
.lpfnWndProc
= mode_set_proc
;
3123 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3124 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3125 wc
.lpfnWndProc
= mode_set_proc2
;
3126 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
3127 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3129 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3130 0, 0, 100, 100, 0, 0, 0, 0);
3131 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3132 0, 0, 100, 100, 0, 0, 0, 0);
3134 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3135 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3137 GetWindowRect(window
, &r
);
3138 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3139 wine_dbgstr_rect(&r
));
3141 memset(&ddsd
, 0, sizeof(ddsd
));
3142 ddsd
.dwSize
= sizeof(ddsd
);
3143 ddsd
.dwFlags
= DDSD_CAPS
;
3144 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3146 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3147 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3148 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3149 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3150 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3151 param
.user32_width
, ddsd
.dwWidth
);
3152 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3153 param
.user32_height
, ddsd
.dwHeight
);
3155 GetWindowRect(window
, &r
);
3156 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3157 wine_dbgstr_rect(&r
));
3159 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3160 expect_messages
= exclusive_messages
;
3164 hr
= IDirectDrawSurface_IsLost(primary
);
3165 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3166 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3167 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3168 hr
= IDirectDrawSurface_IsLost(primary
);
3169 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3171 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3172 expect_messages
= NULL
;
3173 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3174 "Expected screen size %lux%lu, got %lux%lu.\n",
3175 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3177 GetWindowRect(window
, &r
);
3178 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3179 wine_dbgstr_rect(&r
));
3181 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3182 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3183 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3184 param
.user32_width
, ddsd
.dwWidth
);
3185 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3186 param
.user32_height
, ddsd
.dwHeight
);
3187 IDirectDrawSurface_Release(primary
);
3189 memset(&ddsd
, 0, sizeof(ddsd
));
3190 ddsd
.dwSize
= sizeof(ddsd
);
3191 ddsd
.dwFlags
= DDSD_CAPS
;
3192 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3194 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3195 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3196 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3197 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3198 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3199 param
.ddraw_width
, ddsd
.dwWidth
);
3200 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3201 param
.ddraw_height
, ddsd
.dwHeight
);
3203 GetWindowRect(window
, &r
);
3204 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3205 wine_dbgstr_rect(&r
));
3207 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3208 expect_messages
= exclusive_messages
;
3212 hr
= IDirectDrawSurface_IsLost(primary
);
3213 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3214 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3215 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3216 hr
= IDirectDrawSurface_IsLost(primary
);
3217 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3219 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3220 expect_messages
= NULL
;
3221 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3222 "Expected screen size %lux%lu, got %lux%lu.\n",
3223 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3225 GetWindowRect(window
, &r
);
3226 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3227 wine_dbgstr_rect(&r
));
3229 expect_messages
= exclusive_focus_loss_messages
;
3230 ret
= SetForegroundWindow(GetDesktopWindow());
3231 ok(ret
, "Failed to set foreground window.\n");
3232 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3233 memset(&devmode
, 0, sizeof(devmode
));
3234 devmode
.dmSize
= sizeof(devmode
);
3235 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3236 ok(ret
, "Failed to get display mode.\n");
3237 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3238 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3239 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3241 expect_messages
= exclusive_focus_restore_messages
;
3242 ShowWindow(window
, SW_RESTORE
);
3243 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3245 GetWindowRect(window
, &r
);
3246 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3247 wine_dbgstr_rect(&r
));
3248 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3249 ok(ret
, "Failed to get display mode.\n");
3250 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3251 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %lux%lu.\n",
3252 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3254 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3255 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3256 /* Normally the primary should be restored here. Unfortunately this causes the
3257 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3258 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3259 * the point of the GetSurfaceDesc call. */
3261 expect_messages
= sc_minimize_messages
;
3262 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3263 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3264 expect_messages
= NULL
;
3266 expect_messages
= sc_restore_messages
;
3267 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3268 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3269 expect_messages
= NULL
;
3271 expect_messages
= sc_maximize_messages
;
3272 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3273 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3274 expect_messages
= NULL
;
3276 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3277 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3279 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3280 expect_messages
= exclusive_messages
;
3284 hr
= IDirectDrawSurface_IsLost(primary
);
3285 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3286 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3287 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3288 hr
= IDirectDrawSurface_IsLost(primary
);
3289 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3291 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3292 expect_messages
= NULL
;
3293 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3294 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3295 "Expected screen size %lux%lu, got %lux%lu.\n",
3296 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3298 GetWindowRect(window
, &r
);
3299 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3300 wine_dbgstr_rect(&r
));
3302 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3303 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3304 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3305 param
.ddraw_width
, ddsd
.dwWidth
);
3306 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3307 param
.ddraw_height
, ddsd
.dwHeight
);
3308 IDirectDrawSurface_Release(primary
);
3311 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3312 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\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 %#lx.\n",hr
);
3321 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3322 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3323 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3324 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3325 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\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 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3333 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3335 GetWindowRect(window
, &r
);
3336 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3337 wine_dbgstr_rect(&r
));
3339 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3340 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3341 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3342 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3343 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3344 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3345 IDirectDrawSurface_Release(primary
);
3347 memset(&ddsd
, 0, sizeof(ddsd
));
3348 ddsd
.dwSize
= sizeof(ddsd
);
3349 ddsd
.dwFlags
= DDSD_CAPS
;
3350 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3352 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3353 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3354 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3355 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3356 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3357 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3358 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3359 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3361 GetWindowRect(window
, &r
);
3362 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3363 wine_dbgstr_rect(&r
));
3365 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3366 expect_messages
= normal_messages
;
3370 hr
= IDirectDrawSurface_IsLost(primary
);
3371 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3372 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3373 devmode
.dmPelsWidth
= param
.user32_width
;
3374 devmode
.dmPelsHeight
= param
.user32_height
;
3375 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3376 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3377 hr
= IDirectDrawSurface_IsLost(primary
);
3378 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3380 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3381 expect_messages
= NULL
;
3382 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3384 GetWindowRect(window
, &r
);
3385 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3386 wine_dbgstr_rect(&r
));
3388 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3389 expect_messages
= normal_messages
;
3393 hr
= IDirectDrawSurface_Restore(primary
);
3394 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3395 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3396 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3398 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3399 IDirectDrawSurface_Release(primary
);
3400 IDirectDraw2_Release(ddraw
);
3403 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3404 hr
= IDirectDrawSurface_Restore(primary
);
3405 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3406 hr
= IDirectDrawSurface_IsLost(primary
);
3407 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3409 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3410 expect_messages
= NULL
;
3411 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3413 GetWindowRect(window
, &r
);
3414 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3415 wine_dbgstr_rect(&r
));
3417 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3418 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3419 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3420 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3421 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3422 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3423 IDirectDrawSurface_Release(primary
);
3425 memset(&ddsd
, 0, sizeof(ddsd
));
3426 ddsd
.dwSize
= sizeof(ddsd
);
3427 ddsd
.dwFlags
= DDSD_CAPS
;
3428 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3430 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3431 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3432 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3433 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3434 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3435 param
.ddraw_width
, ddsd
.dwWidth
);
3436 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3437 param
.ddraw_height
, ddsd
.dwHeight
);
3439 GetWindowRect(window
, &r
);
3440 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3441 wine_dbgstr_rect(&r
));
3443 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3444 expect_messages
= normal_messages
;
3448 hr
= IDirectDrawSurface_IsLost(primary
);
3449 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3450 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3451 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3452 hr
= IDirectDrawSurface_IsLost(primary
);
3453 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3455 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3456 expect_messages
= NULL
;
3457 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3459 GetWindowRect(window
, &r
);
3460 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3461 wine_dbgstr_rect(&r
));
3463 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3464 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3465 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3466 param
.ddraw_width
, ddsd
.dwWidth
);
3467 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3468 param
.ddraw_height
, ddsd
.dwHeight
);
3469 IDirectDrawSurface_Release(primary
);
3471 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3472 ok(ret
, "Failed to get display mode.\n");
3473 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3474 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3475 "Expected resolution %lux%lu, got %lux%lu.\n",
3476 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3477 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3478 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3479 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3481 memset(&ddsd
, 0, sizeof(ddsd
));
3482 ddsd
.dwSize
= sizeof(ddsd
);
3483 ddsd
.dwFlags
= DDSD_CAPS
;
3484 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3486 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3487 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3488 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3489 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3490 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3491 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3492 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3493 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3495 GetWindowRect(window
, &r
);
3496 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3497 wine_dbgstr_rect(&r
));
3499 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3500 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3501 * not DDSCL_FULLSCREEN. */
3502 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3503 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3505 GetWindowRect(window
, &r
);
3506 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3507 wine_dbgstr_rect(&r
));
3509 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3510 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3511 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3512 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3513 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3514 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3515 IDirectDrawSurface_Release(primary
);
3517 memset(&ddsd
, 0, sizeof(ddsd
));
3518 ddsd
.dwSize
= sizeof(ddsd
);
3519 ddsd
.dwFlags
= DDSD_CAPS
;
3520 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3522 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3523 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3524 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3525 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3526 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3527 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3528 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3529 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3531 GetWindowRect(window
, &r
);
3532 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3533 wine_dbgstr_rect(&r
));
3535 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3536 expect_messages
= normal_messages
;
3540 hr
= IDirectDrawSurface_IsLost(primary
);
3541 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3542 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3543 devmode
.dmPelsWidth
= param
.user32_width
;
3544 devmode
.dmPelsHeight
= param
.user32_height
;
3545 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3546 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3547 hr
= IDirectDrawSurface_IsLost(primary
);
3548 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3550 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3551 expect_messages
= NULL
;
3552 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3554 GetWindowRect(window
, &r
);
3555 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3556 wine_dbgstr_rect(&r
));
3558 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3559 expect_messages
= normal_messages
;
3563 hr
= IDirectDrawSurface_Restore(primary
);
3564 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3565 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3566 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3567 hr
= IDirectDrawSurface_Restore(primary
);
3568 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3569 hr
= IDirectDrawSurface_IsLost(primary
);
3570 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3572 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3573 expect_messages
= NULL
;
3574 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3576 GetWindowRect(window
, &r
);
3577 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3578 wine_dbgstr_rect(&r
));
3580 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3581 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3582 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3583 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3584 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3585 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3586 IDirectDrawSurface_Release(primary
);
3588 memset(&ddsd
, 0, sizeof(ddsd
));
3589 ddsd
.dwSize
= sizeof(ddsd
);
3590 ddsd
.dwFlags
= DDSD_CAPS
;
3591 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3593 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3594 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3595 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3596 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3597 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3598 param
.ddraw_width
, ddsd
.dwWidth
);
3599 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3600 param
.ddraw_height
, ddsd
.dwHeight
);
3602 GetWindowRect(window
, &r
);
3603 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3604 wine_dbgstr_rect(&r
));
3606 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3607 expect_messages
= normal_messages
;
3611 hr
= IDirectDrawSurface_IsLost(primary
);
3612 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3613 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3614 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3615 hr
= IDirectDrawSurface_IsLost(primary
);
3616 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3618 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3619 expect_messages
= NULL
;
3620 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3622 GetWindowRect(window
, &r
);
3623 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3624 wine_dbgstr_rect(&r
));
3626 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3627 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3628 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3629 param
.ddraw_width
, ddsd
.dwWidth
);
3630 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3631 param
.ddraw_height
, ddsd
.dwHeight
);
3632 IDirectDrawSurface_Release(primary
);
3634 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3635 ok(ret
, "Failed to get display mode.\n");
3636 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3637 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3638 "Expected resolution %lux%lu, got %lux%lu.\n",
3639 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3640 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3641 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3642 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3644 memset(&ddsd
, 0, sizeof(ddsd
));
3645 ddsd
.dwSize
= sizeof(ddsd
);
3646 ddsd
.dwFlags
= DDSD_CAPS
;
3647 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3649 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3650 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3651 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3652 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3653 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3654 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3655 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3656 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3657 IDirectDrawSurface_Release(primary
);
3659 GetWindowRect(window
, &r
);
3660 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3661 wine_dbgstr_rect(&r
));
3663 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3664 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3665 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3666 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3667 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3669 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3670 expect_messages
= exclusive_messages
;
3674 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3675 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3677 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3678 expect_messages
= NULL
;
3679 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3680 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3681 "Expected screen size %lux%lu, got %lux%lu.\n",
3682 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3683 screen_size
.cx
, screen_size
.cy
);
3685 GetWindowRect(window
, &r
);
3686 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3687 wine_dbgstr_rect(&r
));
3689 memset(&ddsd
, 0, sizeof(ddsd
));
3690 ddsd
.dwSize
= sizeof(ddsd
);
3691 ddsd
.dwFlags
= DDSD_CAPS
;
3692 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3694 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3695 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3696 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3697 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3698 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3699 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3700 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3701 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3702 IDirectDrawSurface_Release(primary
);
3704 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3705 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3706 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3707 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3708 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3710 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3711 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3713 memset(&ddsd
, 0, sizeof(ddsd
));
3714 ddsd
.dwSize
= sizeof(ddsd
);
3715 ddsd
.dwFlags
= DDSD_CAPS
;
3716 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3718 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3719 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3720 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3721 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3722 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3723 param
.ddraw_width
, ddsd
.dwWidth
);
3724 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3725 param
.ddraw_height
, ddsd
.dwHeight
);
3726 IDirectDrawSurface_Release(primary
);
3728 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3729 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3731 /* If the window is changed at the same time, messages are sent to the new window. */
3732 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3733 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3734 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3735 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3737 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3738 expect_messages
= exclusive_messages
;
3741 screen_size2
.cx
= 0;
3742 screen_size2
.cy
= 0;
3744 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3745 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3747 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3748 expect_messages
= NULL
;
3749 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n",
3750 screen_size
.cx
, screen_size
.cy
);
3751 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3752 "Expected screen size 2 %lux%lu, got %lux%lu.\n",
3753 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3755 GetWindowRect(window
, &r
);
3756 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3757 wine_dbgstr_rect(&r
));
3758 GetWindowRect(window2
, &r
);
3759 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3760 wine_dbgstr_rect(&r
));
3762 memset(&ddsd
, 0, sizeof(ddsd
));
3763 ddsd
.dwSize
= sizeof(ddsd
);
3764 ddsd
.dwFlags
= DDSD_CAPS
;
3765 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3767 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3768 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3769 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3770 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3771 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3772 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3773 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3774 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3775 IDirectDrawSurface_Release(primary
);
3777 ref
= IDirectDraw2_Release(ddraw
);
3778 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3780 GetWindowRect(window
, &r
);
3781 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3782 wine_dbgstr_rect(&r
));
3784 ret
= restore_display_modes(original_modes
, display_count
);
3785 ok(ret
, "Failed to restore display modes.\n");
3787 /* Test that no mode restorations if no mode changes happened */
3788 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3789 devmode
.dmPelsWidth
= param
.user32_width
;
3790 devmode
.dmPelsHeight
= param
.user32_height
;
3791 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3792 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3794 ddraw
= create_ddraw();
3795 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3796 ref
= IDirectDraw2_Release(ddraw
);
3797 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3799 memset(&devmode2
, 0, sizeof(devmode2
));
3800 devmode2
.dmSize
= sizeof(devmode2
);
3801 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3802 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3803 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3804 ret
= restore_display_modes(original_modes
, display_count
);
3805 ok(ret
, "Failed to restore display modes.\n");
3807 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3808 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3809 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3811 ddraw
= create_ddraw();
3812 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3813 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3814 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3815 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3816 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3817 ref
= IDirectDraw2_Release(ddraw
);
3818 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3820 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3821 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3822 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3823 ret
= restore_display_modes(original_modes
, display_count
);
3824 ok(ret
, "Failed to restore display modes.\n");
3826 /* Test that mode restorations use display settings in the registry after ddraw object releases
3827 * if SetDisplayMode() was called */
3828 ddraw
= create_ddraw();
3829 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3830 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3831 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3833 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3834 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3836 ref
= IDirectDraw2_Release(ddraw
);
3837 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3839 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3840 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3841 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3842 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3843 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3844 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3845 ret
= restore_display_modes(original_modes
, display_count
);
3846 ok(ret
, "Failed to restore display modes.\n");
3848 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3849 ddraw
= create_ddraw();
3850 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3851 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3852 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3854 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3855 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3857 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3858 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3860 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3861 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3862 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3863 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3864 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3865 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3867 ref
= IDirectDraw2_Release(ddraw
);
3868 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3871 expect_messages
= NULL
;
3872 DestroyWindow(window
);
3873 DestroyWindow(window2
);
3874 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3875 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3876 ret
= restore_display_modes(original_modes
, display_count
);
3877 ok(ret
, "Failed to restore display modes.\n");
3878 heap_free(original_modes
);
3881 static void test_coop_level_mode_set_multi(void)
3883 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3884 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3885 WCHAR second_monitor_name
[CCHDEVICENAME
];
3886 IDirectDraw2
*ddraw1
, *ddraw2
;
3894 memset(&devmode
, 0, sizeof(devmode
));
3895 devmode
.dmSize
= sizeof(devmode
);
3896 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3897 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3898 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3899 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3900 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3901 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3903 ret
= save_display_modes(&original_modes
, &display_count
);
3904 ok(ret
, "Failed to save original display modes.\n");
3906 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3907 0, 0, 100, 100, 0, 0, 0, 0);
3908 ddraw1
= create_ddraw();
3909 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3911 /* With just a single ddraw object, the display mode is restored on
3913 hr
= set_display_mode(ddraw1
, 800, 600);
3914 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3916 win_skip("Broken SetDisplayMode(), skipping test.\n");
3917 IDirectDraw2_Release(ddraw1
);
3918 DestroyWindow(window
);
3921 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3922 w
= GetSystemMetrics(SM_CXSCREEN
);
3923 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3924 h
= GetSystemMetrics(SM_CYSCREEN
);
3925 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3927 ref
= IDirectDraw2_Release(ddraw1
);
3928 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3929 w
= GetSystemMetrics(SM_CXSCREEN
);
3930 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3931 h
= GetSystemMetrics(SM_CYSCREEN
);
3932 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3934 /* When there are multiple ddraw objects, the display mode is restored to
3935 * the initial mode, before the first SetDisplayMode() call. */
3936 ddraw1
= create_ddraw();
3937 hr
= set_display_mode(ddraw1
, 800, 600);
3938 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3939 w
= GetSystemMetrics(SM_CXSCREEN
);
3940 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3941 h
= GetSystemMetrics(SM_CYSCREEN
);
3942 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3944 ddraw2
= create_ddraw();
3945 hr
= set_display_mode(ddraw2
, 640, 480);
3946 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3947 w
= GetSystemMetrics(SM_CXSCREEN
);
3948 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3949 h
= GetSystemMetrics(SM_CYSCREEN
);
3950 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3952 ref
= IDirectDraw2_Release(ddraw2
);
3953 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3954 w
= GetSystemMetrics(SM_CXSCREEN
);
3955 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3956 h
= GetSystemMetrics(SM_CYSCREEN
);
3957 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3959 ref
= IDirectDraw2_Release(ddraw1
);
3960 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3961 w
= GetSystemMetrics(SM_CXSCREEN
);
3962 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3963 h
= GetSystemMetrics(SM_CYSCREEN
);
3964 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3966 /* Regardless of release ordering. */
3967 ddraw1
= create_ddraw();
3968 hr
= set_display_mode(ddraw1
, 800, 600);
3969 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3970 w
= GetSystemMetrics(SM_CXSCREEN
);
3971 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3972 h
= GetSystemMetrics(SM_CYSCREEN
);
3973 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3975 ddraw2
= create_ddraw();
3976 hr
= set_display_mode(ddraw2
, 640, 480);
3977 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3978 w
= GetSystemMetrics(SM_CXSCREEN
);
3979 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3980 h
= GetSystemMetrics(SM_CYSCREEN
);
3981 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3983 ref
= IDirectDraw2_Release(ddraw1
);
3984 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3985 w
= GetSystemMetrics(SM_CXSCREEN
);
3986 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3987 h
= GetSystemMetrics(SM_CYSCREEN
);
3988 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3990 ref
= IDirectDraw2_Release(ddraw2
);
3991 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3992 w
= GetSystemMetrics(SM_CXSCREEN
);
3993 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3994 h
= GetSystemMetrics(SM_CYSCREEN
);
3995 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3997 /* But only for ddraw objects that called SetDisplayMode(). */
3998 ddraw1
= create_ddraw();
3999 ddraw2
= create_ddraw();
4000 hr
= set_display_mode(ddraw2
, 640, 480);
4001 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4002 w
= GetSystemMetrics(SM_CXSCREEN
);
4003 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4004 h
= GetSystemMetrics(SM_CYSCREEN
);
4005 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4007 ref
= IDirectDraw2_Release(ddraw1
);
4008 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4009 w
= GetSystemMetrics(SM_CXSCREEN
);
4010 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4011 h
= GetSystemMetrics(SM_CYSCREEN
);
4012 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4014 ref
= IDirectDraw2_Release(ddraw2
);
4015 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4016 w
= GetSystemMetrics(SM_CXSCREEN
);
4017 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4018 h
= GetSystemMetrics(SM_CYSCREEN
);
4019 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4021 /* If there's a ddraw object that's currently in exclusive mode, it blocks
4022 * restoring the display mode. */
4023 ddraw1
= create_ddraw();
4024 hr
= set_display_mode(ddraw1
, 800, 600);
4025 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4026 w
= GetSystemMetrics(SM_CXSCREEN
);
4027 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4028 h
= GetSystemMetrics(SM_CYSCREEN
);
4029 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4031 ddraw2
= create_ddraw();
4032 hr
= set_display_mode(ddraw2
, 640, 480);
4033 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4034 w
= GetSystemMetrics(SM_CXSCREEN
);
4035 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4036 h
= GetSystemMetrics(SM_CYSCREEN
);
4037 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4039 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4040 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4042 ref
= IDirectDraw2_Release(ddraw1
);
4043 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4044 w
= GetSystemMetrics(SM_CXSCREEN
);
4045 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4046 h
= GetSystemMetrics(SM_CYSCREEN
);
4047 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4049 ref
= IDirectDraw2_Release(ddraw2
);
4050 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4051 w
= GetSystemMetrics(SM_CXSCREEN
);
4052 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4053 h
= GetSystemMetrics(SM_CYSCREEN
);
4054 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4056 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
4057 ddraw1
= create_ddraw();
4058 hr
= set_display_mode(ddraw1
, 800, 600);
4059 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4060 w
= GetSystemMetrics(SM_CXSCREEN
);
4061 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4062 h
= GetSystemMetrics(SM_CYSCREEN
);
4063 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4065 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4066 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4068 ddraw2
= create_ddraw();
4069 hr
= set_display_mode(ddraw2
, 640, 480);
4070 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
4072 ref
= IDirectDraw2_Release(ddraw1
);
4073 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4074 w
= GetSystemMetrics(SM_CXSCREEN
);
4075 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4076 h
= GetSystemMetrics(SM_CYSCREEN
);
4077 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4079 ref
= IDirectDraw2_Release(ddraw2
);
4080 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4081 w
= GetSystemMetrics(SM_CXSCREEN
);
4082 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4083 h
= GetSystemMetrics(SM_CYSCREEN
);
4084 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4086 if (display_count
< 2)
4088 skip("Following tests require two monitors.\n");
4092 ret
= restore_display_modes(original_modes
, display_count
);
4093 ok(ret
, "Failed to restore display modes.\n");
4095 second_monitor_name
[0] = '\0';
4096 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
4098 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
4100 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
4104 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
4105 memset(&old_devmode
, 0, sizeof(old_devmode
));
4106 old_devmode
.dmSize
= sizeof(old_devmode
);
4107 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
4108 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4110 devmode
= old_devmode
;
4111 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
4113 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4114 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
4117 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4118 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
4119 "Failed to find a different mode for the second monitor.\n");
4121 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
4122 ddraw1
= create_ddraw();
4123 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4124 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4125 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4127 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4128 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4130 memset(&devmode2
, 0, sizeof(devmode2
));
4131 devmode2
.dmSize
= sizeof(devmode2
);
4132 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4133 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4134 if (compare_mode_rect(&devmode2
, &old_devmode
))
4136 skip("Failed to change display settings of the second monitor.\n");
4137 ref
= IDirectDraw2_Release(ddraw1
);
4138 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4142 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
4143 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4144 ref
= IDirectDraw2_Release(ddraw1
);
4145 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4147 memset(&devmode3
, 0, sizeof(devmode3
));
4148 devmode3
.dmSize
= sizeof(devmode3
);
4149 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
4150 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4151 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
4152 ret
= restore_display_modes(original_modes
, display_count
);
4153 ok(ret
, "Failed to restore display modes.\n");
4155 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
4156 * SetDisplayMode() was called */
4157 ddraw1
= create_ddraw();
4158 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4159 hr
= set_display_mode(ddraw1
, 800, 600);
4160 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4162 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4163 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4165 ref
= IDirectDraw2_Release(ddraw1
);
4166 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4168 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4169 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4170 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4171 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4172 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4173 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4174 ret
= restore_display_modes(original_modes
, display_count
);
4175 ok(ret
, "Failed to restore display modes.\n");
4177 /* Test that mode restorations happen for non-primary monitors as well */
4178 ddraw1
= create_ddraw();
4179 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4180 hr
= set_display_mode(ddraw1
, 800, 600);
4181 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4183 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4184 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4186 hr
= IDirectDraw2_RestoreDisplayMode(ddraw1
);
4187 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4189 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4190 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4191 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4192 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4193 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4194 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4196 ref
= IDirectDraw2_Release(ddraw1
);
4197 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4198 ret
= restore_display_modes(original_modes
, display_count
);
4199 ok(ret
, "Failed to restore display modes.\n");
4201 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4202 ddraw1
= create_ddraw();
4203 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4204 hr
= set_display_mode(ddraw1
, 800, 600);
4205 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4207 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4208 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4209 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4211 ref
= IDirectDraw2_Release(ddraw1
);
4212 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4214 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4215 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4216 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4217 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4218 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4219 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4220 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4221 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4222 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4223 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4224 ret
= restore_display_modes(original_modes
, display_count
);
4225 ok(ret
, "Failed to restore display modes.\n");
4227 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4228 * objects and one of them restores display mode */
4229 ddraw1
= create_ddraw();
4230 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4231 ddraw2
= create_ddraw();
4232 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4233 hr
= set_display_mode(ddraw1
, 800, 600);
4234 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4235 hr
= set_display_mode(ddraw2
, 640, 480);
4236 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4238 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4239 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4241 hr
= IDirectDraw2_RestoreDisplayMode(ddraw2
);
4242 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4244 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4245 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4246 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4247 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4248 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4249 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4251 ref
= IDirectDraw2_Release(ddraw2
);
4252 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4253 ref
= IDirectDraw2_Release(ddraw1
);
4254 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4255 ret
= restore_display_modes(original_modes
, display_count
);
4256 ok(ret
, "Failed to restore display modes.\n");
4258 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4259 * objects and one of them got released */
4260 ddraw1
= create_ddraw();
4261 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4262 ddraw2
= create_ddraw();
4263 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4264 hr
= set_display_mode(ddraw1
, 800, 600);
4265 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4266 hr
= set_display_mode(ddraw2
, 640, 480);
4267 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4269 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4270 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4272 ref
= IDirectDraw2_Release(ddraw2
);
4273 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4275 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4276 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4277 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4278 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4279 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4280 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4282 ref
= IDirectDraw2_Release(ddraw1
);
4283 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4286 DestroyWindow(window
);
4287 ret
= restore_display_modes(original_modes
, display_count
);
4288 ok(ret
, "Failed to restore display modes.\n");
4289 heap_free(original_modes
);
4292 static void test_initialize(void)
4294 IDirectDraw2
*ddraw
;
4297 ddraw
= create_ddraw();
4298 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4300 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4301 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx.\n", hr
);
4302 IDirectDraw2_Release(ddraw
);
4305 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
4306 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#lx.\n", hr
);
4307 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4308 ok(hr
== DD_OK
, "Initialize returned hr %#lx, expected DD_OK.\n", hr
);
4309 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4310 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4311 IDirectDraw2_Release(ddraw
);
4315 static void test_coop_level_surf_create(void)
4317 IDirectDrawSurface
*surface
;
4318 IDirectDraw2
*ddraw
;
4322 ddraw
= create_ddraw();
4323 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4325 memset(&ddsd
, 0, sizeof(ddsd
));
4326 ddsd
.dwSize
= sizeof(ddsd
);
4327 ddsd
.dwFlags
= DDSD_CAPS
;
4328 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4329 surface
= (void *)0xdeadbeef;
4330 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4331 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4332 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4334 surface
= (void *)0xdeadbeef;
4335 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4336 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4337 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4339 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4340 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4342 surface
= (void *)0xdeadbeef;
4343 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4344 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#lx.\n", hr
);
4345 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4347 IDirectDraw2_Release(ddraw
);
4350 static void test_coop_level_multi_window(void)
4352 HWND window1
, window2
;
4353 IDirectDraw2
*ddraw
;
4356 window1
= create_window();
4357 window2
= create_window();
4358 ddraw
= create_ddraw();
4359 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4361 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4362 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4363 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4364 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4365 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4366 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4368 IDirectDraw2_Release(ddraw
);
4369 DestroyWindow(window2
);
4370 DestroyWindow(window1
);
4373 static void test_clear_rect_count(void)
4375 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4376 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
4377 IDirect3DViewport2
*viewport
;
4378 IDirect3DDevice2
*device
;
4379 IDirectDrawSurface
*rt
;
4380 IDirectDraw2
*ddraw
;
4385 window
= create_window();
4386 ddraw
= create_ddraw();
4387 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4388 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4390 skip("Failed to create a 3D device, skipping test.\n");
4391 IDirectDraw2_Release(ddraw
);
4392 DestroyWindow(window
);
4396 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4397 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4399 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
4400 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
4401 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
4402 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
4404 viewport
= create_viewport(device
, 0, 0, 640, 480);
4405 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4406 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
4408 viewport_set_background(device
, viewport
, white
);
4409 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4410 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4411 viewport_set_background(device
, viewport
, red
);
4412 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4413 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4414 viewport_set_background(device
, viewport
, green
);
4415 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
4416 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4417 viewport_set_background(device
, viewport
, blue
);
4418 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4419 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4421 color
= get_surface_color(rt
, 320, 240);
4422 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4423 "Got unexpected color 0x%08x.\n", color
);
4425 IDirectDrawSurface_Release(rt
);
4426 destroy_viewport(device
, viewport
);
4427 destroy_material(white
);
4428 destroy_material(red
);
4429 destroy_material(green
);
4430 destroy_material(blue
);
4431 IDirect3DDevice2_Release(device
);
4432 IDirectDraw2_Release(ddraw
);
4433 DestroyWindow(window
);
4436 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
4438 DDSURFACEDESC ddsd1
, ddsd2
;
4441 memset(&ddsd1
, 0, sizeof(ddsd1
));
4442 ddsd1
.dwSize
= sizeof(ddsd1
);
4443 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
4444 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
4446 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4447 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4448 hr
= set_display_mode(ddraw
, 640, 480);
4449 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4450 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4451 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4453 memset(&ddsd2
, 0, sizeof(ddsd2
));
4454 ddsd2
.dwSize
= sizeof(ddsd2
);
4455 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
4456 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
4457 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
4458 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4460 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4463 static void test_coop_level_versions(void)
4469 IDirectDrawSurface
*surface
;
4470 IDirectDraw2
*ddraw2
;
4473 window
= create_window();
4474 ddraw2
= create_ddraw();
4475 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4476 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4477 restored
= test_mode_restored(ddraw2
, window
);
4478 ok(restored
, "Display mode not restored in new ddraw object\n");
4480 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4481 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4482 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4484 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4485 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
4486 restored
= test_mode_restored(ddraw2
, window
);
4487 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4489 /* A successful one does */
4490 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4491 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4492 restored
= test_mode_restored(ddraw2
, window
);
4493 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4495 IDirectDraw_Release(ddraw
);
4496 IDirectDraw2_Release(ddraw2
);
4498 ddraw2
= create_ddraw();
4499 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4500 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4501 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4503 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4504 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4505 restored
= test_mode_restored(ddraw2
, window
);
4506 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4508 IDirectDraw_Release(ddraw
);
4509 IDirectDraw2_Release(ddraw2
);
4511 /* A failing call does not restore the ddraw2+ behavior */
4512 ddraw2
= create_ddraw();
4513 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4514 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4515 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4517 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4518 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4519 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4520 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
4521 restored
= test_mode_restored(ddraw2
, window
);
4522 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4524 IDirectDraw_Release(ddraw
);
4525 IDirectDraw2_Release(ddraw2
);
4527 /* Neither does a sequence of successful calls with the new interface */
4528 ddraw2
= create_ddraw();
4529 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4530 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4531 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4533 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4534 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4535 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4536 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4537 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4538 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4540 restored
= test_mode_restored(ddraw2
, window
);
4541 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
4542 IDirectDraw_Release(ddraw
);
4543 IDirectDraw2_Release(ddraw2
);
4545 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4546 ddraw2
= create_ddraw();
4547 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4548 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4549 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4551 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4552 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4554 memset(&ddsd
, 0, sizeof(ddsd
));
4555 ddsd
.dwSize
= sizeof(ddsd
);
4556 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4557 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4558 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4559 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4560 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#lx.\n", hr
);
4561 IDirectDrawSurface_Release(surface
);
4562 restored
= test_mode_restored(ddraw2
, window
);
4563 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4565 IDirectDraw_Release(ddraw
);
4566 IDirectDraw2_Release(ddraw2
);
4567 DestroyWindow(window
);
4570 static void test_lighting_interface_versions(void)
4572 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4573 IDirect3DMaterial2
*emissive
, *background
;
4574 IDirect3DViewport2
*viewport
;
4575 IDirect3DDevice2
*device
;
4576 IDirectDrawSurface
*rt
;
4577 unsigned int color
, i
;
4578 IDirectDraw2
*ddraw
;
4581 D3DMATERIALHANDLE mat_handle
;
4584 static D3DVERTEX quad
[] =
4586 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4587 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4588 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4589 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4591 static D3DLVERTEX lquad
[] =
4593 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4594 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4595 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4596 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4598 static D3DTLVERTEX tlquad
[] =
4600 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4601 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4602 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4603 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4607 D3DVERTEXTYPE vertextype
;
4609 DWORD d3drs_lighting
, d3drs_specular
;
4615 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
4616 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
4617 * in later d3d versions */
4618 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
4619 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
4620 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4621 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4622 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
4623 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
4624 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4625 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4627 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
4628 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
4629 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4630 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4631 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
4632 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
4633 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4634 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4636 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
4637 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
4638 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4639 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4640 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
4641 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
4642 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4643 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4646 window
= create_window();
4647 ddraw
= create_ddraw();
4648 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4649 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4651 skip("Failed to create a 3D device, skipping test.\n");
4652 IDirectDraw2_Release(ddraw
);
4653 DestroyWindow(window
);
4657 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4658 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4660 viewport
= create_viewport(device
, 0, 0, 640, 480);
4661 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4662 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
4664 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4665 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
4666 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
4667 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4668 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
4669 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
4670 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#lx.\n", hr
);
4672 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
4673 viewport_set_background(device
, viewport
, background
);
4675 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
4676 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#lx.\n", hr
);
4677 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#lx, expected TRUE.\n", rs
);
4679 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4681 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4682 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4684 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
4685 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#lx.\n", hr
);
4686 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4687 tests
[i
].d3drs_specular
);
4688 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#lx.\n", hr
);
4690 hr
= IDirect3DDevice2_BeginScene(device
);
4691 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
4692 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4693 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4694 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
4695 hr
= IDirect3DDevice2_EndScene(device
);
4696 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
4698 color
= get_surface_color(rt
, 320, 240);
4699 ok(compare_color(color
, tests
[i
].color
, 1),
4700 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4701 color
, tests
[i
].color
, i
);
4704 destroy_material(background
);
4705 destroy_material(emissive
);
4706 destroy_viewport(device
, viewport
);
4707 IDirectDrawSurface_Release(rt
);
4708 IDirect3DDevice2_Release(device
);
4709 ref
= IDirectDraw2_Release(ddraw
);
4710 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4711 DestroyWindow(window
);
4717 IDirectDraw2
*ddraw
;
4720 } activateapp_testdata
;
4722 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4724 if (message
== WM_ACTIVATEAPP
)
4726 if (activateapp_testdata
.ddraw
)
4729 activateapp_testdata
.received
= FALSE
;
4730 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4731 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4732 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#lx.\n", hr
);
4733 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4735 activateapp_testdata
.received
= TRUE
;
4738 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4741 static void test_coop_level_activateapp(void)
4743 IDirectDraw2
*ddraw
;
4748 IDirectDrawSurface
*surface
;
4750 ddraw
= create_ddraw();
4751 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4753 wc
.lpfnWndProc
= activateapp_test_proc
;
4754 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4755 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4757 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4758 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4760 /* Exclusive with window already active. */
4761 SetForegroundWindow(window
);
4762 activateapp_testdata
.received
= FALSE
;
4763 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4764 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4765 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4766 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4767 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4769 /* Exclusive with window not active. */
4770 SetForegroundWindow(GetDesktopWindow());
4771 activateapp_testdata
.received
= FALSE
;
4772 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4773 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4774 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4775 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4776 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4778 /* Normal with window not active, then exclusive with the same window. */
4779 SetForegroundWindow(GetDesktopWindow());
4780 activateapp_testdata
.received
= FALSE
;
4781 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4782 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4783 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4784 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4785 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4786 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4787 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4788 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4790 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4791 SetForegroundWindow(GetDesktopWindow());
4792 activateapp_testdata
.received
= FALSE
;
4793 activateapp_testdata
.ddraw
= ddraw
;
4794 activateapp_testdata
.window
= window
;
4795 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4796 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4797 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4798 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4799 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4800 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4802 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4803 * succeeding. Another switch to exclusive and back to normal is needed to release the
4804 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4805 * WM_ACTIVATEAPP messages. */
4806 activateapp_testdata
.ddraw
= NULL
;
4807 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4808 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4809 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4810 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4812 /* Setting DDSCL_NORMAL with recursive invocation. */
4813 SetForegroundWindow(GetDesktopWindow());
4814 activateapp_testdata
.received
= FALSE
;
4815 activateapp_testdata
.ddraw
= ddraw
;
4816 activateapp_testdata
.window
= window
;
4817 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4818 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4819 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4820 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4822 /* DDraw is in exclusive mode now. */
4823 memset(&ddsd
, 0, sizeof(ddsd
));
4824 ddsd
.dwSize
= sizeof(ddsd
);
4825 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4826 ddsd
.dwBackBufferCount
= 1;
4827 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4828 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4829 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
4830 IDirectDrawSurface_Release(surface
);
4832 /* Recover again, just to be sure. */
4833 activateapp_testdata
.ddraw
= NULL
;
4834 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4835 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4836 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4837 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4839 DestroyWindow(window
);
4840 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4841 IDirectDraw2_Release(ddraw
);
4844 struct format_support_check
4846 const DDPIXELFORMAT
*format
;
4850 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4852 struct format_support_check
*format
= ctx
;
4854 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4856 format
->supported
= TRUE
;
4857 return DDENUMRET_CANCEL
;
4860 return DDENUMRET_OK
;
4863 static void test_unsupported_formats(void)
4866 BOOL expect_success
;
4868 IDirectDraw2
*ddraw
;
4869 IDirect3DDevice2
*device
;
4870 IDirectDrawSurface
*surface
;
4873 DWORD expected_caps
;
4884 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4885 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4891 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4892 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4896 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4898 window
= create_window();
4899 ddraw
= create_ddraw();
4900 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4901 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4903 skip("Failed to create a 3D device, skipping test.\n");
4904 IDirectDraw2_Release(ddraw
);
4905 DestroyWindow(window
);
4909 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4911 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4912 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4913 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
4915 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4917 memset(&ddsd
, 0, sizeof(ddsd
));
4918 ddsd
.dwSize
= sizeof(ddsd
);
4919 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4920 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4923 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4925 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4926 expect_success
= FALSE
;
4928 expect_success
= TRUE
;
4930 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4931 ok(SUCCEEDED(hr
) == expect_success
,
4932 "Got unexpected hr %#lx for format %s, caps %#lx, expected %s.\n",
4933 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4937 memset(&ddsd
, 0, sizeof(ddsd
));
4938 ddsd
.dwSize
= sizeof(ddsd
);
4939 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4940 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
4942 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4943 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4944 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4945 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4946 else if (check
.supported
)
4947 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4949 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4951 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4952 "Expected caps %#lx, format %s, input caps %#lx.\n",
4953 expected_caps
, formats
[i
].name
, caps
[j
]);
4955 IDirectDrawSurface_Release(surface
);
4959 IDirect3DDevice2_Release(device
);
4960 IDirectDraw2_Release(ddraw
);
4961 DestroyWindow(window
);
4964 static void test_rt_caps(const GUID
*device_guid
)
4966 PALETTEENTRY palette_entries
[256];
4967 IDirectDrawPalette
*palette
;
4968 IDirect3DDevice2
*device
;
4969 BOOL software_device
;
4970 IDirectDraw2
*ddraw
;
4979 static const DDPIXELFORMAT p8_fmt
=
4981 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4982 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4987 const DDPIXELFORMAT
*pf
;
4989 HRESULT create_device_hr
;
4991 HRESULT alternative_set_rt_hr
;
4992 BOOL create_may_fail
;
4998 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5006 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5014 DDSCAPS_OFFSCREENPLAIN
,
5022 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5023 D3DERR_SURFACENOTINVIDMEM
,
5030 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5038 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5062 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5063 D3DERR_SURFACENOTINVIDMEM
,
5070 DDSCAPS_SYSTEMMEMORY
,
5086 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5087 DDERR_NOPALETTEATTACHED
,
5094 DDSCAPS_OFFSCREENPLAIN
,
5102 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5103 DDERR_NOPALETTEATTACHED
,
5110 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5118 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
5120 DDERR_INVALIDPIXELFORMAT
,
5122 TRUE
/* AMD Evergreen */,
5126 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5128 DDERR_INVALIDPIXELFORMAT
,
5142 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5144 DDERR_INVALIDPIXELFORMAT
,
5145 DDERR_INVALIDPIXELFORMAT
,
5146 TRUE
/* Nvidia Kepler */,
5150 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5154 TRUE
/* Nvidia Kepler */,
5158 software_device
= is_software_device_type(device_guid
);
5160 window
= create_window();
5161 ddraw
= create_ddraw();
5162 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5163 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
5165 skip("Failed to create a 3D device, skipping test.\n");
5166 IDirectDraw2_Release(ddraw
);
5167 DestroyWindow(window
);
5170 z_depth
= get_device_z_depth(device
);
5171 ok(!!z_depth
, "Failed to get device z depth.\n");
5172 IDirect3DDevice2_Release(device
);
5174 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
5176 skip("D3D interface is not available, skipping test.\n");
5180 memset(palette_entries
, 0, sizeof(palette_entries
));
5181 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
5182 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5184 memset(&hal_caps
, 0, sizeof(hal_caps
));
5185 hal_caps
.dwSize
= sizeof(hal_caps
);
5186 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
5187 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5189 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5191 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
5192 DWORD caps_in
, expected_caps
;
5193 DDSURFACEDESC surface_desc
;
5194 IDirect3DDevice2
*device
;
5195 HRESULT expected_hr
;
5197 caps_in
= test_data
[i
].caps_in
;
5199 memset(&surface_desc
, 0, sizeof(surface_desc
));
5200 surface_desc
.dwSize
= sizeof(surface_desc
);
5201 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5202 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
5203 if (test_data
[i
].pf
)
5205 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5206 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5208 if (caps_in
& DDSCAPS_ZBUFFER
)
5210 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5211 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
5213 surface_desc
.dwWidth
= 640;
5214 surface_desc
.dwHeight
= 480;
5215 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5216 expected_hr
= DDERR_NODIRECTDRAWHW
;
5218 expected_hr
= DD_OK
;
5219 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5220 ok(hr
== expected_hr
|| broken(test_data
[i
].create_may_fail
5221 || (software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
)),
5222 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5226 memset(&surface_desc
, 0, sizeof(surface_desc
));
5227 surface_desc
.dwSize
= sizeof(surface_desc
);
5228 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5230 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5231 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
5233 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
5235 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
5236 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
5237 || (software_device
&& caps_in
& DDSCAPS_ZBUFFER
5238 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
5239 "Got unexpected caps %#lx, expected %#lx, test %u, software_device %u.\n",
5240 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
5242 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5244 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
5245 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
5246 ? DD_OK
: test_data
[i
].create_device_hr
))),
5247 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5251 if (hr
== DDERR_NOPALETTEATTACHED
)
5253 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
5254 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5255 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5256 if (software_device
)
5258 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5259 hr
, i
, software_device
);
5260 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
5261 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5262 hr
, i
, software_device
);
5264 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5265 hr
, i
, software_device
);
5269 refcount
= IDirect3DDevice2_Release(device
);
5270 ok(!refcount
, "Test %u: The device was not properly freed, refcount %lu.\n", i
, refcount
);
5273 IDirectDrawSurface_Release(surface
);
5275 memset(&surface_desc
, 0, sizeof(surface_desc
));
5276 surface_desc
.dwSize
= sizeof(surface_desc
);
5277 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5278 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5279 surface_desc
.dwWidth
= 640;
5280 surface_desc
.dwHeight
= 480;
5281 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5282 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5284 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5285 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5288 memset(&surface_desc
, 0, sizeof(surface_desc
));
5289 surface_desc
.dwSize
= sizeof(surface_desc
);
5290 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5291 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5292 if (test_data
[i
].pf
)
5294 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5295 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5297 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
5299 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5300 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
5302 surface_desc
.dwWidth
= 640;
5303 surface_desc
.dwHeight
= 480;
5304 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
5305 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5307 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
5308 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
5309 || broken(hr
== test_data
[i
].alternative_set_rt_hr
),
5310 "Got unexpected hr %#lx, test %u, software_device %u.\n",
5311 hr
, i
, software_device
);
5313 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
5316 expected_rt
= surface
;
5318 /* It appears the surface is set as render target in this case, but no
5319 * reference is taken. */
5320 if (hr
== DDERR_INVALIDPIXELFORMAT
)
5322 refcount
= IDirectDrawSurface_AddRef(rt
);
5323 ok(refcount
== 2, "Test %u: Got unexpected refcount %lu.\n", i
, refcount
);
5326 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
5327 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5328 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
5330 IDirectDrawSurface_Release(tmp
);
5331 IDirectDrawSurface_Release(rt
);
5332 refcount
= IDirect3DDevice2_Release(device
);
5333 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5334 refcount
= IDirectDrawSurface_Release(surface
);
5335 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5338 IDirectDrawPalette_Release(palette
);
5339 IDirect3D2_Release(d3d
);
5342 refcount
= IDirectDraw2_Release(ddraw
);
5343 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5344 DestroyWindow(window
);
5347 static void test_primary_caps(void)
5349 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5350 IDirectDrawSurface
*surface
;
5351 DDSURFACEDESC surface_desc
;
5352 IDirectDraw2
*ddraw
;
5362 DWORD back_buffer_count
;
5370 DDSCAPS_PRIMARYSURFACE
,
5373 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
5377 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
5384 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
5391 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
5398 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
5405 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
5412 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5419 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5426 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5428 DDERR_NOEXCLUSIVEMODE
,
5432 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5433 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5439 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5440 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5443 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
5446 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5447 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
5453 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5454 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
5461 window
= create_window();
5462 ddraw
= create_ddraw();
5463 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5465 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5467 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
5468 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5470 memset(&surface_desc
, 0, sizeof(surface_desc
));
5471 surface_desc
.dwSize
= sizeof(surface_desc
);
5472 surface_desc
.dwFlags
= DDSD_CAPS
;
5473 if (test_data
[i
].back_buffer_count
!= ~0u)
5474 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5475 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5476 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5477 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5478 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
5482 memset(&surface_desc
, 0, sizeof(surface_desc
));
5483 surface_desc
.dwSize
= sizeof(surface_desc
);
5484 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5485 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
5486 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5487 "Test %u: Got unexpected caps %#lx, expected %#lx.\n",
5488 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5490 IDirectDrawSurface_Release(surface
);
5493 refcount
= IDirectDraw2_Release(ddraw
);
5494 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5495 DestroyWindow(window
);
5498 static void test_surface_lock(void)
5500 IDirectDraw2
*ddraw
;
5501 IDirectDrawSurface
*surface
;
5502 IDirect3DDevice2
*device
;
5517 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5518 "videomemory offscreenplain"
5521 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5522 "systemmemory offscreenplain"
5525 DDSCAPS_PRIMARYSURFACE
,
5529 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5530 "videomemory texture"
5533 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5534 "systemmemory texture"
5537 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5546 window
= create_window();
5547 ddraw
= create_ddraw();
5548 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5549 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5551 skip("Failed to create a 3D device, skipping test.\n");
5552 IDirectDraw2_Release(ddraw
);
5553 DestroyWindow(window
);
5556 z_depth
= get_device_z_depth(device
);
5557 ok(!!z_depth
, "Failed to get device z depth.\n");
5558 IDirect3DDevice2_Release(device
);
5560 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5562 memset(&ddsd
, 0, sizeof(ddsd
));
5563 ddsd
.dwSize
= sizeof(ddsd
);
5564 ddsd
.dwFlags
= DDSD_CAPS
;
5565 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5567 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5571 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
5573 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5574 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
5576 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5578 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5579 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5581 memset(&ddsd
, 0, sizeof(ddsd
));
5582 ddsd
.dwSize
= sizeof(ddsd
);
5583 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5584 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5587 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5588 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5591 memset(&ddsd
, 0, sizeof(ddsd
));
5592 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5593 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, tests
[i
].name
);
5595 IDirectDrawSurface_Release(surface
);
5598 refcount
= IDirectDraw2_Release(ddraw
);
5599 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5600 DestroyWindow(window
);
5603 static void test_surface_discard(void)
5605 IDirectDraw2
*ddraw
;
5606 IDirect3DDevice2
*device
;
5610 IDirectDrawSurface
*surface
, *target
;
5619 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5620 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5621 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5622 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5626 window
= create_window();
5628 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5632 /* Sigh. Anything other than the first run of the loop randomly fails with
5633 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
5634 * the blit fails, but with sleeps added between surface creation and lock
5635 * the lock can fail too. Interestingly ddraw claims the render target has
5636 * been lost, not the test surface.
5638 * Recreating ddraw every iteration seems to fix this. */
5639 ddraw
= create_ddraw();
5640 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5641 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5643 skip("Failed to create a 3D device, skipping test.\n");
5644 DestroyWindow(window
);
5645 IDirectDraw2_Release(ddraw
);
5649 hr
= IDirect3DDevice2_GetRenderTarget(device
, &target
);
5650 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5652 memset(&ddsd
, 0, sizeof(ddsd
));
5653 ddsd
.dwSize
= sizeof(ddsd
);
5654 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5655 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5658 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5661 skip("Failed to create surface, skipping.\n");
5665 memset(&ddsd
, 0, sizeof(ddsd
));
5666 ddsd
.dwSize
= sizeof(ddsd
);
5667 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5668 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5669 addr
= ddsd
.lpSurface
;
5670 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5671 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5673 memset(&ddsd
, 0, sizeof(ddsd
));
5674 ddsd
.dwSize
= sizeof(ddsd
);
5675 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5676 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#lx.\n", hr
);
5677 discarded
= ddsd
.lpSurface
!= addr
;
5678 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5679 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5681 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
5682 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
5684 memset(&ddsd
, 0, sizeof(ddsd
));
5685 ddsd
.dwSize
= sizeof(ddsd
);
5686 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5687 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5688 discarded
|= ddsd
.lpSurface
!= addr
;
5689 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5690 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5692 IDirectDrawSurface_Release(surface
);
5694 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
5695 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
5696 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
5698 IDirectDrawSurface_Release(target
);
5699 IDirect3DDevice2_Release(device
);
5700 IDirectDraw2_Release(ddraw
);
5703 DestroyWindow(window
);
5706 static void test_flip(void)
5708 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5709 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5710 DDSCAPS caps
= {DDSCAPS_FLIP
};
5711 DDSURFACEDESC surface_desc
;
5712 unsigned int color
, i
;
5713 BOOL sysmem_primary
;
5714 IDirectDraw2
*ddraw
;
5715 DWORD expected_caps
;
5727 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5728 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5729 {"TEXTURE", DDSCAPS_TEXTURE
},
5732 window
= create_window();
5733 ddraw
= create_ddraw();
5734 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5736 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5737 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5739 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5741 /* Creating a flippable texture induces a BSoD on some versions of the
5742 * Intel graphics driver. At least Intel GMA 950 with driver version
5743 * 6.14.10.4926 on Windows XP SP3 is affected. */
5744 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5746 win_skip("Skipping flippable texture test.\n");
5750 memset(&surface_desc
, 0, sizeof(surface_desc
));
5751 surface_desc
.dwSize
= sizeof(surface_desc
);
5752 surface_desc
.dwFlags
= DDSD_CAPS
;
5753 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5754 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5755 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5756 surface_desc
.dwWidth
= 512;
5757 surface_desc
.dwHeight
= 512;
5758 surface_desc
.dwBackBufferCount
= 3;
5759 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5760 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5762 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5763 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5764 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5765 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5767 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5768 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5769 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5770 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5772 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5773 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5774 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5775 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5779 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5780 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5781 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5782 ok(hr
== DD_OK
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5783 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5784 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5785 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5787 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5788 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5789 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5790 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5791 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5792 hr
= restore_surfaces(ddraw
);
5793 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#lx.\n", test_data
[i
].name
, hr
);
5795 memset(&surface_desc
, 0, sizeof(surface_desc
));
5796 surface_desc
.dwSize
= sizeof(surface_desc
);
5797 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5798 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5799 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5800 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5801 expected_caps
|= DDSCAPS_VISIBLE
;
5802 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5803 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5804 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5806 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5807 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5808 memset(&surface_desc
, 0, sizeof(surface_desc
));
5809 surface_desc
.dwSize
= sizeof(surface_desc
);
5810 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5811 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5812 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5813 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5814 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5815 expected_caps
|= DDSCAPS_BACKBUFFER
;
5816 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5817 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5819 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5820 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5821 memset(&surface_desc
, 0, sizeof(surface_desc
));
5822 surface_desc
.dwSize
= sizeof(surface_desc
);
5823 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5824 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5825 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5826 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5827 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5828 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5829 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5831 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5832 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5833 memset(&surface_desc
, 0, sizeof(surface_desc
));
5834 surface_desc
.dwSize
= sizeof(surface_desc
);
5835 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5836 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5837 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5838 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5839 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5840 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5842 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5843 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5844 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5845 test_data
[i
].name
, surface
, frontbuffer
);
5846 IDirectDrawSurface_Release(surface
);
5848 memset(&surface_desc
, 0, sizeof(surface_desc
));
5849 surface_desc
.dwSize
= sizeof(surface_desc
);
5850 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5851 surface_desc
.ddsCaps
.dwCaps
= 0;
5852 surface_desc
.dwWidth
= 640;
5853 surface_desc
.dwHeight
= 480;
5854 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5855 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5856 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5857 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5858 IDirectDrawSurface_Release(surface
);
5860 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5861 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5862 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5863 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5864 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5865 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5866 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5867 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5869 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5870 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5871 * as a workaround. */
5872 fill_surface(backbuffer1
, 0xffff0000);
5873 fill_surface(backbuffer2
, 0xff00ff00);
5874 fill_surface(backbuffer3
, 0xff0000ff);
5876 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5877 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5878 color
= get_surface_color(backbuffer1
, 320, 240);
5879 /* The testbot seems to just copy the contents of one surface to all the
5880 * others, instead of properly flipping. */
5881 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5882 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5883 color
= get_surface_color(backbuffer2
, 320, 240);
5884 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5885 fill_surface(backbuffer3
, 0xffff0000);
5887 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5888 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5889 color
= get_surface_color(backbuffer1
, 320, 240);
5890 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5891 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5892 color
= get_surface_color(backbuffer2
, 320, 240);
5893 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5894 fill_surface(backbuffer3
, 0xff00ff00);
5896 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5897 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5898 color
= get_surface_color(backbuffer1
, 320, 240);
5899 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5900 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5901 color
= get_surface_color(backbuffer2
, 320, 240);
5902 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5903 fill_surface(backbuffer3
, 0xff0000ff);
5905 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5906 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5907 color
= get_surface_color(backbuffer2
, 320, 240);
5908 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5909 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5910 color
= get_surface_color(backbuffer3
, 320, 240);
5911 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5912 fill_surface(backbuffer1
, 0xffff0000);
5914 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5915 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5916 color
= get_surface_color(backbuffer1
, 320, 240);
5917 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5918 color
= get_surface_color(backbuffer3
, 320, 240);
5919 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5920 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5921 fill_surface(backbuffer2
, 0xff00ff00);
5923 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5924 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5925 color
= get_surface_color(backbuffer1
, 320, 240);
5926 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5927 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5928 color
= get_surface_color(backbuffer2
, 320, 240);
5929 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5931 IDirectDrawSurface_Release(backbuffer3
);
5932 IDirectDrawSurface_Release(backbuffer2
);
5933 IDirectDrawSurface_Release(backbuffer1
);
5934 IDirectDrawSurface_Release(frontbuffer
);
5937 refcount
= IDirectDraw2_Release(ddraw
);
5938 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5939 DestroyWindow(window
);
5942 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
5944 memset(ddsd
, 0, sizeof(*ddsd
));
5945 ddsd
->dwSize
= sizeof(*ddsd
);
5948 static void test_set_surface_desc(void)
5950 IDirectDraw2
*ddraw
;
5954 IDirectDrawSurface
*surface
;
5955 IDirectDrawSurface3
*surface3
;
5965 invalid_caps_tests
[] =
5967 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
5968 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
5969 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
5972 window
= create_window();
5973 ddraw
= create_ddraw();
5974 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5975 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5976 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5979 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
5982 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5983 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5984 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5985 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5986 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5987 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5988 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5990 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5991 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5993 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
5994 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#lx.\n", hr
);
5995 IDirectDrawSurface_Release(surface
);
5998 ddsd
.dwFlags
= DDSD_LPSURFACE
;
5999 ddsd
.lpSurface
= data
;
6000 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6001 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6003 /* Redundantly setting the same lpSurface is not an error. */
6004 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6005 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6006 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6007 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6008 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6009 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
6011 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
6012 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
6013 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6014 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
6015 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
6016 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6019 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6020 ddsd
.lpSurface
= data
;
6021 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
6022 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6024 ddsd
.lpSurface
= NULL
;
6025 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6026 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6028 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
6029 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6031 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6032 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6033 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6034 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
6036 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
6037 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6038 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6040 ddsd
.dwFlags
= DDSD_CAPS
;
6041 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6042 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6044 /* dwCaps = 0 is allowed, but ignored. */
6045 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
6046 ddsd
.lpSurface
= data
;
6047 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6048 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
6049 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6050 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6051 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
6052 ddsd
.ddsCaps
.dwCaps
= 0;
6053 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6054 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6056 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6057 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6058 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6059 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
6061 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
6063 ddsd
.dwFlags
= DDSD_HEIGHT
;
6065 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6066 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6068 ddsd
.lpSurface
= data
;
6069 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
6070 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6071 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6074 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6075 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6078 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6079 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#lx.\n", hr
);
6080 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
6081 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
6083 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
6085 ddsd
.dwFlags
= DDSD_PITCH
;
6086 U1(ddsd
).lPitch
= 8 * 4;
6087 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6088 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6090 ddsd
.dwFlags
= DDSD_WIDTH
;
6092 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6093 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6095 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
6096 ddsd
.lpSurface
= data
;
6097 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6098 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6100 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
6101 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6102 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6104 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6105 U1(ddsd
).lPitch
= 16 * 4;
6107 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6108 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6111 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6112 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6113 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
6114 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
6115 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %lu.\n", U1(ddsd
).lPitch
);
6117 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
6119 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
6120 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6121 U1(ddsd
).lPitch
= 4 * 4;
6122 ddsd
.lpSurface
= data
;
6123 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6124 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
6126 U1(ddsd
).lPitch
= 4;
6127 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6128 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
6130 U1(ddsd
).lPitch
= 16 * 4 + 1;
6131 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6132 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6134 U1(ddsd
).lPitch
= 16 * 4 + 3;
6135 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6136 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6138 U1(ddsd
).lPitch
= -4;
6139 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6140 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6142 U1(ddsd
).lPitch
= 16 * 4;
6143 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6144 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6147 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6148 U1(ddsd
).lPitch
= 0;
6150 ddsd
.lpSurface
= data
;
6151 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6152 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6154 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6155 U1(ddsd
).lPitch
= 16 * 4;
6157 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6158 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6160 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
6161 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
6162 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6163 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6164 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6165 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6166 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6167 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6168 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6169 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6171 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6172 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6173 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6175 /* Can't set color keys. */
6177 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
6178 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
6179 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
6180 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6181 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6183 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
6184 ddsd
.lpSurface
= data
;
6185 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6186 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6188 IDirectDrawSurface3_Release(surface3
);
6190 /* Test mipmap texture. */
6192 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6195 U2(ddsd
).dwMipMapCount
= 3;
6196 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6197 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6198 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
6202 skip("Mipmaps are not supported.\n");
6206 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6207 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6208 IDirectDrawSurface_Release(surface
);
6210 /* Changing surface desc for mipmap fails even without changing any
6212 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6213 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
6216 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6217 ddsd
.lpSurface
= data
;
6218 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6219 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
6220 IDirectDrawSurface3_Release(surface3
);
6224 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6227 U2(ddsd
).dwMipMapCount
= 3;
6228 ddsd
.lpSurface
= data
;
6229 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6231 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6232 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
6236 static DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6237 IDirectDrawSurface3
*surface2
;
6239 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6240 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6241 IDirectDrawSurface_Release(surface
);
6243 hr
= IDirectDrawSurface3_GetAttachedSurface(surface3
, &caps
, &surface2
);
6244 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6246 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface2
, &ddsd
);
6247 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6248 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %lu.\n", ddsd
.dwWidth
);
6251 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6254 U1(ddsd
).lPitch
= 16 * 4;
6255 ddsd
.lpSurface
= data
;
6256 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6257 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6260 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6263 U1(ddsd
).lPitch
= 8 * 4;
6264 ddsd
.lpSurface
= data
;
6265 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6266 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6269 /* _Lock causes access violation on Windows. */
6271 hr
= IDirectDrawSurface3_Lock(surface2
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6272 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6273 IDirectDrawSurface3_Unlock(surface2
, NULL
);
6278 /* Causes access violation on Windows. */
6280 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6283 U1(ddsd
).lPitch
= 4 * 4;
6284 ddsd
.lpSurface
= data
;
6285 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface2
, &ddsd
, 0);
6286 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6288 IDirectDrawSurface3_Release(surface2
);
6289 IDirectDrawSurface3_Release(surface3
);
6292 /* Test surface created with DDSD_LPSURFACE. */
6294 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
6297 ddsd
.lpSurface
= data
;
6298 U1(ddsd
).lPitch
= 8 * 4;
6299 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6300 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6301 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
6303 /* SetSurfaceDesc needs systemmemory surfaces.
6305 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
6306 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
6309 ddsd
.dwFlags
= DDSD_CAPS
;
6310 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
6311 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6313 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6316 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6317 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6318 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6319 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6320 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6321 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6324 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6325 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#lx.\n", hr
);
6328 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
6329 invalid_caps_tests
[i
].name
);
6332 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6333 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6334 IDirectDrawSurface_Release(surface
);
6337 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6338 ddsd
.lpSurface
= data
;
6339 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6340 if (invalid_caps_tests
[i
].supported
)
6342 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6346 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
6347 invalid_caps_tests
[i
].name
, hr
);
6349 /* Check priority of error conditions. */
6350 ddsd
.dwFlags
= DDSD_WIDTH
;
6351 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6352 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
6353 invalid_caps_tests
[i
].name
, hr
);
6356 IDirectDrawSurface3_Release(surface3
);
6360 ref
= IDirectDraw2_Release(ddraw
);
6361 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6362 DestroyWindow(window
);
6365 static void test_user_memory_getdc(void)
6367 unsigned int data
[16][16], x
, y
;
6368 IDirectDraw2
*ddraw
;
6372 IDirectDrawSurface
*surface
;
6373 IDirectDrawSurface3
*surface3
;
6380 window
= create_window();
6381 ddraw
= create_ddraw();
6382 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6384 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6385 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6388 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6391 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6392 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6393 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6394 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6395 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6396 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6397 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6398 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6399 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6401 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6402 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#lx.\n", hr
);
6403 IDirectDrawSurface_Release(surface
);
6405 memset(data
, 0xaa, sizeof(data
));
6407 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6408 ddsd
.lpSurface
= data
;
6409 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6410 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6412 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6413 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
6414 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
6415 ok(!!bitmap
, "Failed to get bitmap.\n");
6416 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
6417 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
6418 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
6419 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
6420 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
6421 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6422 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
6424 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
6425 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
6427 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
6428 ddsd
.lpSurface
= data
;
6431 U1(ddsd
).lPitch
= sizeof(*data
);
6432 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6433 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6435 memset(data
, 0xaa, sizeof(data
));
6436 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6437 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
6438 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
6439 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
6440 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6441 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
6443 for (y
= 0; y
< 4; y
++)
6445 for (x
= 0; x
< 4; x
++)
6447 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
6448 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
6451 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
6455 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
6457 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
6459 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
6461 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
6464 IDirectDrawSurface3_Release(surface3
);
6465 ref
= IDirectDraw2_Release(ddraw
);
6466 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6467 DestroyWindow(window
);
6470 static void test_sysmem_overlay(void)
6472 IDirectDraw2
*ddraw
;
6476 IDirectDrawSurface
*surface
;
6479 window
= create_window();
6480 ddraw
= create_ddraw();
6481 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6483 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6484 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6487 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6490 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
6491 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6492 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6493 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6494 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6495 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6496 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6497 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6498 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#lx.\n", hr
);
6500 ref
= IDirectDraw2_Release(ddraw
);
6501 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6502 DestroyWindow(window
);
6505 static void test_primary_palette(void)
6507 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
6508 IDirectDrawSurface
*primary
, *backbuffer
;
6509 PALETTEENTRY palette_entries
[256];
6510 IDirectDrawPalette
*palette
, *tmp
;
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 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6523 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6524 IDirectDraw2_Release(ddraw
);
6525 DestroyWindow(window
);
6528 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6529 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6531 memset(&surface_desc
, 0, sizeof(surface_desc
));
6532 surface_desc
.dwSize
= sizeof(surface_desc
);
6533 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6534 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6535 surface_desc
.dwBackBufferCount
= 1;
6536 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6537 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6538 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
6539 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
6541 memset(palette_entries
, 0, sizeof(palette_entries
));
6542 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
6543 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6544 refcount
= get_refcount((IUnknown
*)palette
);
6545 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6547 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6548 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6549 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
6551 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6552 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6554 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
6555 * and is generally somewhat broken with respect to 8 bpp / palette
6557 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
6559 win_skip("Broken palette handling detected, skipping tests.\n");
6560 IDirectDrawPalette_Release(tmp
);
6561 IDirectDrawPalette_Release(palette
);
6562 /* The Windows 8 testbot keeps extra references to the primary and
6563 * backbuffer while in 8 bpp mode. */
6564 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
6565 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
6569 refcount
= get_refcount((IUnknown
*)palette
);
6570 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6572 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6573 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6574 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
6575 "Got unexpected palette caps %#lx.\n", palette_caps
);
6577 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
6578 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6579 refcount
= get_refcount((IUnknown
*)palette
);
6580 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6582 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6583 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6584 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
6586 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6587 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6588 refcount
= get_refcount((IUnknown
*)palette
);
6589 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6591 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6592 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
6593 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
6594 IDirectDrawPalette_Release(tmp
);
6595 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
6596 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6598 refcount
= IDirectDrawPalette_Release(palette
);
6599 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6600 refcount
= IDirectDrawPalette_Release(palette
);
6601 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6603 /* Note that this only seems to work when the palette is attached to the
6604 * primary surface. When attached to a regular surface, attempting to get
6605 * the palette here will cause an access violation. */
6606 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6607 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6609 hr
= IDirectDrawSurface_IsLost(primary
);
6610 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6612 memset(&surface_desc
, 0, sizeof(surface_desc
));
6613 surface_desc
.dwSize
= sizeof(surface_desc
);
6614 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6615 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6616 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6617 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6618 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %lu.\n",
6619 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6621 hr
= set_display_mode(ddraw
, 640, 480);
6622 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
6624 memset(&surface_desc
, 0, sizeof(surface_desc
));
6625 surface_desc
.dwSize
= sizeof(surface_desc
);
6626 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6627 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6628 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6629 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6630 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
6631 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
6632 "Got unexpected bit count %lu.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6634 hr
= IDirectDrawSurface_IsLost(primary
);
6635 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
6636 hr
= IDirectDrawSurface_Restore(primary
);
6637 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
6638 hr
= IDirectDrawSurface_IsLost(primary
);
6639 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
6641 memset(&surface_desc
, 0, sizeof(surface_desc
));
6642 surface_desc
.dwSize
= sizeof(surface_desc
);
6643 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6644 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6645 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6646 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6647 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
6648 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
6649 "Got unexpected bit count %lu.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
6652 refcount
= IDirectDrawSurface_Release(backbuffer
);
6653 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6654 refcount
= IDirectDrawSurface_Release(primary
);
6655 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6656 refcount
= IDirectDraw2_Release(ddraw
);
6657 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6658 DestroyWindow(window
);
6661 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
6663 UINT
*surface_count
= context
;
6666 IDirectDrawSurface_Release(surface
);
6668 return DDENUMRET_OK
;
6671 static void test_surface_attachment(void)
6673 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
6674 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6675 DDSURFACEDESC surface_desc
;
6676 IDirectDraw2
*ddraw
;
6682 window
= create_window();
6683 ddraw
= create_ddraw();
6684 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6685 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6686 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6688 memset(&surface_desc
, 0, sizeof(surface_desc
));
6689 surface_desc
.dwSize
= sizeof(surface_desc
);
6690 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
6691 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6692 U2(surface_desc
).dwMipMapCount
= 3;
6693 surface_desc
.dwWidth
= 128;
6694 surface_desc
.dwHeight
= 128;
6695 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6696 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6698 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
6699 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
6700 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
6701 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
6702 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
6703 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6706 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
6707 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6709 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
6710 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6712 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
6713 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
6715 memset(&surface_desc
, 0, sizeof(surface_desc
));
6716 surface_desc
.dwSize
= sizeof(surface_desc
);
6717 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6718 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6719 surface_desc
.dwWidth
= 16;
6720 surface_desc
.dwHeight
= 16;
6721 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6722 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6724 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6725 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6726 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6727 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6728 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6729 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6730 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6731 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6732 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6733 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6734 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6735 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6737 IDirectDrawSurface_Release(surface4
);
6739 memset(&surface_desc
, 0, sizeof(surface_desc
));
6740 surface_desc
.dwSize
= sizeof(surface_desc
);
6741 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6742 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6743 surface_desc
.dwWidth
= 16;
6744 surface_desc
.dwHeight
= 16;
6745 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6746 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6748 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
6750 skip("Running on refrast, skipping some tests.\n");
6751 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
6752 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6756 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6757 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6758 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6759 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6760 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6761 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6762 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6763 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6764 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6765 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6766 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6769 IDirectDrawSurface_Release(surface4
);
6770 IDirectDrawSurface_Release(surface3
);
6771 IDirectDrawSurface_Release(surface2
);
6772 IDirectDrawSurface_Release(surface1
);
6774 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6775 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6777 /* Try a single primary and two offscreen plain surfaces. */
6778 memset(&surface_desc
, 0, sizeof(surface_desc
));
6779 surface_desc
.dwSize
= sizeof(surface_desc
);
6780 surface_desc
.dwFlags
= DDSD_CAPS
;
6781 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6782 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6783 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6785 memset(&surface_desc
, 0, sizeof(surface_desc
));
6786 surface_desc
.dwSize
= sizeof(surface_desc
);
6787 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6788 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6789 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6790 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6791 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6792 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6794 memset(&surface_desc
, 0, sizeof(surface_desc
));
6795 surface_desc
.dwSize
= sizeof(surface_desc
);
6796 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6797 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6798 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6799 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6800 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6801 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6803 /* This one has a different size. */
6804 memset(&surface_desc
, 0, sizeof(surface_desc
));
6805 surface_desc
.dwSize
= sizeof(surface_desc
);
6806 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6807 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6808 surface_desc
.dwWidth
= 128;
6809 surface_desc
.dwHeight
= 128;
6810 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6811 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6813 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6814 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6815 /* Try the reverse without detaching first. */
6816 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6817 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6818 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6819 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6821 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6822 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6823 /* Try to detach reversed. */
6824 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6825 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6826 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
6827 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6829 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
6830 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6831 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
6832 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6834 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6835 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6836 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6837 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6839 IDirectDrawSurface_Release(surface4
);
6840 IDirectDrawSurface_Release(surface3
);
6841 IDirectDrawSurface_Release(surface2
);
6842 IDirectDrawSurface_Release(surface1
);
6844 /* Test depth surfaces of different sizes. */
6845 memset(&surface_desc
, 0, sizeof(surface_desc
));
6846 surface_desc
.dwSize
= sizeof(surface_desc
);
6847 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6848 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6849 surface_desc
.dwWidth
= 64;
6850 surface_desc
.dwHeight
= 64;
6851 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6852 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6854 memset(&surface_desc
, 0, sizeof(surface_desc
));
6855 surface_desc
.dwSize
= sizeof(surface_desc
);
6856 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6857 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6858 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6859 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6860 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6861 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6862 surface_desc
.dwWidth
= 32;
6863 surface_desc
.dwHeight
= 32;
6864 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6865 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6866 surface_desc
.dwWidth
= 64;
6867 surface_desc
.dwHeight
= 64;
6868 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6869 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6870 surface_desc
.dwWidth
= 128;
6871 surface_desc
.dwHeight
= 128;
6872 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6873 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6875 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6876 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6878 IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface2
);
6879 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
6880 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#lx.\n", hr
);
6881 hr
= IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface3
);
6882 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#lx.\n", hr
);
6883 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6884 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6886 IDirectDrawSurface2_Release(surface4
);
6887 IDirectDrawSurface2_Release(surface3
);
6888 IDirectDrawSurface2_Release(surface2
);
6889 IDirectDrawSurface2_Release(surface1
);
6891 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
6892 memset(&surface_desc
, 0, sizeof(surface_desc
));
6893 surface_desc
.dwSize
= sizeof(surface_desc
);
6894 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6895 surface_desc
.dwWidth
= 64;
6896 surface_desc
.dwHeight
= 64;
6897 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6898 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6899 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
6900 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
6901 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
6902 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
6903 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
6904 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6905 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6906 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6907 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6909 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6910 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6911 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
6912 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
6913 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6914 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6916 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6917 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6918 refcount
= get_refcount((IUnknown
*)surface2
);
6919 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6920 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6921 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6923 /* Attaching while already attached to other surface. */
6924 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
6925 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6926 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
6927 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6928 IDirectDrawSurface_Release(surface3
);
6930 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6931 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6932 refcount
= get_refcount((IUnknown
*)surface2
);
6933 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6935 /* Automatic detachment on release. */
6936 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6937 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6938 refcount
= get_refcount((IUnknown
*)surface2
);
6939 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6940 refcount
= IDirectDrawSurface_Release(surface1
);
6941 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6942 refcount
= IDirectDrawSurface_Release(surface2
);
6943 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6944 refcount
= IDirectDraw2_Release(ddraw
);
6945 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6946 DestroyWindow(window
);
6949 static void test_pixel_format(void)
6951 HWND window
, window2
= NULL
;
6952 HDC hdc
, hdc2
= NULL
;
6954 int format
, test_format
;
6955 PIXELFORMATDESCRIPTOR pfd
;
6956 IDirectDraw2
*ddraw
= NULL
;
6957 IDirectDrawClipper
*clipper
= NULL
;
6959 IDirectDrawSurface
*primary
= NULL
, *offscreen
;
6963 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6964 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6967 skip("Failed to create window\n");
6971 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6972 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
6974 hdc
= GetDC(window
);
6977 skip("Failed to get DC\n");
6982 hdc2
= GetDC(window2
);
6984 gl
= LoadLibraryA("opengl32.dll");
6985 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
6987 format
= GetPixelFormat(hdc
);
6988 ok(format
== 0, "new window has pixel format %d\n", format
);
6990 ZeroMemory(&pfd
, sizeof(pfd
));
6991 pfd
.nSize
= sizeof(pfd
);
6993 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
6994 pfd
.iPixelType
= PFD_TYPE_RGBA
;
6995 pfd
.iLayerType
= PFD_MAIN_PLANE
;
6996 format
= ChoosePixelFormat(hdc
, &pfd
);
6999 skip("no pixel format available\n");
7003 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7005 skip("failed to set pixel format\n");
7009 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7011 skip("failed to set pixel format on second window\n");
7014 ReleaseDC(window2
, hdc2
);
7019 ddraw
= create_ddraw();
7020 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7022 test_format
= GetPixelFormat(hdc
);
7023 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7025 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7028 skip("Failed to set cooperative level, hr %#lx.\n", hr
);
7032 test_format
= GetPixelFormat(hdc
);
7033 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7037 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
7038 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
7039 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
7040 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
7042 test_format
= GetPixelFormat(hdc
);
7043 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7045 test_format
= GetPixelFormat(hdc2
);
7046 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7049 memset(&ddsd
, 0, sizeof(ddsd
));
7050 ddsd
.dwSize
= sizeof(ddsd
);
7051 ddsd
.dwFlags
= DDSD_CAPS
;
7052 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7054 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7055 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
7057 test_format
= GetPixelFormat(hdc
);
7058 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7062 test_format
= GetPixelFormat(hdc2
);
7063 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7068 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
7069 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
7071 test_format
= GetPixelFormat(hdc
);
7072 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7074 test_format
= GetPixelFormat(hdc2
);
7075 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7078 memset(&ddsd
, 0, sizeof(ddsd
));
7079 ddsd
.dwSize
= sizeof(ddsd
);
7080 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7081 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7082 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
7083 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
7084 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
7086 memset(&fx
, 0, sizeof(fx
));
7087 fx
.dwSize
= sizeof(fx
);
7088 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7089 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
7091 test_format
= GetPixelFormat(hdc
);
7092 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7094 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
7095 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
7097 test_format
= GetPixelFormat(hdc
);
7098 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7102 test_format
= GetPixelFormat(hdc2
);
7103 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7106 IDirectDrawSurface_Release(offscreen
);
7109 if (primary
) IDirectDrawSurface_Release(primary
);
7110 if (clipper
) IDirectDrawClipper_Release(clipper
);
7111 if (ddraw
) IDirectDraw2_Release(ddraw
);
7112 if (gl
) FreeLibrary(gl
);
7113 if (hdc
) ReleaseDC(window
, hdc
);
7114 if (hdc2
) ReleaseDC(window2
, hdc2
);
7115 DestroyWindow(window
);
7116 if (window2
) DestroyWindow(window2
);
7119 static void test_create_surface_pitch(void)
7121 DWORD vidmem_total
= 0, vidmem_free
= 0, vidmem_free2
= 0;
7122 DDSCAPS vidmem_caps
= {DDSCAPS_TEXTURE
};
7123 IDirectDrawSurface
* surface
, *primary
;
7124 DDSURFACEDESC surface_desc
;
7125 IDirectDraw2
*ddraw
;
7145 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7147 DDSD_PITCH
, 0x100, 0x100},
7148 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7149 DDSD_PITCH
, 0x104, DD_OK
,
7150 DDSD_PITCH
, 0x100, 0x100},
7151 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7152 DDSD_PITCH
, 0x0f8, DD_OK
,
7153 DDSD_PITCH
, 0x100, 0x100},
7154 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7155 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7157 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7159 DDSD_PITCH
, 0x100, 0x0fc},
7161 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7162 DDSD_PITCH
, 0x104, DD_OK
,
7163 DDSD_PITCH
, 0x100, 0x0fc},
7164 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7165 DDSD_PITCH
, 0x0f8, DD_OK
,
7166 DDSD_PITCH
, 0x100, 0x0fc},
7167 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7168 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
7169 DDSD_PITCH
, 0x100, 0x0fc},
7170 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7171 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
7173 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7174 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7177 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7178 0, 0, DDERR_INVALIDCAPS
,
7180 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7182 DDSD_PITCH
, 0x100, 0 },
7183 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
,
7185 DDSD_PITCH
, 0x100, 0 },
7186 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7187 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7189 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7190 0, 0, DDERR_INVALIDCAPS
,
7193 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7195 DDSD_PITCH
, 0x100, 0 },
7196 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7197 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7200 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
7202 window
= create_window();
7203 ddraw
= create_ddraw();
7204 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7205 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7206 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7208 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
7210 /* We need a primary surface and exclusive mode for video memory accounting to work
7211 * right on Windows. Otherwise it gives us junk data, like creating a video memory
7212 * surface freeing up memory. */
7213 memset(&surface_desc
, 0, sizeof(surface_desc
));
7214 surface_desc
.dwSize
= sizeof(surface_desc
);
7215 surface_desc
.dwFlags
= DDSD_CAPS
;
7216 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7217 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7218 ok(SUCCEEDED(hr
), "Failed to create a primary surface, hr %#lx.\n", hr
);
7220 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free
);
7221 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7222 "Failed to get available video memory, hr %#lx.\n", hr
);
7224 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7226 memset(&surface_desc
, 0, sizeof(surface_desc
));
7227 surface_desc
.dwSize
= sizeof(surface_desc
);
7228 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
7229 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7230 surface_desc
.dwWidth
= 63;
7231 surface_desc
.dwHeight
= 63;
7232 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
7233 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7234 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7235 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7236 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7237 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7238 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7239 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7240 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
7242 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
7243 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, expected_hr
);
7244 surface_desc
.lpSurface
= mem
;
7245 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7247 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
7249 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
7253 memset(&surface_desc
, 0, sizeof(surface_desc
));
7254 surface_desc
.dwSize
= sizeof(surface_desc
);
7255 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7256 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
7257 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
7258 "Test %u: Got unexpected flags %#lx, expected %#lx.\n",
7259 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
7260 /* The pitch for textures seems to be implementation specific. */
7261 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
7263 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
7264 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
7265 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
7266 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
7268 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
7269 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
7270 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
7272 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
7274 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
7275 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7276 "Failed to get available video memory, hr %#lx.\n", hr
);
7277 if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
7279 /* Star Trek Starfleet Academy cares about this bit here: That creating a system memory
7280 * resource does not influence available video memory. */
7281 ok(vidmem_free2
== vidmem_free
, "Free video memory changed from %#lx to %#lx, test %u.\n",
7282 vidmem_free
, vidmem_free2
, i
);
7284 else if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
7286 /* DDSCAPS_ALLOCONLOAD does not seem to delay video memory allocation, at least not on
7289 * The amount of video memory consumed is different from what dwHeight * lPitch would
7290 * suggest, although not by much. */
7291 ok(vidmem_free2
< vidmem_free
,
7292 "Expected free video memory to change, but it did not, test %u.\n", i
);
7295 IDirectDrawSurface_Release(surface
);
7297 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
7298 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7299 "Failed to get available video memory, hr %#lx.\n", hr
);
7300 ok(hr
== DDERR_NODIRECTDRAWHW
|| vidmem_free2
== vidmem_free
,
7301 "Free video memory changed from %#lx to %#lx, test %u.\n",
7302 vidmem_free
, vidmem_free2
, i
);
7305 IDirectDrawSurface_Release(primary
);
7306 HeapFree(GetProcessHeap(), 0, mem
);
7307 refcount
= IDirectDraw2_Release(ddraw
);
7308 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7309 DestroyWindow(window
);
7312 static void test_mipmap(void)
7314 IDirectDrawSurface
*surface1
;
7315 IDirectDrawSurface2
*surface
, *surface_base
, *surface_mip
;
7316 unsigned int i
, mipmap_count
;
7317 DDSURFACEDESC surface_desc
;
7318 IDirectDraw2
*ddraw
;
7322 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7331 DWORD mipmap_count_in
;
7333 DWORD mipmap_count_out
;
7337 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
7338 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
7339 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
7340 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
7341 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
7342 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
7345 window
= create_window();
7346 ddraw
= create_ddraw();
7347 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7348 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7349 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7351 memset(&hal_caps
, 0, sizeof(hal_caps
));
7352 hal_caps
.dwSize
= sizeof(hal_caps
);
7353 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7354 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7355 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7357 skip("Mipmapped textures not supported, skipping tests.\n");
7358 IDirectDraw2_Release(ddraw
);
7359 DestroyWindow(window
);
7363 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7365 memset(&surface_desc
, 0, sizeof(surface_desc
));
7366 surface_desc
.dwSize
= sizeof(surface_desc
);
7367 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
7368 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7369 surface_desc
.dwWidth
= tests
[i
].width
;
7370 surface_desc
.dwHeight
= tests
[i
].height
;
7371 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
7372 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
7373 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7374 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
7378 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7379 ok(SUCCEEDED(hr
), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", i
, hr
);
7380 IDirectDrawSurface_Release(surface1
);
7382 memset(&surface_desc
, 0, sizeof(surface_desc
));
7383 surface_desc
.dwSize
= sizeof(surface_desc
);
7384 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
7385 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
7386 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7387 "Test %u: Got unexpected flags %#lx.\n", i
, surface_desc
.dwFlags
);
7388 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
7389 "Test %u: Got unexpected mipmap count %lu.\n", i
, U2(surface_desc
).dwMipMapCount
);
7391 surface_base
= surface
;
7392 IDirectDrawSurface2_AddRef(surface_base
);
7393 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
7394 while (mipmap_count
> 1)
7396 hr
= IDirectDrawSurface2_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
7397 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7399 memset(&surface_desc
, 0, sizeof(surface_desc
));
7400 surface_desc
.dwSize
= sizeof(surface_desc
);
7401 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface_base
, &surface_desc
);
7402 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#lx.\n", i
, mipmap_count
, hr
);
7403 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7404 "Test %u, %u: Got unexpected flags %#lx.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
7405 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
7406 "Test %u, %u: Got unexpected mipmap count %lu.\n",
7407 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
7409 memset(&surface_desc
, 0, sizeof(surface_desc
));
7410 surface_desc
.dwSize
= sizeof(surface_desc
);
7411 hr
= IDirectDrawSurface2_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
7412 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7413 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
7414 "Test %u, %u: unexpected change of mipmap count %lu.\n",
7415 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7416 memset(&surface_desc
, 0, sizeof(surface_desc
));
7417 surface_desc
.dwSize
= sizeof(surface_desc
);
7418 hr
= IDirectDrawSurface2_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
7419 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7420 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
7421 "Test %u, %u: Got unexpected child mipmap count %lu.\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7422 IDirectDrawSurface2_Unlock(surface_mip
, NULL
);
7423 IDirectDrawSurface2_Unlock(surface_base
, NULL
);
7425 IDirectDrawSurface2_Release(surface_base
);
7426 surface_base
= surface_mip
;
7429 IDirectDrawSurface2_Release(surface_base
);
7431 IDirectDrawSurface2_Release(surface
);
7434 refcount
= IDirectDraw2_Release(ddraw
);
7435 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7436 DestroyWindow(window
);
7439 static void test_palette_complex(void)
7441 IDirectDrawSurface
*surface1
;
7442 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
7443 DDSURFACEDESC surface_desc
;
7444 IDirectDraw2
*ddraw
;
7445 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
7449 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7451 PALETTEENTRY palette_entries
[256];
7457 window
= create_window();
7458 ddraw
= create_ddraw();
7459 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7460 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7461 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7463 memset(&hal_caps
, 0, sizeof(hal_caps
));
7464 hal_caps
.dwSize
= sizeof(hal_caps
);
7465 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7466 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7467 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7469 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
7470 IDirectDraw2_Release(ddraw
);
7471 DestroyWindow(window
);
7475 memset(&surface_desc
, 0, sizeof(surface_desc
));
7476 surface_desc
.dwSize
= sizeof(surface_desc
);
7477 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7478 surface_desc
.dwWidth
= 128;
7479 surface_desc
.dwHeight
= 128;
7480 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7481 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7482 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7483 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7484 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7485 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7486 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7487 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
7488 IDirectDrawSurface_Release(surface1
);
7490 memset(palette_entries
, 0, sizeof(palette_entries
));
7491 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7492 palette_entries
, &palette
, NULL
);
7493 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7495 memset(palette_entries
, 0, sizeof(palette_entries
));
7496 palette_entries
[1].peRed
= 0xff;
7497 palette_entries
[1].peGreen
= 0x80;
7498 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7499 palette_entries
, &palette_mipmap
, NULL
);
7500 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7502 palette2
= (void *)0xdeadbeef;
7503 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7504 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
7505 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
7506 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7507 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7508 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7509 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
7510 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
7511 IDirectDrawPalette_Release(palette2
);
7514 IDirectDrawSurface2_AddRef(mipmap
);
7515 for (i
= 0; i
< 7; ++i
)
7517 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7518 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
7519 palette2
= (void *)0xdeadbeef;
7520 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7521 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
7522 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
7524 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
7525 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#lx.\n", i
, hr
);
7527 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7528 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#lx.\n", i
, hr
);
7529 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
7530 IDirectDrawPalette_Release(palette2
);
7532 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
7533 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#lx.\n", i
, hr
);
7534 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7535 ok(count
== 1, "Expected count 1, got %u.\n", count
);
7536 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
7537 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
7538 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
7539 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
7540 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#lx.\n", i
, hr
);
7542 IDirectDrawSurface2_Release(mipmap
);
7546 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7547 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
7548 IDirectDrawSurface2_Release(mipmap
);
7549 refcount
= IDirectDrawSurface2_Release(surface
);
7550 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7551 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
7552 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7553 refcount
= IDirectDrawPalette_Release(palette
);
7554 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7556 refcount
= IDirectDraw2_Release(ddraw
);
7557 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7558 DestroyWindow(window
);
7561 static void test_p8_blit(void)
7563 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
7564 DDSURFACEDESC surface_desc
;
7565 unsigned int color
, x
;
7566 IDirectDraw2
*ddraw
;
7567 IDirectDrawPalette
*palette
, *palette2
;
7571 PALETTEENTRY palette_entries
[256];
7574 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
7575 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
7576 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
7577 static const unsigned int expected
[] =
7579 0x00101010, 0x00010101, 0x00020202, 0x00030303,
7580 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
7583 window
= create_window();
7584 ddraw
= create_ddraw();
7585 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7586 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7587 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7588 is_warp
= ddraw_is_warp(ddraw
);
7590 memset(palette_entries
, 0, sizeof(palette_entries
));
7591 palette_entries
[1].peGreen
= 0xff;
7592 palette_entries
[2].peBlue
= 0xff;
7593 palette_entries
[3].peFlags
= 0xff;
7594 palette_entries
[4].peRed
= 0xff;
7595 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7596 palette_entries
, &palette
, NULL
);
7597 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7598 palette_entries
[1].peBlue
= 0xff;
7599 palette_entries
[2].peGreen
= 0xff;
7600 palette_entries
[3].peRed
= 0xff;
7601 palette_entries
[4].peFlags
= 0x0;
7602 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7603 palette_entries
, &palette2
, NULL
);
7604 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7606 memset(&surface_desc
, 0, sizeof(surface_desc
));
7607 surface_desc
.dwSize
= sizeof(surface_desc
);
7608 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7609 surface_desc
.dwWidth
= 8;
7610 surface_desc
.dwHeight
= 1;
7611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7612 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7613 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7614 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7615 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
7616 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7617 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
7618 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7619 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
7620 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7622 memset(&surface_desc
, 0, sizeof(surface_desc
));
7623 surface_desc
.dwSize
= sizeof(surface_desc
);
7624 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7625 surface_desc
.dwWidth
= 8;
7626 surface_desc
.dwHeight
= 1;
7627 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7628 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7629 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7630 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7631 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7632 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7633 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7634 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
7635 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
7636 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7638 memset(&surface_desc
, 0, sizeof(surface_desc
));
7639 surface_desc
.dwSize
= sizeof(surface_desc
);
7640 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7641 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
7642 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
7643 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
7644 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
7646 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7647 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
7648 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
7649 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7650 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
7652 fx
.dwSize
= sizeof(fx
);
7653 fx
.dwFillColor
= 0xdeadbeef;
7654 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7655 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7657 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
7658 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7659 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
7660 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
7661 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
7662 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
7663 "Failed to blit, hr %#lx.\n", hr
);
7667 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
7669 color
= get_surface_color(dst
, x
, 0);
7670 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
7671 * blits see below. */
7672 todo_wine
ok(compare_color(color
, expected
[x
], 0)
7673 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
7674 "Pixel %u: Got color %#x, expected %#x.\n",
7675 x
, color
, expected
[x
]);
7679 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
7680 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
7681 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
7682 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
7684 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
7685 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
7686 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
7687 * surface untouched. Error checking (DDBLT_KEYSRC without a key
7688 * for example) also works as expected.
7690 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
7691 * the display mode set to P8 doesn't help either. */
7692 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
7693 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
7694 "Got unexpected P8 color key blit result.\n");
7695 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7696 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
7698 IDirectDrawSurface_Release(src
);
7699 IDirectDrawSurface_Release(dst
);
7700 IDirectDrawSurface_Release(dst_p8
);
7701 IDirectDrawPalette_Release(palette
);
7702 IDirectDrawPalette_Release(palette2
);
7704 refcount
= IDirectDraw2_Release(ddraw
);
7705 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7706 DestroyWindow(window
);
7709 static void test_material(void)
7711 IDirect3DMaterial2
*background
, *material
;
7712 D3DMATERIALHANDLE mat_handle
, tmp
;
7713 IDirect3DViewport2
*viewport
;
7714 IDirect3DDevice2
*device
;
7715 IDirectDrawSurface
*rt
;
7716 unsigned int color
, i
;
7717 IDirectDraw2
*ddraw
;
7723 static D3DVERTEX quad
[] =
7725 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7726 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7727 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7728 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7733 D3DCOLOR expected_color
;
7738 {FALSE
, 0x00ffffff},
7740 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7742 window
= create_window();
7743 ddraw
= create_ddraw();
7744 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7745 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7747 skip("Failed to create a 3D device, skipping test.\n");
7748 DestroyWindow(window
);
7752 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7753 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
7755 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
7756 viewport
= create_viewport(device
, 0, 0, 640, 480);
7757 viewport_set_background(device
, viewport
, background
);
7758 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7759 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
7761 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
7762 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7763 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
7765 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7766 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7767 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
7768 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7769 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7770 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7771 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7772 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7773 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
7774 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7775 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7776 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7777 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
7779 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7781 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
7782 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7784 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
7785 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7787 hr
= IDirect3DDevice2_BeginScene(device
);
7788 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
7789 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
7790 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
7791 hr
= IDirect3DDevice2_EndScene(device
);
7792 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
7793 color
= get_surface_color(rt
, 320, 240);
7794 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
7795 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
7798 destroy_material(material
);
7799 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7800 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7801 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
7803 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
7804 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
7805 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7806 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
7807 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7808 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7809 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7810 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7811 color
= get_surface_color(rt
, 320, 240);
7812 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7814 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
7815 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
7816 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7817 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
7818 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7819 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7820 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7821 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7822 color
= get_surface_color(rt
, 320, 240);
7823 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7825 destroy_viewport(device
, viewport
);
7826 viewport
= create_viewport(device
, 0, 0, 640, 480);
7828 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7829 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
7830 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
7831 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
7832 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7833 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7834 color
= get_surface_color(rt
, 320, 240);
7835 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
7837 destroy_viewport(device
, viewport
);
7838 destroy_material(background
);
7839 destroy_material(material
);
7840 IDirectDrawSurface_Release(rt
);
7841 refcount
= IDirect3DDevice2_Release(device
);
7842 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7843 refcount
= IDirectDraw2_Release(ddraw
);
7844 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
7845 DestroyWindow(window
);
7848 static void test_lighting(void)
7850 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7851 static D3DMATRIX mat
=
7853 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7854 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7855 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7856 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7860 1.0f
, 0.0f
, 1.0f
, 0.0f
,
7861 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7862 1.0f
, 0.0f
, 1.0f
, 0.0f
,
7863 0.0f
, 0.0f
, 0.5f
, 1.0f
,
7867 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7868 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7869 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
7870 10.f
, 10.0f
, 10.0f
, 1.0f
,
7874 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7875 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7876 0.0f
, 0.0f
, 1.0f
, -1.0f
,
7877 10.f
, 10.0f
, 10.0f
, 0.0f
,
7879 static D3DLVERTEX unlitquad
[] =
7881 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7882 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7883 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7884 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
7888 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7889 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7890 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7891 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
7893 static D3DVERTEX unlitnquad
[] =
7895 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7896 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7897 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7898 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7902 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7903 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7904 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7905 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7909 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7910 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7911 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7912 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7916 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7917 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7918 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7919 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
7923 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7924 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7925 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7926 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
7928 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
7931 D3DMATRIX
*world_matrix
;
7934 const char *message
;
7938 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
7939 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
7940 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
7941 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
7944 IDirect3DViewport2
*viewport
, *viewport2
;
7945 D3DMATERIALHANDLE mat_handle
;
7946 IDirect3DMaterial2
*material
;
7947 IDirect3DDevice2
*device
;
7948 IDirectDrawSurface
*rt
;
7949 IDirect3DLight
*light
;
7950 unsigned int color
, i
;
7951 D3DLIGHT2 light_desc
;
7952 IDirectDraw2
*ddraw
;
7958 window
= create_window();
7959 ddraw
= create_ddraw();
7960 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7961 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7963 skip("Failed to create a 3D device, skipping test.\n");
7964 DestroyWindow(window
);
7968 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
7969 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7971 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7972 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7974 viewport
= create_viewport(device
, 0, 0, 640, 480);
7975 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7976 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7978 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7979 viewport_set_background(device
, viewport
, material
);
7981 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7982 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7984 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
7985 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
7986 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
7987 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
7988 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
7989 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
7990 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7991 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#lx.\n", hr
);
7992 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7993 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
7994 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
7995 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
7997 hr
= IDirect3DDevice2_BeginScene(device
);
7998 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8000 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
8001 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
8002 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8003 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, unlitquad
,
8005 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8007 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
8008 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#lx.\n", hr
);
8009 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, litquad
,
8011 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8013 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
8014 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8015 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, unlitnquad
,
8017 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8019 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
8020 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8021 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, litnquad
,
8023 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8025 hr
= IDirect3DDevice2_EndScene(device
);
8026 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8028 color
= get_surface_color(rt
, 160, 360);
8029 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
8030 color
= get_surface_color(rt
, 160, 120);
8031 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
8032 color
= get_surface_color(rt
, 480, 360);
8033 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
8034 color
= get_surface_color(rt
, 480, 120);
8035 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
8037 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
8038 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8039 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8040 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8041 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
8042 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8044 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
8045 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8046 memset(&light_desc
, 0, sizeof(light_desc
));
8047 light_desc
.dwSize
= sizeof(light_desc
);
8048 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
8049 U1(light_desc
.dcvColor
).r
= 0.0f
;
8050 U2(light_desc
.dcvColor
).g
= 0.25f
;
8051 U3(light_desc
.dcvColor
).b
= 1.0f
;
8052 U4(light_desc
.dcvColor
).a
= 1.0f
;
8053 U3(light_desc
.dvDirection
).z
= 1.0f
;
8054 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
8055 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8056 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8057 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8058 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8059 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
8061 viewport2
= create_viewport(device
, 0, 0, 640, 480);
8062 hr
= IDirect3DViewport2_AddLight(viewport2
, light
);
8063 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
8064 destroy_viewport(device
, viewport2
);
8066 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8067 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8069 hr
= IDirect3DDevice2_BeginScene(device
);
8070 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8072 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, nquad
,
8074 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8076 hr
= IDirect3DDevice2_EndScene(device
);
8077 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8079 color
= get_surface_color(rt
, 320, 240);
8080 ok(color
== 0x00002000, "Lit quad with no light has color 0x%08x.\n", color
);
8082 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
8083 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
8084 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8085 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8086 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8087 light_desc
.dwFlags
= 0;
8088 hr
= IDirect3DLight_GetLight(light
, (D3DLIGHT
*)&light_desc
);
8089 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8090 ok(light_desc
.dwFlags
== D3DLIGHT_ACTIVE
, "Got unexpected flags %#lx.\n", light_desc
.dwFlags
);
8092 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8093 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8094 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8096 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
8097 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
8099 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8100 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8102 hr
= IDirect3DDevice2_BeginScene(device
);
8103 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8105 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
8106 tests
[i
].quad
, 4, indices
, 6, 0);
8107 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8109 hr
= IDirect3DDevice2_EndScene(device
);
8110 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8112 color
= get_surface_color(rt
, 320, 240);
8113 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
8116 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8117 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#lx.\n", hr
);
8118 IDirect3DLight_Release(light
);
8119 destroy_material(material
);
8120 destroy_viewport(device
, viewport
);
8121 IDirectDrawSurface2_Release(rt
);
8122 refcount
= IDirect3DDevice2_Release(device
);
8123 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8124 IDirect3D2_Release(d3d
);
8125 refcount
= IDirectDraw2_Release(ddraw
);
8126 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
8127 DestroyWindow(window
);
8130 static void test_specular_lighting(void)
8132 static const unsigned int vertices_side
= 5;
8133 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
8134 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8135 static D3DMATRIX mat
=
8137 1.0f
, 0.0f
, 0.0f
, 0.0f
,
8138 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8139 0.0f
, 0.0f
, 1.0f
, 0.0f
,
8140 0.0f
, 0.0f
, 0.0f
, 1.0f
,
8142 static D3DLIGHT2 directional
=
8145 D3DLIGHT_DIRECTIONAL
,
8146 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8147 {{0.0f
}, {0.0f
}, {0.0f
}},
8148 {{0.0f
}, {0.0f
}, {1.0f
}},
8154 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8155 {{0.0f
}, {0.0f
}, {0.0f
}},
8156 {{0.0f
}, {0.0f
}, {0.0f
}},
8165 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8166 {{0.0f
}, {0.0f
}, {0.0f
}},
8167 {{0.0f
}, {0.0f
}, {1.0f
}},
8171 M_PI
/ 12.0f
, M_PI
/ 3.0f
8176 D3DLIGHT_PARALLELPOINT
,
8177 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8178 {{0.5f
}, {0.0f
}, {-1.0f
}},
8179 {{0.0f
}, {0.0f
}, {0.0f
}},
8185 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8186 {{-1.1f
}, {0.0f
}, {1.1f
}},
8187 {{0.0f
}, {0.0f
}, {0.0f
}},
8196 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8197 {{0.0f
}, {0.0f
}, {0.1f
}},
8198 {{0.0f
}, {0.0f
}, {0.0f
}},
8203 static const struct expected_color
8205 unsigned int x
, y
, color
;
8207 expected_directional_local
[] =
8209 {160, 120, 0x003c3c3c},
8210 {320, 120, 0x00717171},
8211 {480, 120, 0x003c3c3c},
8212 {160, 240, 0x00717171},
8213 {320, 240, 0x00ffffff},
8214 {480, 240, 0x00717171},
8215 {160, 360, 0x003c3c3c},
8216 {320, 360, 0x00717171},
8217 {480, 360, 0x003c3c3c},
8219 expected_point_local
[] =
8221 {160, 120, 0x00000000},
8222 {320, 120, 0x00090909},
8223 {480, 120, 0x00000000},
8224 {160, 240, 0x00090909},
8225 {320, 240, 0x00fafafa},
8226 {480, 240, 0x00090909},
8227 {160, 360, 0x00000000},
8228 {320, 360, 0x00090909},
8229 {480, 360, 0x00000000},
8231 expected_spot_local
[] =
8233 {160, 120, 0x00000000},
8234 {320, 120, 0x00020202},
8235 {480, 120, 0x00000000},
8236 {160, 240, 0x00020202},
8237 {320, 240, 0x00fafafa},
8238 {480, 240, 0x00020202},
8239 {160, 360, 0x00000000},
8240 {320, 360, 0x00020202},
8241 {480, 360, 0x00000000},
8243 expected_parallelpoint
[] =
8245 {160, 120, 0x00050505},
8246 {320, 120, 0x002c2c2c},
8247 {480, 120, 0x006e6e6e},
8248 {160, 240, 0x00090909},
8249 {320, 240, 0x00717171},
8250 {480, 240, 0x00ffffff},
8251 {160, 360, 0x00050505},
8252 {320, 360, 0x002c2c2c},
8253 {480, 360, 0x006e6e6e},
8255 expected_point_far
[] =
8257 {160, 120, 0x00000000},
8258 {320, 120, 0x00000000},
8259 {480, 120, 0x00000000},
8260 {160, 240, 0x00000000},
8261 {320, 240, 0x00ffffff},
8262 {480, 240, 0x00000000},
8263 {160, 360, 0x00000000},
8264 {320, 360, 0x00000000},
8265 {480, 360, 0x00000000},
8269 {160, 120, 0x00000000},
8270 {320, 120, 0x00000000},
8271 {480, 120, 0x00000000},
8272 {160, 240, 0x00000000},
8273 {320, 240, 0x00000000},
8274 {480, 240, 0x00000000},
8275 {160, 360, 0x00000000},
8276 {320, 360, 0x00000000},
8277 {480, 360, 0x00000000},
8282 float specular_power
;
8283 const struct expected_color
*expected
;
8284 unsigned int expected_count
;
8288 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
8289 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
8290 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
8291 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
8292 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8293 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
8294 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8295 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8296 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8297 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8298 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8301 IDirect3DDevice2
*device
;
8302 IDirectDraw2
*ddraw
;
8303 IDirectDrawSurface
*rt
;
8304 IDirect3DViewport2
*viewport
;
8305 IDirect3DMaterial2
*material
, *background_material
;
8306 unsigned int color
, i
, j
, x
, y
;
8307 IDirect3DLight
*light
;
8308 D3DMATERIALHANDLE mat_handle
;
8315 window
= create_window();
8316 ddraw
= create_ddraw();
8317 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8318 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8320 skip("Failed to create a 3D device, skipping test.\n");
8321 DestroyWindow(window
);
8325 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
8326 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
8327 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
8329 for (x
= 0; x
< vertices_side
; ++x
)
8331 U1(quad
[i
]).x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8332 U2(quad
[i
]).y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8333 U3(quad
[i
]).z
= 1.0f
;
8334 U4(quad
[i
]).nx
= 0.0f
;
8335 U5(quad
[i
]).ny
= 0.0f
;
8336 U6(quad
[i
]).nz
= -1.0f
;
8337 U7(quad
[i
]).tu
= 0.0f
;
8338 U8(quad
[i
++]).tv
= 0.0f
;
8341 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
8343 for (x
= 0; x
< (vertices_side
- 1); ++x
)
8345 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8346 indices
[i
++] = y
* vertices_side
+ x
;
8347 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8348 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8349 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8350 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
8354 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
8355 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
8357 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8358 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8360 viewport
= create_viewport(device
, 0, 0, 640, 480);
8361 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8362 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
8364 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
8365 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
8366 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
8367 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
8368 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
8369 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
8370 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
8371 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
8372 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
8373 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
8375 background_material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
8376 viewport_set_background(device
, viewport
, background_material
);
8378 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
8379 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#lx.\n", hr
);
8380 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8381 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#lx.\n", hr
);
8383 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
8384 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#lx.\n", hr
);
8386 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8388 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
8389 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
8390 ok(SUCCEEDED(hr
), "Failed to set light, hr %#lx.\n", hr
);
8392 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
8393 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
8394 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
8395 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8396 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
8398 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8399 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8401 hr
= IDirect3DDevice2_BeginScene(device
);
8402 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8404 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
8405 quad
, vertices_side
* vertices_side
, indices
, indices_count
, 0);
8406 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8408 hr
= IDirect3DDevice2_EndScene(device
);
8409 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8411 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
8413 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
8414 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
8415 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
8416 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
8417 tests
[i
].expected
[j
].y
, color
, i
);
8420 destroy_material(material
);
8423 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8424 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#lx.\n", hr
);
8425 IDirect3DLight_Release(light
);
8426 destroy_material(background_material
);
8427 destroy_viewport(device
, viewport
);
8428 IDirectDrawSurface2_Release(rt
);
8429 refcount
= IDirect3DDevice2_Release(device
);
8430 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8431 IDirect3D2_Release(d3d
);
8432 refcount
= IDirectDraw2_Release(ddraw
);
8433 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
8434 DestroyWindow(window
);
8435 HeapFree(GetProcessHeap(), 0, indices
);
8436 HeapFree(GetProcessHeap(), 0, quad
);
8439 static void test_palette_gdi(void)
8441 IDirectDrawSurface
*surface
, *primary
;
8442 DDSURFACEDESC surface_desc
;
8443 unsigned int color
, i
;
8444 IDirectDraw2
*ddraw
;
8445 IDirectDrawPalette
*palette
, *palette2
;
8449 PALETTEENTRY palette_entries
[256];
8454 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8455 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8456 * not the point of this test. */
8457 static const RGBQUAD expected1
[] =
8459 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8460 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8462 static const RGBQUAD expected2
[] =
8464 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8465 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8467 static const RGBQUAD expected3
[] =
8469 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8470 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8472 HPALETTE ddraw_palette_handle
;
8473 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8474 RGBQUAD rgbquad
[255];
8475 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8477 window
= create_window();
8478 ddraw
= create_ddraw();
8479 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8480 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8481 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8483 memset(&surface_desc
, 0, sizeof(surface_desc
));
8484 surface_desc
.dwSize
= sizeof(surface_desc
);
8485 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8486 surface_desc
.dwWidth
= 16;
8487 surface_desc
.dwHeight
= 16;
8488 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8489 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8490 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8491 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
8492 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8493 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8495 /* Avoid colors from the Windows default palette. */
8496 memset(palette_entries
, 0, sizeof(palette_entries
));
8497 palette_entries
[1].peRed
= 0x01;
8498 palette_entries
[2].peGreen
= 0x02;
8499 palette_entries
[3].peBlue
= 0x03;
8500 palette_entries
[4].peRed
= 0x13;
8501 palette_entries
[4].peGreen
= 0x14;
8502 palette_entries
[4].peBlue
= 0x15;
8503 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8504 palette_entries
, &palette
, NULL
);
8505 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8507 /* If there is no palette assigned and the display mode is not 8 bpp, some
8508 * drivers refuse to create a DC while others allow it. If a DC is created,
8509 * the DIB color table is uninitialized and contains random colors. No error
8510 * is generated when trying to read pixels and random garbage is returned.
8512 * The most likely explanation is that if the driver creates a DC, it (or
8513 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8514 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8515 * contains uninitialized garbage. See comments below for the P8 case. */
8517 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8518 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8519 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8520 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8521 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8522 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8523 "Got unexpected palette %p, expected %p.\n",
8524 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8526 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8527 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8528 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8530 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8531 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8532 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8533 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8535 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8537 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8538 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8539 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8542 /* Update the palette while the DC is in use. This does not modify the DC. */
8543 palette_entries
[4].peRed
= 0x23;
8544 palette_entries
[4].peGreen
= 0x24;
8545 palette_entries
[4].peBlue
= 0x25;
8546 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8547 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
8549 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8550 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8551 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8552 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8553 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8554 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8556 /* Neither does re-setting the palette. */
8557 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
8558 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8559 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8560 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8562 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8563 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8564 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8565 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8566 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8567 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8569 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8570 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8572 /* Refresh the DC. This updates the palette. */
8573 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8574 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8575 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8576 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8577 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8579 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8580 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8581 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8582 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8584 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8586 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8587 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8588 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8590 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8591 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8593 refcount
= IDirectDrawSurface_Release(surface
);
8594 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8596 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8597 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8598 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8600 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8601 IDirectDrawPalette_Release(palette
);
8602 IDirectDraw2_Release(ddraw
);
8603 DestroyWindow(window
);
8606 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
8608 memset(&surface_desc
, 0, sizeof(surface_desc
));
8609 surface_desc
.dwSize
= sizeof(surface_desc
);
8610 surface_desc
.dwFlags
= DDSD_CAPS
;
8611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8612 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8613 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8615 memset(&fx
, 0, sizeof(fx
));
8616 fx
.dwSize
= sizeof(fx
);
8617 U5(fx
).dwFillColor
= 3;
8618 SetRect(&r
, 0, 0, 319, 479);
8619 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8620 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
8621 SetRect(&r
, 320, 0, 639, 479);
8622 U5(fx
).dwFillColor
= 4;
8623 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8624 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
8626 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
8627 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8628 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
8629 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8631 color
= GetPixel(dc
, 160, 240);
8632 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8633 color
= GetPixel(dc
, 480, 240);
8634 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8636 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8637 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8638 "Got unexpected palette %p, expected %p.\n",
8639 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8640 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8642 /* The primary uses the system palette. In exclusive mode, the system palette matches
8643 * the ddraw palette attached to the primary, so the result is what you would expect
8644 * from a regular surface. Tests for the interaction between the ddraw palette and
8645 * the system palette are not included pending an application that depends on this.
8646 * The relation between those causes problems on Windows Vista and newer for games
8647 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8648 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8649 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8650 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8652 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8653 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8654 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8655 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8657 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8659 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8660 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8661 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8663 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
8664 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8666 memset(&surface_desc
, 0, sizeof(surface_desc
));
8667 surface_desc
.dwSize
= sizeof(surface_desc
);
8668 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8669 surface_desc
.dwWidth
= 16;
8670 surface_desc
.dwHeight
= 16;
8671 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8672 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8673 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8675 /* Here the offscreen surface appears to use the primary's palette,
8676 * but in all likelihood it is actually the system palette. */
8677 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8678 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8679 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8680 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8681 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8683 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8684 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8685 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8686 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8688 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8690 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8691 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8692 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8694 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8695 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8697 /* On real hardware a change to the primary surface's palette applies immediately,
8698 * even on device contexts from offscreen surfaces that do not have their own
8699 * palette. On the testbot VMs this is not the case. Don't test this until we
8700 * know of an application that depends on this. */
8702 memset(palette_entries
, 0, sizeof(palette_entries
));
8703 palette_entries
[1].peBlue
= 0x40;
8704 palette_entries
[2].peRed
= 0x40;
8705 palette_entries
[3].peGreen
= 0x40;
8706 palette_entries
[4].peRed
= 0x12;
8707 palette_entries
[4].peGreen
= 0x34;
8708 palette_entries
[4].peBlue
= 0x56;
8709 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8710 palette_entries
, &palette2
, NULL
);
8711 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8712 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
8713 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8715 /* A palette assigned to the offscreen surface overrides the primary / system
8717 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8718 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8719 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8720 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8721 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
8723 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
8724 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8725 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8726 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
8728 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8730 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8731 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8732 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8734 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8735 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8737 refcount
= IDirectDrawSurface_Release(surface
);
8738 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8740 /* The Windows 8 testbot keeps extra references to the primary and
8741 * backbuffer while in 8 bpp mode. */
8742 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8743 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
8745 refcount
= IDirectDrawSurface_Release(primary
);
8746 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8747 refcount
= IDirectDrawPalette_Release(palette2
);
8748 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8749 refcount
= IDirectDrawPalette_Release(palette
);
8750 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8751 refcount
= IDirectDraw2_Release(ddraw
);
8752 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8753 DestroyWindow(window
);
8756 static void test_palette_alpha(void)
8758 IDirectDrawSurface
*surface1
;
8759 IDirectDrawSurface2
*surface
;
8760 DDSURFACEDESC surface_desc
;
8761 IDirectDraw2
*ddraw
;
8762 IDirectDrawPalette
*palette
;
8766 PALETTEENTRY palette_entries
[256];
8771 BOOL attach_allowed
;
8776 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
8777 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
8778 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
8781 window
= create_window();
8782 ddraw
= create_ddraw();
8783 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8784 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8786 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8787 IDirectDraw2_Release(ddraw
);
8788 DestroyWindow(window
);
8791 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8792 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8794 memset(palette_entries
, 0, sizeof(palette_entries
));
8795 palette_entries
[1].peFlags
= 0x42;
8796 palette_entries
[2].peFlags
= 0xff;
8797 palette_entries
[3].peFlags
= 0x80;
8798 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
8799 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8801 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8802 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8803 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
8804 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8805 palette_entries
[0].peFlags
);
8806 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8807 palette_entries
[1].peFlags
);
8808 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8809 palette_entries
[2].peFlags
);
8810 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8811 palette_entries
[3].peFlags
);
8813 IDirectDrawPalette_Release(palette
);
8815 memset(palette_entries
, 0, sizeof(palette_entries
));
8816 palette_entries
[1].peFlags
= 0x42;
8817 palette_entries
[1].peRed
= 0xff;
8818 palette_entries
[2].peFlags
= 0xff;
8819 palette_entries
[3].peFlags
= 0x80;
8820 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
8821 palette_entries
, &palette
, NULL
);
8822 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8824 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8825 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8826 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
8827 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8828 palette_entries
[0].peFlags
);
8829 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8830 palette_entries
[1].peFlags
);
8831 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8832 palette_entries
[2].peFlags
);
8833 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8834 palette_entries
[3].peFlags
);
8836 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
8838 memset(&surface_desc
, 0, sizeof(surface_desc
));
8839 surface_desc
.dwSize
= sizeof(surface_desc
);
8840 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
8841 surface_desc
.dwWidth
= 128;
8842 surface_desc
.dwHeight
= 128;
8843 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8844 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8845 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
8846 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
8847 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
8848 IDirectDrawSurface_Release(surface1
);
8850 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
8851 if (test_data
[i
].attach_allowed
)
8852 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
8854 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
8862 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
8863 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
8864 "Failed to get DC, hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
8867 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8868 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
8869 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
8870 rgbquad
.rgbRed
, test_data
[i
].name
);
8871 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
8872 rgbquad
.rgbGreen
, test_data
[i
].name
);
8873 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
8874 rgbquad
.rgbBlue
, test_data
[i
].name
);
8875 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
8876 rgbquad
.rgbReserved
, test_data
[i
].name
);
8877 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
8878 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8881 IDirectDrawSurface2_Release(surface
);
8884 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8885 memset(&surface_desc
, 0, sizeof(surface_desc
));
8886 surface_desc
.dwSize
= sizeof(surface_desc
);
8887 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8888 surface_desc
.dwWidth
= 128;
8889 surface_desc
.dwHeight
= 128;
8890 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8891 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8892 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8893 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8894 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8895 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8896 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8897 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8898 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8899 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
8900 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
8901 IDirectDrawSurface_Release(surface1
);
8903 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
8904 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
8905 IDirectDrawSurface2_Release(surface
);
8907 /* The Windows 8 testbot keeps extra references to the primary
8908 * while in 8 bpp mode. */
8909 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8910 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
8912 refcount
= IDirectDrawPalette_Release(palette
);
8913 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8914 refcount
= IDirectDraw2_Release(ddraw
);
8915 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8916 DestroyWindow(window
);
8919 static void test_lost_device(void)
8921 IDirectDrawSurface
*surface
, *back_buffer
, *back_buffer2
, *ds
;
8922 IDirectDrawSurface
*sysmem_surface
, *vidmem_surface
;
8923 DDSURFACEDESC surface_desc
;
8924 HWND window1
, window2
;
8925 IDirectDraw2
*ddraw
;
8931 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8932 0, 0, 640, 480, 0, 0, 0, 0);
8933 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8934 0, 0, 640, 480, 0, 0, 0, 0);
8935 ddraw
= create_ddraw();
8936 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8937 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8938 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8940 memset(&surface_desc
, 0, sizeof(surface_desc
));
8941 surface_desc
.dwSize
= sizeof(surface_desc
);
8942 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8943 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8944 surface_desc
.dwBackBufferCount
= 1;
8945 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8946 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8948 memset(&surface_desc
, 0, sizeof(surface_desc
));
8949 surface_desc
.dwSize
= sizeof(surface_desc
);
8950 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8951 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
8952 surface_desc
.dwWidth
= 100;
8953 surface_desc
.dwHeight
= 100;
8954 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
8955 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8957 memset(&surface_desc
, 0, sizeof(surface_desc
));
8958 surface_desc
.dwSize
= sizeof(surface_desc
);
8959 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8960 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
8961 surface_desc
.dwWidth
= 64;
8962 surface_desc
.dwHeight
= 64;
8963 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8964 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8965 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8966 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8967 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8968 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8969 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
8971 skip("Failed to create video memory surface, skipping related tests.\n");
8972 vidmem_surface
= NULL
;
8975 hr
= IDirectDrawSurface_IsLost(surface
);
8976 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8977 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8978 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8979 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8980 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8983 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8984 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8987 ret
= SetForegroundWindow(GetDesktopWindow());
8988 ok(ret
, "Failed to set foreground window.\n");
8989 hr
= IDirectDrawSurface_IsLost(surface
);
8990 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8991 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8992 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8993 hr
= IDirectDrawSurface_Restore(surface
);
8994 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8995 hr
= IDirectDrawSurface_IsLost(surface
);
8996 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8997 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8998 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8999 hr
= IDirectDrawSurface_Restore(sysmem_surface
);
9000 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9001 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9002 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9005 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9006 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9007 hr
= IDirectDrawSurface_Restore(vidmem_surface
);
9008 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
9009 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9010 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9013 ret
= SetForegroundWindow(window1
);
9014 ok(ret
, "Failed to set foreground window.\n");
9015 hr
= IDirectDrawSurface_IsLost(surface
);
9016 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9017 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9018 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9019 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9020 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9023 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9024 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9027 hr
= restore_surfaces(ddraw
);
9028 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9029 hr
= IDirectDrawSurface_IsLost(surface
);
9030 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9031 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9032 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9033 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9034 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9037 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9038 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9041 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9042 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9043 hr
= IDirectDrawSurface_IsLost(surface
);
9044 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9045 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9046 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9047 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9048 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9051 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9052 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9055 /* Trying to restore the primary will crash, probably because flippable
9056 * surfaces can't exist in DDSCL_NORMAL. */
9057 IDirectDrawSurface_Release(surface
);
9058 memset(&surface_desc
, 0, sizeof(surface_desc
));
9059 surface_desc
.dwSize
= sizeof(surface_desc
);
9060 surface_desc
.dwFlags
= DDSD_CAPS
;
9061 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9062 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9063 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9064 hr
= restore_surfaces(ddraw
);
9065 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9067 hr
= IDirectDrawSurface_IsLost(surface
);
9068 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9070 ret
= SetForegroundWindow(GetDesktopWindow());
9071 ok(ret
, "Failed to set foreground window.\n");
9072 hr
= IDirectDrawSurface_IsLost(surface
);
9073 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9074 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9075 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9078 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9079 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9082 ret
= SetForegroundWindow(window1
);
9083 ok(ret
, "Failed to set foreground window.\n");
9084 hr
= IDirectDrawSurface_IsLost(surface
);
9085 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9086 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9087 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9090 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9091 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9094 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9095 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9096 hr
= IDirectDrawSurface_IsLost(surface
);
9097 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9098 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9099 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9102 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9103 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9106 hr
= restore_surfaces(ddraw
);
9107 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9108 hr
= IDirectDrawSurface_IsLost(surface
);
9109 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9110 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9111 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9114 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9115 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9118 IDirectDrawSurface_Release(surface
);
9119 memset(&surface_desc
, 0, sizeof(surface_desc
));
9120 surface_desc
.dwSize
= sizeof(surface_desc
);
9121 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9122 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9123 surface_desc
.dwBackBufferCount
= 2;
9124 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9125 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9128 memset(&surface_desc
, 0, sizeof(surface_desc
));
9129 surface_desc
.dwSize
= sizeof(surface_desc
);
9130 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
9131 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9133 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
9134 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9135 U2(surface_desc
).dwZBufferBitDepth
= 16;
9136 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
9139 skip("Could not create Z buffer, skipping Z buffer restore test.\n");
9143 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
9144 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9147 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9148 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9149 hr
= IDirectDrawSurface_IsLost(surface
);
9150 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9151 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9152 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9153 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9154 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9157 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9158 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9161 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9162 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9163 hr
= IDirectDrawSurface_IsLost(surface
);
9164 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9165 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9166 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9167 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9168 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9171 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9172 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9175 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9176 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9177 hr
= IDirectDrawSurface_IsLost(surface
);
9178 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9179 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9180 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9181 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9182 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9185 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9186 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9189 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
9190 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9191 hr
= IDirectDrawSurface_IsLost(surface
);
9192 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9193 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9194 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9195 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9196 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9199 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9200 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9203 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9204 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9205 hr
= IDirectDrawSurface_IsLost(surface
);
9206 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9207 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9208 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9209 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9210 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9213 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9214 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9217 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9218 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9219 hr
= IDirectDrawSurface_IsLost(surface
);
9220 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9221 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9222 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9223 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9224 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9227 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9228 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9231 memset(&caps
, 0, sizeof(caps
));
9232 caps
.dwCaps
= DDSCAPS_FLIP
;
9234 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9235 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9236 ok(back_buffer
!= surface
, "Got the same surface.\n");
9237 hr
= IDirectDrawSurface_Restore(surface
);
9238 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9239 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9240 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9241 hr
= IDirectDrawSurface_IsLost(back_buffer
);
9242 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9243 IDirectDrawSurface_Release(back_buffer
);
9245 hr
= IDirectDrawSurface_GetAttachedSurface(back_buffer
, &caps
, &back_buffer2
);
9246 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9247 ok(back_buffer2
!= back_buffer
, "Got the same surface.\n");
9248 ok(back_buffer2
!= surface
, "Got the same surface.\n");
9249 hr
= IDirectDrawSurface_IsLost(back_buffer2
);
9250 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9251 IDirectDrawSurface_Release(back_buffer2
);
9255 hr
= IDirectDrawSurface_IsLost(ds
);
9256 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9257 hr
= IDirectDrawSurface_Restore(ds
);
9258 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9259 hr
= IDirectDrawSurface_IsLost(ds
);
9260 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9261 IDirectDrawSurface_Release(ds
);
9265 IDirectDrawSurface_Release(vidmem_surface
);
9266 IDirectDrawSurface_Release(sysmem_surface
);
9267 IDirectDrawSurface_Release(surface
);
9268 refcount
= IDirectDraw2_Release(ddraw
);
9269 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9270 DestroyWindow(window2
);
9271 DestroyWindow(window1
);
9274 static void test_surface_desc_lock(void)
9276 IDirectDrawSurface
*surface
;
9277 DDSURFACEDESC surface_desc
;
9278 IDirectDraw2
*ddraw
;
9283 window
= create_window();
9284 ddraw
= create_ddraw();
9285 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9286 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9287 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9289 memset(&surface_desc
, 0, sizeof(surface_desc
));
9290 surface_desc
.dwSize
= sizeof(surface_desc
);
9291 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9292 surface_desc
.dwWidth
= 16;
9293 surface_desc
.dwHeight
= 16;
9294 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9295 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9296 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9298 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9299 surface_desc
.dwSize
= sizeof(surface_desc
);
9300 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9301 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9302 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9304 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9305 surface_desc
.dwSize
= sizeof(surface_desc
);
9306 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9307 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9308 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9309 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9310 surface_desc
.dwSize
= sizeof(surface_desc
);
9311 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9312 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9313 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9314 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9315 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9317 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9318 surface_desc
.dwSize
= sizeof(surface_desc
);
9319 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9320 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9321 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9323 IDirectDrawSurface_Release(surface
);
9324 refcount
= IDirectDraw2_Release(ddraw
);
9325 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9326 DestroyWindow(window
);
9329 static void test_texturemapblend(void)
9334 static RECT rect
= {0, 0, 64, 128};
9335 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9337 IDirectDrawSurface
*surface
, *rt
;
9338 IDirect3DTexture2
*texture
;
9339 D3DTEXTUREHANDLE texture_handle
;
9342 IDirectDraw2
*ddraw
;
9343 IDirect3DDevice2
*device
;
9344 IDirect3DMaterial2
*material
;
9345 IDirect3DViewport2
*viewport
;
9348 static D3DTLVERTEX test1_quads
[] =
9350 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
9351 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
9352 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
9353 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
9354 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
9355 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
9356 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
9357 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
9361 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
9362 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
9363 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
9364 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
9365 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
9366 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
9367 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
9368 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
9371 window
= create_window();
9372 ddraw
= create_ddraw();
9373 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9374 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9376 skip("Failed to create a 3D device, skipping test.\n");
9377 DestroyWindow(window
);
9378 IDirectDraw2_Release(ddraw
);
9382 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9383 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9385 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
9386 viewport
= create_viewport(device
, 0, 0, 640, 480);
9387 viewport_set_background(device
, viewport
, material
);
9388 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9389 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
9391 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
9393 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
9394 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
9395 memset(&ddsd
, 0, sizeof(ddsd
));
9396 ddsd
.dwSize
= sizeof(ddsd
);
9397 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9398 ddsd
.dwHeight
= 128;
9400 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9401 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9402 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9403 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9404 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9405 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9406 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9407 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9408 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9409 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9411 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9412 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9413 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9414 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9415 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9416 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9418 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9419 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9421 memset(&fx
, 0, sizeof(fx
));
9422 fx
.dwSize
= sizeof(fx
);
9423 U5(fx
).dwFillColor
= 0xff0000ff;
9424 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9425 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9426 U5(fx
).dwFillColor
= 0x800000ff;
9427 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9428 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9430 /* Note that the ddraw1 version of this test runs tests 1-3 with D3DRENDERSTATE_COLORKEYENABLE
9431 * enabled, whereas this version only runs test 4 with color keying on. Because no color key
9432 * is set on the texture this should not result in different behavior. */
9433 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9434 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9435 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9436 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9437 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9438 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9439 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9440 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9441 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9442 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9443 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9444 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9446 hr
= IDirect3DDevice2_BeginScene(device
);
9447 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9448 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9449 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9450 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9451 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9452 hr
= IDirect3DDevice2_EndScene(device
);
9453 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9455 color
= get_surface_color(rt
, 5, 5);
9456 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9457 color
= get_surface_color(rt
, 400, 5);
9458 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9459 color
= get_surface_color(rt
, 5, 245);
9460 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9461 color
= get_surface_color(rt
, 400, 245);
9462 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9464 IDirect3DTexture2_Release(texture
);
9465 ref
= IDirectDrawSurface_Release(surface
);
9466 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9468 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
9469 memset(&ddsd
, 0, sizeof(ddsd
));
9470 ddsd
.dwSize
= sizeof(ddsd
);
9471 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9472 ddsd
.dwHeight
= 128;
9474 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9475 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9476 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9477 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9478 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9479 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9480 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9482 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9483 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9485 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9486 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9487 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9488 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9489 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9490 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9492 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9493 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9495 U5(fx
).dwFillColor
= 0xff0000ff;
9496 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9497 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9498 U5(fx
).dwFillColor
= 0x800000ff;
9499 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9500 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9502 hr
= IDirect3DDevice2_BeginScene(device
);
9503 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9504 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9505 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9506 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9507 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9508 hr
= IDirect3DDevice2_EndScene(device
);
9509 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9511 color
= get_surface_color(rt
, 5, 5);
9512 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9513 color
= get_surface_color(rt
, 400, 5);
9514 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9515 color
= get_surface_color(rt
, 5, 245);
9516 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9517 color
= get_surface_color(rt
, 400, 245);
9518 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9520 IDirect3DTexture2_Release(texture
);
9521 ref
= IDirectDrawSurface_Release(surface
);
9522 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9524 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
9525 memset(&ddsd
, 0, sizeof(ddsd
));
9526 ddsd
.dwSize
= sizeof(ddsd
);
9527 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9528 ddsd
.dwHeight
= 128;
9530 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9531 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9532 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9533 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9534 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9535 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9536 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9537 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9538 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9539 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9541 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9542 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9543 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9544 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9545 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9546 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9548 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9549 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9551 U5(fx
).dwFillColor
= 0x00ffffff;
9552 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9553 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9554 U5(fx
).dwFillColor
= 0x00ffff80;
9555 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9556 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9558 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9559 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9561 hr
= IDirect3DDevice2_BeginScene(device
);
9562 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9563 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[0], 4, 0);
9564 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9565 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[4], 4, 0);
9566 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9567 hr
= IDirect3DDevice2_EndScene(device
);
9568 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9570 color
= get_surface_color(rt
, 5, 5);
9571 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9572 color
= get_surface_color(rt
, 400, 5);
9573 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9574 color
= get_surface_color(rt
, 5, 245);
9575 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9576 color
= get_surface_color(rt
, 400, 245);
9577 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9579 IDirect3DTexture2_Release(texture
);
9580 ref
= IDirectDrawSurface_Release(surface
);
9581 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9583 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
9584 memset(&ddsd
, 0, sizeof(ddsd
));
9585 ddsd
.dwSize
= sizeof(ddsd
);
9586 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9587 ddsd
.dwHeight
= 128;
9589 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9590 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9591 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9592 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
9593 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
9594 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9595 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
9597 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9598 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9600 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9601 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9602 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9603 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9604 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9605 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9607 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9608 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9610 U5(fx
).dwFillColor
= 0xf800;
9611 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9612 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9613 U5(fx
).dwFillColor
= 0x001f;
9614 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9615 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9617 ckey
.dwColorSpaceLowValue
= 0x001f;
9618 ckey
.dwColorSpaceHighValue
= 0x001f;
9619 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9620 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9622 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9623 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9624 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9625 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9627 hr
= IDirect3DDevice2_BeginScene(device
);
9628 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9629 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9630 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9631 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9632 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9633 hr
= IDirect3DDevice2_EndScene(device
);
9634 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9636 color
= get_surface_color(rt
, 5, 5);
9637 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9638 color
= get_surface_color(rt
, 400, 5);
9639 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9640 color
= get_surface_color(rt
, 5, 245);
9641 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9642 color
= get_surface_color(rt
, 400, 245);
9643 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9645 IDirect3DTexture2_Release(texture
);
9646 ref
= IDirectDrawSurface_Release(surface
);
9647 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9649 destroy_viewport(device
, viewport
);
9650 ref
= IDirect3DMaterial2_Release(material
);
9651 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9652 IDirectDrawSurface_Release(rt
);
9653 IDirect3DDevice2_Release(device
);
9654 ref
= IDirectDraw2_Release(ddraw
);
9655 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9656 DestroyWindow(window
);
9659 static void test_viewport_clear_rect(void)
9662 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9663 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
9664 IDirectDrawSurface
*rt
;
9667 IDirectDraw2
*ddraw
;
9668 IDirect3DDevice2
*device
;
9669 IDirect3DMaterial2
*red
, *green
;
9670 IDirect3DViewport2
*viewport
, *viewport2
;
9673 window
= create_window();
9674 ddraw
= create_ddraw();
9675 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9676 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9678 skip("Failed to create a 3D device, skipping test.\n");
9679 DestroyWindow(window
);
9680 IDirectDraw2_Release(ddraw
);
9684 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9685 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9687 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
9688 viewport
= create_viewport(device
, 0, 0, 640, 480);
9689 viewport_set_background(device
, viewport
, red
);
9690 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9691 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9693 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
9694 viewport2
= create_viewport(device
, 100, 100, 20, 20);
9695 viewport_set_background(device
, viewport2
, green
);
9696 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
9697 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9699 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
9700 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9701 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
9702 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
9703 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
9704 "Got unexpected color 0x%08x.\n", color
);
9705 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
9706 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9707 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
9708 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9709 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
9710 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9712 destroy_viewport(device
, viewport2
);
9713 destroy_material(green
);
9714 destroy_viewport(device
, viewport
);
9715 destroy_material(red
);
9716 IDirectDrawSurface_Release(rt
);
9717 IDirect3DDevice2_Release(device
);
9718 ref
= IDirectDraw2_Release(ddraw
);
9719 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9720 DestroyWindow(window
);
9723 static void test_color_fill(void)
9726 IDirect3DDevice2
*device
;
9727 IDirectDraw2
*ddraw
;
9728 IDirectDrawSurface
*surface
, *surface2
;
9729 DDSURFACEDESC surface_desc
;
9730 unsigned int i
, *color
;
9735 RECT rect
= {5, 5, 7, 7};
9736 DWORD num_fourcc_codes
, *fourcc_codes
;
9738 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
9742 HRESULT colorfill_hr
, depthfill_hr
;
9745 unsigned int result
;
9747 DDPIXELFORMAT format
;
9752 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9753 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9755 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9756 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9760 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9761 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9763 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9764 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9768 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9769 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9771 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9772 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9776 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9777 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9779 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9780 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9784 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
9785 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9786 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9789 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9790 * different afterwards. DX9+ GPUs set one of the two luminance values
9791 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9792 * value they set. r200 (dx8) just sets the entire block to the clear
9794 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9795 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9797 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9798 {0}, {0}, {0}, {0}, {0}
9802 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9803 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9805 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9806 {0}, {0}, {0}, {0}, {0}
9810 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9811 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9813 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9814 {0}, {0}, {0}, {0}, {0}
9818 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9819 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9821 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9822 {0}, {0}, {0}, {0}, {0}
9826 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9827 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
9829 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9830 {0}, {0}, {0}, {0}, {0}
9834 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9835 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
9837 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9838 {0}, {0}, {0}, {0}, {0}
9842 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
9843 * surface works, presumably because it is handled by the runtime instead of
9845 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9846 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
9848 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9849 {8}, {0}, {0}, {0}, {0}
9853 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9854 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
9856 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9857 {8}, {0}, {0}, {0}, {0}
9869 {SRCCOPY
, "SRCCOPY", DD_OK
},
9870 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9871 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9872 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9873 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9874 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9875 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9876 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9877 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9878 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9879 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9880 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9881 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9882 {BLACKNESS
, "BLACKNESS", DD_OK
},
9883 {WHITENESS
, "WHITENESS", DD_OK
},
9884 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9887 window
= create_window();
9888 ddraw
= create_ddraw();
9889 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9890 is_warp
= ddraw_is_warp(ddraw
);
9891 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9893 skip("Failed to create a 3D device, skipping test.\n");
9894 DestroyWindow(window
);
9895 IDirectDraw2_Release(ddraw
);
9899 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9900 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9901 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
9902 num_fourcc_codes
* sizeof(*fourcc_codes
));
9905 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9906 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9907 for (i
= 0; i
< num_fourcc_codes
; i
++)
9909 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9910 support_yuy2
= TRUE
;
9911 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9912 support_uyvy
= TRUE
;
9914 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
9916 memset(&hal_caps
, 0, sizeof(hal_caps
));
9917 hal_caps
.dwSize
= sizeof(hal_caps
);
9918 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
9919 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9921 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9922 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9924 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9926 DWORD expected_broken
= tests
[i
].result
;
9927 unsigned int mask
= 0xffffffffu
;
9929 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9930 memset(&fx
, 0, sizeof(fx
));
9931 fx
.dwSize
= sizeof(fx
);
9932 U5(fx
).dwFillColor
= 0xdeadbeef;
9934 memset(&surface_desc
, 0, sizeof(surface_desc
));
9935 surface_desc
.dwSize
= sizeof(surface_desc
);
9936 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9937 surface_desc
.dwWidth
= 64;
9938 surface_desc
.dwHeight
= 64;
9939 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
9940 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9942 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
9944 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
9945 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
9946 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9947 if (!check
.supported
)
9951 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
9953 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
9955 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9958 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9960 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
9961 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
9962 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9963 mask
>>= (32 - U2(surface_desc
).dwZBufferBitDepth
);
9964 /* Some drivers seem to convert depth values incorrectly or not at
9965 * all. Affects at least AMD PALM, 8.17.10.1247. */
9966 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9971 expected
= tests
[i
].result
& mask
;
9972 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
9973 g
= (f
+ 1.0f
) / 2.0f
;
9975 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9976 expected_broken
*= 0x01010101;
9980 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9981 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9983 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9984 todo_wine_if (tests
[i
].format
.dwFourCC
)
9985 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9986 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9988 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9989 todo_wine_if (tests
[i
].format
.dwFourCC
)
9990 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9991 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9993 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9995 memset(&surface_desc
, 0, sizeof(surface_desc
));
9996 surface_desc
.dwSize
= sizeof(surface_desc
);
9997 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9998 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9999 color
= surface_desc
.lpSurface
;
10000 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10001 *color
, tests
[i
].result
, tests
[i
].name
);
10002 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10003 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10006 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10007 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10008 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10009 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10010 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10011 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10013 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10015 memset(&surface_desc
, 0, sizeof(surface_desc
));
10016 surface_desc
.dwSize
= sizeof(surface_desc
);
10017 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10018 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10019 color
= surface_desc
.lpSurface
;
10020 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& U2(surface_desc
).dwZBufferBitDepth
!= 16)
10021 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
10022 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
10023 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10024 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
10025 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10026 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10029 U5(fx
).dwFillColor
= 0xdeadbeef;
10030 fx
.dwROP
= BLACKNESS
;
10031 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10032 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
10033 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10034 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
10035 U5(fx
).dwFillColor
, tests
[i
].name
);
10037 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10039 memset(&surface_desc
, 0, sizeof(surface_desc
));
10040 surface_desc
.dwSize
= sizeof(surface_desc
);
10041 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10042 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10043 color
= surface_desc
.lpSurface
;
10044 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
10045 *color
, tests
[i
].name
);
10046 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10047 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10050 fx
.dwROP
= WHITENESS
;
10051 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10052 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
10053 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10054 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
10055 U5(fx
).dwFillColor
, tests
[i
].name
);
10057 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10059 memset(&surface_desc
, 0, sizeof(surface_desc
));
10060 surface_desc
.dwSize
= sizeof(surface_desc
);
10061 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10062 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10063 color
= surface_desc
.lpSurface
;
10064 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
10065 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
10066 *color
, tests
[i
].name
);
10067 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10068 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10071 IDirectDrawSurface_Release(surface
);
10074 memset(&fx
, 0, sizeof(fx
));
10075 fx
.dwSize
= sizeof(fx
);
10076 U5(fx
).dwFillColor
= 0xdeadbeef;
10077 fx
.dwROP
= WHITENESS
;
10079 memset(&surface_desc
, 0, sizeof(surface_desc
));
10080 surface_desc
.dwSize
= sizeof(surface_desc
);
10081 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10082 surface_desc
.dwWidth
= 64;
10083 surface_desc
.dwHeight
= 64;
10084 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10085 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10086 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10087 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10088 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10089 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10090 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10091 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10092 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10093 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10094 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10097 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
10098 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10099 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
10100 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10102 /* Unused source rectangle. */
10103 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10104 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10105 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10106 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10108 /* Unused source surface. */
10109 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10110 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10111 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10112 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10113 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10114 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10115 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10116 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10118 /* Inverted destination or source rectangle. */
10119 SetRect(&rect
, 5, 7, 7, 5);
10120 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10121 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10122 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10123 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10124 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10125 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10126 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10127 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10128 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10129 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10131 /* Negative rectangle. */
10132 SetRect(&rect
, -1, -1, 5, 5);
10133 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10134 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10135 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10136 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10137 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10138 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10139 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10140 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10141 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10142 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10144 /* Out of bounds rectangle. */
10145 SetRect(&rect
, 0, 0, 65, 65);
10146 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10147 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10148 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10149 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10151 /* Combine multiple flags. */
10152 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10153 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10154 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10155 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10156 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10157 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10159 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
10161 fx
.dwROP
= rops
[i
].rop
;
10162 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10163 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#lx for rop %s.\n", hr
, rops
[i
].name
);
10166 IDirectDrawSurface_Release(surface2
);
10167 IDirectDrawSurface_Release(surface
);
10169 memset(&surface_desc
, 0, sizeof(surface_desc
));
10170 surface_desc
.dwSize
= sizeof(surface_desc
);
10171 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
10172 surface_desc
.dwWidth
= 64;
10173 surface_desc
.dwHeight
= 64;
10174 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
10175 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10176 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10177 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10178 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10179 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10182 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
10183 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10185 /* Unused source rectangle. */
10186 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10187 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10189 /* Unused source surface. */
10190 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10191 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10192 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10193 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10195 /* Inverted destination or source rectangle. */
10196 SetRect(&rect
, 5, 7, 7, 5);
10197 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10198 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10199 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10200 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10201 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10202 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10203 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10204 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10206 /* Negative rectangle. */
10207 SetRect(&rect
, -1, -1, 5, 5);
10208 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10209 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10210 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10211 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10212 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10213 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10214 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10215 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10217 /* Out of bounds rectangle. */
10218 SetRect(&rect
, 0, 0, 65, 65);
10219 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10220 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10222 /* Combine multiple flags. */
10223 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10224 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10226 IDirectDrawSurface_Release(surface2
);
10227 IDirectDrawSurface_Release(surface
);
10230 IDirect3DDevice2_Release(device
);
10231 refcount
= IDirectDraw2_Release(ddraw
);
10232 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
10233 DestroyWindow(window
);
10236 static void test_colorkey_precision(void)
10238 static D3DLVERTEX quad
[] =
10240 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {0.0f
}},
10241 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {1.0f
}},
10242 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {0.0f
}},
10243 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {1.0f
}},
10245 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10246 unsigned int data
[4] = {0}, color_mask
, color
, t
, c
;
10247 IDirect3DDevice2
*device
;
10248 IDirectDraw2
*ddraw
;
10249 IDirectDrawSurface
*rt
;
10250 IDirect3DViewport2
*viewport
;
10253 IDirectDrawSurface
*src
, *dst
, *texture
;
10254 D3DTEXTUREHANDLE handle
;
10255 IDirect3DTexture2
*d3d_texture
;
10256 IDirect3DMaterial2
*green
;
10257 DDSURFACEDESC surface_desc
, lock_desc
;
10261 BOOL is_nvidia
, is_warp
;
10262 static const struct
10264 unsigned int max
, shift
, bpp
, clear
;
10272 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10274 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10275 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10280 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10282 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10283 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10288 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10290 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10291 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10296 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10298 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10299 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10304 window
= create_window();
10305 ddraw
= create_ddraw();
10306 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10307 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10309 skip("Failed to create a 3D device, skipping test.\n");
10310 DestroyWindow(window
);
10311 IDirectDraw2_Release(ddraw
);
10314 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10315 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10317 is_nvidia
= ddraw_is_nvidia(ddraw
);
10318 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10319 * (color key doesn't match although the values are equal), and a false
10320 * positive when the color key is 0 and the texture contains the value 1.
10321 * I don't want to mark this broken unconditionally since this would
10322 * essentially disable the test on Windows. Also on random occasions
10323 * 254 == 255 and 255 != 255.*/
10324 is_warp
= ddraw_is_warp(ddraw
);
10326 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
10327 viewport
= create_viewport(device
, 0, 0, 640, 480);
10328 viewport_set_background(device
, viewport
, green
);
10329 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10330 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
10332 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10333 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
10334 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
10335 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
10336 /* There's no way to ignore the texture color in d3d2, so multiply the texture color
10337 * with a black vertex color. */
10338 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
10339 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
10341 memset(&fx
, 0, sizeof(fx
));
10342 fx
.dwSize
= sizeof(fx
);
10343 memset(&lock_desc
, 0, sizeof(lock_desc
));
10344 lock_desc
.dwSize
= sizeof(lock_desc
);
10346 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
10348 if (is_nvidia
&& tests
[t
].skip_nv
)
10350 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
10354 memset(&surface_desc
, 0, sizeof(surface_desc
));
10355 surface_desc
.dwSize
= sizeof(surface_desc
);
10356 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10357 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10358 surface_desc
.dwWidth
= 4;
10359 surface_desc
.dwHeight
= 1;
10360 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
10361 /* Windows XP (at least with the r200 driver, other drivers untested) produces
10362 * garbage when doing color keyed texture->texture blits. */
10363 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
10364 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10365 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
10366 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10368 U5(fx
).dwFillColor
= tests
[t
].clear
;
10369 /* On the w8 testbot (WARP driver) the blit result has different values in the
10371 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
10372 | U3(tests
[t
].fmt
).dwGBitMask
10373 | U4(tests
[t
].fmt
).dwBBitMask
;
10375 for (c
= 0; c
<= tests
[t
].max
; ++c
)
10377 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
10378 * texture after it has been set once... */
10379 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
10380 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10381 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10382 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10383 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
10384 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10386 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
10387 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
10388 hr
= IDirect3DTexture2_GetHandle(d3d_texture
, device
, &handle
);
10389 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
10390 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
10391 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
10392 IDirect3DTexture2_Release(d3d_texture
);
10394 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10395 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
10397 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10398 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10399 switch (tests
[t
].bpp
)
10402 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10403 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10404 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10405 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
10409 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10410 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10411 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10412 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
10415 hr
= IDirectDrawSurface_Unlock(src
, 0);
10416 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10417 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
10418 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10420 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10421 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10422 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
10423 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10425 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
10426 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10428 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
10429 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10430 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10431 switch (tests
[t
].bpp
)
10434 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10435 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10436 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10437 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10441 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10442 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10443 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10444 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10447 hr
= IDirectDrawSurface_Unlock(dst
, 0);
10448 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10452 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10453 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
10455 if (data
[3] == tests
[t
].clear
)
10457 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
10458 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
10459 * even when a different surface is used. The blit itself doesn't draw anything,
10460 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
10461 * never be masked out by the key.
10463 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
10464 * test is disabled entirely.
10466 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
10467 * terrible on WARP. */
10468 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
10469 IDirectDrawSurface_Release(texture
);
10470 IDirectDrawSurface_Release(src
);
10471 IDirectDrawSurface_Release(dst
);
10476 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10477 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
10479 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10480 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
10482 if (c
== tests
[t
].max
)
10483 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10484 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
10486 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10487 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
10489 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10490 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
10492 hr
= IDirect3DDevice2_BeginScene(device
);
10493 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
10494 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
10495 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
10496 hr
= IDirect3DDevice2_EndScene(device
);
10497 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10499 color
= get_surface_color(rt
, 80, 240);
10501 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10502 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10503 color
, tests
[t
].name
, c
);
10505 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10506 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10507 color
, tests
[t
].name
, c
);
10509 color
= get_surface_color(rt
, 240, 240);
10510 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10511 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10512 color
, tests
[t
].name
, c
);
10514 color
= get_surface_color(rt
, 400, 240);
10515 if (c
== tests
[t
].max
)
10516 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10517 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10518 color
, tests
[t
].name
, c
);
10520 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10521 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10522 color
, tests
[t
].name
, c
);
10524 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
10525 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
10526 IDirectDrawSurface_Release(texture
);
10528 IDirectDrawSurface_Release(src
);
10529 IDirectDrawSurface_Release(dst
);
10533 destroy_viewport(device
, viewport
);
10534 destroy_material(green
);
10535 IDirectDrawSurface_Release(rt
);
10536 IDirect3DDevice2_Release(device
);
10537 refcount
= IDirectDraw2_Release(ddraw
);
10538 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
10539 DestroyWindow(window
);
10542 static void test_range_colorkey(void)
10544 IDirectDraw2
*ddraw
;
10547 IDirectDrawSurface
*surface
;
10548 DDSURFACEDESC surface_desc
;
10552 window
= create_window();
10553 ddraw
= create_ddraw();
10554 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10555 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10556 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10558 memset(&surface_desc
, 0, sizeof(surface_desc
));
10559 surface_desc
.dwSize
= sizeof(surface_desc
);
10560 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
10561 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10562 surface_desc
.dwWidth
= 1;
10563 surface_desc
.dwHeight
= 1;
10564 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10565 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10566 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10567 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10568 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10569 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
10571 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
10572 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10573 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10574 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10575 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10577 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10578 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10579 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10580 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10582 /* Same for DDSCAPS_OFFSCREENPLAIN. */
10583 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10584 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10585 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10586 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10587 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10589 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10590 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10591 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10592 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10594 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10595 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10596 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10597 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10599 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
10600 ckey
.dwColorSpaceLowValue
= 0x00000000;
10601 ckey
.dwColorSpaceHighValue
= 0x00000001;
10602 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10603 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10605 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10606 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10607 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10608 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10610 ckey
.dwColorSpaceLowValue
= 0x00000001;
10611 ckey
.dwColorSpaceHighValue
= 0x00000000;
10612 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10613 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10615 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10616 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10617 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10618 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10620 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
10621 ckey
.dwColorSpaceLowValue
= 0x00000000;
10622 ckey
.dwColorSpaceHighValue
= 0x00000000;
10623 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10624 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10626 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
10627 ckey
.dwColorSpaceLowValue
= 0x00000001;
10628 ckey
.dwColorSpaceHighValue
= 0x00000000;
10629 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10630 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10631 ckey
.dwColorSpaceLowValue
= 0x00000000;
10632 ckey
.dwColorSpaceHighValue
= 0x00000001;
10633 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10634 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10635 /* Range destination keys don't work either. */
10636 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
10637 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10639 /* Just to show it's not because of A, R, and G having equal values. */
10640 ckey
.dwColorSpaceLowValue
= 0x00000000;
10641 ckey
.dwColorSpaceHighValue
= 0x01010101;
10642 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10643 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10645 /* None of these operations modified the key. */
10646 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10647 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10648 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10649 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10651 IDirectDrawSurface_Release(surface
);
10652 refcount
= IDirectDraw2_Release(ddraw
);
10653 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10654 DestroyWindow(window
);
10657 static void test_shademode(void)
10659 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10660 unsigned int color0
, color1
, i
, count
;
10661 IDirect3DMaterial2
*background
;
10662 IDirect3DViewport2
*viewport
;
10663 IDirect3DDevice2
*device
;
10664 IDirectDrawSurface
*rt
;
10665 IDirectDraw2
*ddraw
;
10670 static D3DLVERTEX quad_strip
[] =
10672 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10673 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10674 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10675 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10679 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10680 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10681 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10683 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10684 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10685 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10687 static const struct
10691 unsigned int color0
, color1
;
10695 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
10696 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10697 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10698 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10699 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
10700 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10703 window
= create_window();
10704 ddraw
= create_ddraw();
10705 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10706 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10708 skip("Failed to create a 3D device, skipping test.\n");
10709 IDirectDraw2_Release(ddraw
);
10710 DestroyWindow(window
);
10714 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10715 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10717 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
10718 viewport
= create_viewport(device
, 0, 0, 640, 480);
10719 viewport_set_background(device
, viewport
, background
);
10720 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10721 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
10723 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10724 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
10726 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10727 * the color fixups we have to do for FLAT shading will be dependent on that. */
10729 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10731 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10732 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
10734 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10735 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#lx.\n", hr
);
10737 hr
= IDirect3DDevice2_BeginScene(device
);
10738 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
10739 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
10740 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
10741 hr
= IDirect3DDevice2_DrawPrimitive(device
, tests
[i
].primtype
, D3DVT_LVERTEX
, quad
, count
, 0);
10742 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
10743 hr
= IDirect3DDevice2_EndScene(device
);
10744 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10746 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10747 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10749 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10750 * each triangle. This requires EXT_provoking_vertex or similar
10751 * functionality being available. */
10752 /* PHONG should be the same as GOURAUD, since no hardware implements
10754 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10755 i
, color0
, tests
[i
].color0
);
10756 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10757 i
, color1
, tests
[i
].color1
);
10760 destroy_viewport(device
, viewport
);
10761 destroy_material(background
);
10762 IDirectDrawSurface_Release(rt
);
10763 refcount
= IDirect3DDevice2_Release(device
);
10764 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10765 IDirectDraw2_Release(ddraw
);
10766 DestroyWindow(window
);
10769 static void test_lockrect_invalid(void)
10772 IDirectDraw2
*ddraw
;
10773 IDirectDrawSurface
*surface1
;
10774 IDirectDrawSurface2
*surface
;
10777 DDSURFACEDESC surface_desc
;
10779 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10780 static RECT valid
[] =
10785 {120, 60, 128, 68},
10786 {60, 120, 68, 128},
10788 static RECT invalid
[] =
10790 {68, 60, 60, 68}, /* left > right */
10791 {60, 68, 68, 60}, /* top > bottom */
10792 {-8, 60, 0, 68}, /* left < surface */
10793 {60, -8, 68, 0}, /* top < surface */
10794 {-16, 60, -8, 68}, /* right < surface */
10795 {60, -16, 68, -8}, /* bottom < surface */
10796 {60, 60, 136, 68}, /* right > surface */
10797 {60, 60, 68, 136}, /* bottom > surface */
10798 {136, 60, 144, 68}, /* left > surface */
10799 {60, 136, 68, 144}, /* top > surface */
10801 static const struct
10809 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10810 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10811 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
10812 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
10815 window
= create_window();
10816 ddraw
= create_ddraw();
10817 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10818 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10819 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10821 memset(&hal_caps
, 0, sizeof(hal_caps
));
10822 hal_caps
.dwSize
= sizeof(hal_caps
);
10823 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
10824 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
10825 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
10827 skip("Required surface types not supported, skipping test.\n");
10831 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
10833 memset(&surface_desc
, 0, sizeof(surface_desc
));
10834 surface_desc
.dwSize
= sizeof(surface_desc
);
10835 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10836 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
10837 surface_desc
.dwWidth
= 128;
10838 surface_desc
.dwHeight
= 128;
10839 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10840 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10841 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10842 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
10843 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
10844 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
10846 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
10847 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10848 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
10849 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
10850 IDirectDrawSurface_Release(surface1
);
10852 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
10853 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10855 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
10857 RECT
*rect
= &valid
[i
];
10859 memset(&surface_desc
, 0, sizeof(surface_desc
));
10860 surface_desc
.dwSize
= sizeof(surface_desc
);
10862 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10863 ok(SUCCEEDED(hr
), "Lock failed (%#lx) for rect %s, type %s.\n",
10864 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10866 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10867 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10870 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
10872 RECT
*rect
= &invalid
[i
];
10874 memset(&surface_desc
, 1, sizeof(surface_desc
));
10875 surface_desc
.dwSize
= sizeof(surface_desc
);
10877 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10878 ok(hr
== resources
[r
].hr
, "Lock returned %#lx for rect %s, type %s.\n",
10879 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10882 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10883 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10886 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10889 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10890 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#lx, type %s.\n",
10891 hr
, resources
[r
].name
);
10892 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10893 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#lx, type %s.\n",
10894 hr
, resources
[r
].name
);
10895 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10896 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10898 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10899 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#lx).\n", wine_dbgstr_rect(&valid
[0]), hr
);
10900 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10901 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#lx).\n",
10902 wine_dbgstr_rect(&valid
[0]), hr
);
10904 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
10905 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
10907 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
10908 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10910 IDirectDrawSurface2_Release(surface
);
10914 IDirectDraw2_Release(ddraw
);
10915 DestroyWindow(window
);
10918 static void test_yv12_overlay(void)
10920 IDirectDrawSurface
*src_surface
, *dst_surface
;
10921 RECT rect
= {13, 17, 14, 18};
10922 unsigned int offset
, y
;
10923 unsigned char *base
;
10924 IDirectDraw2
*ddraw
;
10925 DDSURFACEDESC desc
;
10929 window
= create_window();
10930 ddraw
= create_ddraw();
10931 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10932 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10933 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10935 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10937 skip("Failed to create a YV12 overlay, skipping test.\n");
10941 memset(&desc
, 0, sizeof(desc
));
10942 desc
.dwSize
= sizeof(desc
);
10943 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10944 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10946 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
10947 "Got unexpected flags %#lx.\n", desc
.dwFlags
);
10948 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
10949 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
10950 "Got unexpected caps %#lx.\n", desc
.ddsCaps
.dwCaps
);
10951 ok(desc
.dwWidth
== 256, "Got unexpected width %lu.\n", desc
.dwWidth
);
10952 ok(desc
.dwHeight
== 256, "Got unexpected height %lu.\n", desc
.dwHeight
);
10953 /* The overlay pitch seems to have 256 byte alignment. */
10954 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %lu.\n", U1(desc
).lPitch
);
10956 /* Fill the surface with some data for the blit test. */
10957 base
= desc
.lpSurface
;
10959 for (y
= 0; y
< desc
.dwHeight
; ++y
)
10961 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
10964 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
10966 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
10969 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
10971 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
10974 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10975 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10977 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
10978 * other block-based formats like DXT the entire Y channel is stored in
10979 * one big chunk of memory, followed by the chroma channels. So partial
10980 * locks do not really make sense. Show that they are allowed nevertheless
10981 * and the offset points into the luminance data. */
10982 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
10983 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10984 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
10985 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %lu.\n",
10986 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
10987 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10988 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10990 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10992 /* Windows XP with a Radeon X1600 GPU refuses to create a second
10993 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
10994 skip("Failed to create a second YV12 surface, skipping blit test.\n");
10995 IDirectDrawSurface_Release(src_surface
);
10999 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
11000 /* VMware rejects YV12 blits. This behavior has not been seen on real
11001 * hardware yet, so mark it broken. */
11002 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#lx.\n", hr
);
11006 memset(&desc
, 0, sizeof(desc
));
11007 desc
.dwSize
= sizeof(desc
);
11008 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11009 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
11011 base
= desc
.lpSurface
;
11012 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
11013 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
11014 ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
11015 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
11016 ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
11018 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
11019 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
11022 IDirectDrawSurface_Release(dst_surface
);
11023 IDirectDrawSurface_Release(src_surface
);
11025 IDirectDraw2_Release(ddraw
);
11026 DestroyWindow(window
);
11029 static BOOL
dwm_enabled(void)
11033 if (!strcmp(winetest_platform
, "wine"))
11035 if (!pDwmIsCompositionEnabled
)
11037 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
11042 static void test_offscreen_overlay(void)
11044 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
11045 DDSURFACEDESC surface_desc
;
11046 IDirectDraw2
*ddraw
;
11051 window
= create_window();
11052 ddraw
= create_ddraw();
11053 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11054 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11055 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11057 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11059 skip("Failed to create a UYVY overlay, skipping test.\n");
11063 memset(&surface_desc
, 0, sizeof(surface_desc
));
11064 surface_desc
.dwSize
= sizeof(surface_desc
);
11065 surface_desc
.dwFlags
= DDSD_CAPS
;
11066 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11067 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11068 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11070 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11071 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11072 * surface prevents this by disabling the dwm. */
11073 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
11074 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
11075 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
11076 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
11078 /* Try to overlay a NULL surface. */
11079 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
11080 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11081 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
11082 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11084 /* Try to overlay an offscreen surface. */
11085 memset(&surface_desc
, 0, sizeof(surface_desc
));
11086 surface_desc
.dwSize
= sizeof(surface_desc
);
11087 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11088 surface_desc
.dwWidth
= 64;
11089 surface_desc
.dwHeight
= 64;
11090 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11091 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11092 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11093 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
11094 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
11095 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
11096 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
11097 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
11098 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11099 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11101 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
11102 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
11103 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
11104 "Failed to update overlay, hr %#lx.\n", hr
);
11106 /* Try to overlay the primary with a non-overlay surface. */
11107 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11108 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
11109 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11110 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
11112 IDirectDrawSurface_Release(offscreen
);
11113 IDirectDrawSurface_Release(primary
);
11114 IDirectDrawSurface_Release(overlay
);
11116 IDirectDraw2_Release(ddraw
);
11117 DestroyWindow(window
);
11120 static void test_overlay_rect(void)
11122 IDirectDrawSurface
*overlay
, *primary
= NULL
;
11123 DDSURFACEDESC surface_desc
;
11124 RECT rect
= {0, 0, 64, 64};
11125 IDirectDraw2
*ddraw
;
11131 window
= create_window();
11132 ddraw
= create_ddraw();
11133 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11134 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11135 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11137 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11139 skip("Failed to create a UYVY overlay, skipping test.\n");
11143 memset(&surface_desc
, 0, sizeof(surface_desc
));
11144 surface_desc
.dwSize
= sizeof(surface_desc
);
11145 surface_desc
.dwFlags
= DDSD_CAPS
;
11146 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11147 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11148 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11150 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11151 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11152 * surface prevents this by disabling the dwm. */
11153 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
11154 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
11155 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
11156 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
11158 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
11161 win_skip("Cannot disable DWM, skipping overlay test.\n");
11165 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
11166 * used. This is not true in Windows Vista and earlier, but changed in
11168 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11169 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11170 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11171 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11172 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11173 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11175 /* Show that the overlay position is the (top, left) coordinate of the
11176 * destination rectangle. */
11177 OffsetRect(&rect
, 32, 16);
11178 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11179 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11180 pos_x
= -1; pos_y
= -1;
11181 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11182 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
11183 ok(pos_x
== rect
.left
, "Got unexpected pos_x %ld, expected %ld.\n", pos_x
, rect
.left
);
11184 ok(pos_y
== rect
.top
, "Got unexpected pos_y %ld, expected %ld.\n", pos_y
, rect
.top
);
11186 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
11187 * seen that the overlay overlays the whole primary(==screen). */
11188 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
11189 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#lx.\n", hr2
);
11190 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11191 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
11192 if (SUCCEEDED(hr2
))
11194 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
11195 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
11199 ok(pos_x
== 32, "Got unexpected pos_x %ld.\n", pos_x
);
11200 ok(pos_y
== 16, "Got unexpected pos_y %ld.\n", pos_y
);
11203 /* The position cannot be retrieved when the overlay is not shown. */
11204 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
11205 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11206 pos_x
= -1; pos_y
= -1;
11207 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11208 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#lx.\n", hr
);
11209 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
11210 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
11214 IDirectDrawSurface_Release(primary
);
11216 IDirectDrawSurface_Release(overlay
);
11217 IDirectDraw2_Release(ddraw
);
11218 DestroyWindow(window
);
11221 static void test_blt(void)
11223 IDirectDrawSurface
*surface
, *rt
;
11224 DDSURFACEDESC surface_desc
;
11225 IDirect3DDevice2
*device
;
11226 IDirectDraw2
*ddraw
;
11240 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
11241 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
11242 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11243 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11244 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11245 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11246 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11247 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11248 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11249 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11252 window
= create_window();
11253 ddraw
= create_ddraw();
11254 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11255 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11257 skip("Failed to create a 3D device, skipping test.\n");
11258 IDirectDraw2_Release(ddraw
);
11259 DestroyWindow(window
);
11263 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
11264 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11266 memset(&surface_desc
, 0, sizeof(surface_desc
));
11267 surface_desc
.dwSize
= sizeof(surface_desc
);
11268 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11269 surface_desc
.dwWidth
= 640;
11270 surface_desc
.dwHeight
= 480;
11271 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11272 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11273 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11275 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11276 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
11278 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11279 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
11281 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11283 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11284 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11285 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
11287 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11288 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11289 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
11291 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11292 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11293 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11295 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
11296 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11299 IDirectDrawSurface_Release(surface
);
11300 IDirectDrawSurface_Release(rt
);
11301 refcount
= IDirect3DDevice2_Release(device
);
11302 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11303 IDirectDraw2_Release(ddraw
);
11304 DestroyWindow(window
);
11307 static void test_blt_z_alpha(void)
11309 DWORD blt_flags
[] =
11313 DDBLT_ALPHADESTCONSTOVERRIDE
,
11314 DDBLT_ALPHADESTNEG
,
11315 DDBLT_ALPHADESTSURFACEOVERRIDE
,
11316 DDBLT_ALPHAEDGEBLEND
,
11319 DDBLT_ALPHASRCCONSTOVERRIDE
,
11321 DDBLT_ALPHASRCSURFACEOVERRIDE
,
11324 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
11325 DDBLT_ZBUFFERDESTOVERRIDE
,
11326 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
11327 DDBLT_ZBUFFERSRCOVERRIDE
,
11329 IDirectDrawSurface
*src_surface
, *dst_surface
;
11330 DDSURFACEDESC surface_desc
;
11331 unsigned int color
, i
;
11332 IDirectDraw2
*ddraw
;
11339 window
= create_window();
11340 ddraw
= create_ddraw();
11341 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11342 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11343 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11345 memset(&pf
, 0, sizeof(pf
));
11346 pf
.dwSize
= sizeof(pf
);
11347 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11348 U1(pf
).dwRGBBitCount
= 32;
11349 U2(pf
).dwRBitMask
= 0x00ff0000;
11350 U3(pf
).dwGBitMask
= 0x0000ff00;
11351 U4(pf
).dwBBitMask
= 0x000000ff;
11352 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
11354 memset(&surface_desc
, 0, sizeof(surface_desc
));
11355 surface_desc
.dwSize
= sizeof(surface_desc
);
11356 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11357 surface_desc
.dwWidth
= 64;
11358 surface_desc
.dwHeight
= 64;
11359 surface_desc
.ddpfPixelFormat
= pf
;
11360 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11362 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11363 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
11364 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11365 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
11367 memset(&fx
, 0, sizeof(fx
));
11368 fx
.dwSize
= sizeof(fx
);
11369 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
11370 fx
.dwZDestConstBitDepth
= 32;
11371 U1(fx
).dwZDestConst
= 0x11111111;
11372 fx
.dwZSrcConstBitDepth
= 32;
11373 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
11374 fx
.dwAlphaEdgeBlendBitDepth
= 8;
11375 fx
.dwAlphaEdgeBlend
= 0x7f;
11376 fx
.dwAlphaDestConstBitDepth
= 8;
11377 U3(fx
).dwAlphaDestConst
= 0xdd;
11378 fx
.dwAlphaSrcConstBitDepth
= 8;
11379 U4(fx
).dwAlphaSrcConst
= 0x22;
11381 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
11383 U5(fx
).dwFillColor
= 0x3300ff00;
11384 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11385 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11387 U5(fx
).dwFillColor
= 0xccff0000;
11388 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11389 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11391 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
11392 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11394 color
= get_surface_color(dst_surface
, 32, 32);
11395 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
11398 IDirectDrawSurface_Release(dst_surface
);
11399 IDirectDrawSurface_Release(src_surface
);
11400 refcount
= IDirectDraw2_Release(ddraw
);
11401 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
11402 DestroyWindow(window
);
11405 static void test_cross_device_blt(void)
11407 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
11408 IDirect3DDevice2
*device
, *device2
;
11409 IDirectDraw2
*ddraw
, *ddraw2
;
11410 DDSURFACEDESC surface_desc
;
11411 HWND window
, window2
;
11412 unsigned int color
;
11417 window
= create_window();
11418 ddraw
= create_ddraw();
11419 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
11421 skip("Failed to create a 3D device.\n");
11422 IDirectDraw2_Release(ddraw
);
11423 DestroyWindow(window
);
11427 window2
= create_window();
11428 ddraw2
= create_ddraw();
11429 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
11431 skip("Failed to create a 3D device.\n");
11432 IDirectDraw2_Release(ddraw2
);
11433 IDirect3DDevice2_Release(device
);
11434 IDirectDraw2_Release(ddraw
);
11435 DestroyWindow(window
);
11436 DestroyWindow(window2
);
11440 memset(&surface_desc
, 0, sizeof(surface_desc
));
11441 surface_desc
.dwSize
= sizeof(surface_desc
);
11442 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11443 surface_desc
.dwWidth
= 640;
11444 surface_desc
.dwHeight
= 480;
11445 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11446 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
11447 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11449 memset(&surface_desc
, 0, sizeof(surface_desc
));
11450 surface_desc
.dwSize
= sizeof(surface_desc
);
11451 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11452 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
11453 surface_desc
.dwBackBufferCount
= 2;
11454 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11455 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11457 memset(&surface_desc
, 0, sizeof(surface_desc
));
11458 surface_desc
.dwSize
= sizeof(surface_desc
);
11459 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11460 surface_desc
.dwWidth
= 640;
11461 surface_desc
.dwHeight
= 480;
11462 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11463 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11464 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11465 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
11466 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
11467 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
11468 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
11469 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11470 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11472 memset(&fx
, 0, sizeof(fx
));
11473 fx
.dwSize
= sizeof(fx
);
11474 U5(fx
).dwFillColor
= 0xff0000ff;
11475 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11476 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
11478 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11479 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11480 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
11481 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
11482 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11483 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11484 color
= get_surface_color(surface
, 320, 240);
11485 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11487 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11488 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11489 color
= get_surface_color(sysmem_surface
, 320, 240);
11490 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11492 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11493 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11494 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
11495 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11497 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11498 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11499 color
= get_surface_color(sysmem_surface
, 320, 240);
11500 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11502 IDirectDrawSurface_Release(surface2
);
11503 memset(&surface_desc
, 0, sizeof(surface_desc
));
11504 surface_desc
.dwSize
= sizeof(surface_desc
);
11505 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11506 surface_desc
.dwWidth
= 640;
11507 surface_desc
.dwHeight
= 480;
11508 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11509 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11510 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11511 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11512 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
11514 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11515 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#lx.\n", hr
);
11516 color
= get_surface_color(sysmem_surface
, 320, 240);
11517 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11519 IDirectDrawSurface_Release(surface
);
11520 IDirectDrawSurface_Release(surface2
);
11521 IDirectDrawSurface_Release(sysmem_surface
);
11522 refcount
= IDirect3DDevice2_Release(device
);
11523 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11524 refcount
= IDirect3DDevice2_Release(device2
);
11525 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11526 IDirectDraw2_Release(ddraw
);
11527 IDirectDraw2_Release(ddraw2
);
11528 DestroyWindow(window
);
11529 DestroyWindow(window2
);
11532 static void test_getdc(void)
11534 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
11535 DDSURFACEDESC surface_desc
, map_desc
;
11536 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
11537 IDirectDraw2
*ddraw
;
11538 unsigned int i
, screen_bpp
;
11543 static const struct
11546 DDPIXELFORMAT format
;
11547 BOOL getdc_supported
;
11548 HRESULT alt_result
;
11552 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11553 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
11554 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11555 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
11556 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11557 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11558 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11559 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11560 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11561 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
11562 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11563 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11564 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11565 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11566 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11567 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
11568 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11569 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11570 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11571 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11572 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
11573 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
11574 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
11575 * This is not implemented in wine yet, so disable the test for now.
11576 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
11577 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
11578 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
11580 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
11581 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11582 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
11583 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
11584 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
11585 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11586 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
11587 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11588 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
11589 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11590 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
11591 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11592 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
11593 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11596 window
= create_window();
11597 ddraw
= create_ddraw();
11598 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11599 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11600 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11602 surface_desc
.dwSize
= sizeof(surface_desc
);
11603 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
11604 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11605 screen_bpp
= U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
;
11607 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11609 memset(&surface_desc
, 0, sizeof(surface_desc
));
11610 surface_desc
.dwSize
= sizeof(surface_desc
);
11611 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11612 surface_desc
.dwWidth
= 64;
11613 surface_desc
.dwHeight
= 64;
11614 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
11615 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11617 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11619 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11620 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11622 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", test_data
[i
].name
, hr
);
11627 dc
= (void *)0x1234;
11628 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11629 if (test_data
[i
].getdc_supported
)
11630 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
11631 "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11633 ok(FAILED(hr
), "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11637 unsigned int width_bytes
;
11643 type
= GetObjectType(dc
);
11644 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
11645 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
11646 type
= GetObjectType(bitmap
);
11647 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
11649 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
11650 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
11651 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
11652 dib
.dsBm
.bmType
, test_data
[i
].name
);
11653 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11654 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
11655 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11656 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
11657 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
11658 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
11659 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
11660 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
11661 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
11662 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
11663 "Got unexpected bit count %d for format %s.\n",
11664 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
11665 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
11666 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
11667 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
11668 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
11669 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
11671 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %lu for format %s.\n",
11672 dib
.dsBmih
.biSize
, test_data
[i
].name
);
11673 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %ld for format %s.\n",
11674 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11675 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %ld for format %s.\n",
11676 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11677 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
11678 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
11679 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
11680 "Got unexpected bit count %u for format %s.\n",
11681 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
11682 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
11683 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
11684 "Got unexpected compression %#lx for format %s.\n",
11685 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
11686 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %lu for format %s.\n",
11687 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
11688 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %ld for format %s.\n",
11689 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
11690 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %ld for format %s.\n",
11691 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
11692 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %lu for format %s.\n",
11693 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
11694 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %lu for format %s.\n",
11695 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
11697 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11699 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
11700 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
11701 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
11702 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11703 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11704 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11708 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11709 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11710 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11712 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11713 ok(!dib
.dsOffset
, "Got unexpected offset %lu for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11715 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11716 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11720 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11723 IDirectDrawSurface_Release(surface
);
11728 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11729 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11731 skip("Failed to create mip-mapped texture for format %s (hr %#lx), skipping tests.\n",
11732 test_data
[i
].name
, hr
);
11736 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
11737 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11738 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
11739 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11740 IDirectDrawSurface_Release(tmp
);
11742 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11743 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11744 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11745 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11746 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11747 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11748 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11749 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11751 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11752 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11753 dc2
= (void *)0x1234;
11754 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11755 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11756 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11757 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11758 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11759 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11760 ok(hr
== DDERR_NODC
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11762 map_desc
.dwSize
= sizeof(map_desc
);
11763 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11764 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11765 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11766 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11767 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11768 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11769 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11770 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11772 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11773 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11774 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11775 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11776 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11777 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11779 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11780 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11781 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11782 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11783 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11784 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11785 /* Geforce 9600, Windows 7 returns E_FAIL. The unlock still seems to work as intended, after-
11786 * wards the surface can be locked again. ReleaseDC() does not unlock the surface, trying to
11787 * Lock it after ReleaseDC returns DDERR_SURFACEBUSY. ddraw4 and 7 are unaffected. */
11788 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11789 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11790 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11792 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11793 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11794 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
11795 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11796 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
11797 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11798 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11799 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11801 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11802 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11803 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11804 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11805 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
11806 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11807 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11808 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11810 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11811 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11812 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11813 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11814 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11815 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11816 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11817 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11819 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11820 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11821 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11822 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11823 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11824 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11825 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11826 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11827 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11829 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11830 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11831 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11832 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11833 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11834 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11835 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11836 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11838 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11839 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11840 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11841 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11842 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11843 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11844 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11845 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11847 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11848 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11849 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11850 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11851 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11852 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11853 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11854 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11856 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11857 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11858 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11859 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11860 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11861 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11862 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11863 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11864 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11865 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11867 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11868 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11869 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11870 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11871 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11872 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11873 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11874 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11875 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11876 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11878 IDirectDrawSurface_Release(surface2
);
11879 IDirectDrawSurface_Release(surface
);
11882 IDirectDraw2_Release(ddraw
);
11883 DestroyWindow(window
);
11886 static void test_draw_primitive(void)
11888 static WORD indices
[] = {0, 1, 2, 3};
11889 static D3DVERTEX quad
[] =
11891 {{-1.0f
}, {-1.0f
}, {0.0f
}},
11892 {{-1.0f
}, { 1.0f
}, {0.0f
}},
11893 {{ 1.0f
}, {-1.0f
}, {0.0f
}},
11894 {{ 1.0f
}, { 1.0f
}, {0.0f
}},
11896 IDirect3DViewport2
*viewport
;
11897 IDirect3DDevice2
*device
;
11898 IDirectDraw2
*ddraw
;
11904 window
= create_window();
11905 ddraw
= create_ddraw();
11906 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11907 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11909 skip("Failed to create a 3D device, skipping test.\n");
11910 IDirectDraw2_Release(ddraw
);
11911 DestroyWindow(window
);
11915 viewport
= create_viewport(device
, 0, 0, 640, 480);
11916 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
11917 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
11919 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
11920 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
11922 IDirect3D2_Release(d3d
);
11924 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
11925 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11926 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
11927 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11929 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
11930 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11932 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
11933 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11934 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
11935 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11936 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
11937 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11939 destroy_viewport(device
, viewport
);
11940 refcount
= IDirect3DDevice2_Release(device
);
11941 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11942 IDirectDraw2_Release(ddraw
);
11943 DestroyWindow(window
);
11946 static void test_edge_antialiasing_blending(void)
11948 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11949 IDirect3DMaterial2
*green_background
;
11950 IDirect3DMaterial2
*red_background
;
11951 IDirectDrawSurface
*offscreen
, *ds
;
11952 D3DDEVICEDESC hal_desc
, hel_desc
;
11953 IDirect3DViewport2
*viewport
;
11954 DDSURFACEDESC surface_desc
;
11955 IDirect3DDevice2
*device
;
11956 IDirectDraw2
*ddraw
;
11957 unsigned int color
;
11962 static D3DMATRIX mat
=
11964 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11965 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11966 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11967 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11969 static D3DLVERTEX green_quad
[] =
11971 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11972 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11973 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11974 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
11976 static D3DLVERTEX red_quad
[] =
11978 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
11979 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
11980 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
11981 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
11984 window
= create_window();
11985 ddraw
= create_ddraw();
11986 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11987 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11989 skip("Failed to create a 3D device.\n");
11990 DestroyWindow(window
);
11994 memset(&hal_desc
, 0, sizeof(hal_desc
));
11995 hal_desc
.dwSize
= sizeof(hal_desc
);
11996 memset(&hel_desc
, 0, sizeof(hel_desc
));
11997 hel_desc
.dwSize
= sizeof(hel_desc
);
11998 hr
= IDirect3DDevice2_GetCaps(device
, &hal_desc
, &hel_desc
);
11999 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
12000 trace("HAL line edge antialiasing support: %#lx.\n",
12001 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12002 trace("HAL triangle edge antialiasing support: %#lx.\n",
12003 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12004 trace("HEL line edge antialiasing support: %#lx.\n",
12005 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12006 trace("HEL triangle edge antialiasing support: %#lx.\n",
12007 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12009 memset(&surface_desc
, 0, sizeof(surface_desc
));
12010 surface_desc
.dwSize
= sizeof(surface_desc
);
12011 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12012 surface_desc
.dwWidth
= 640;
12013 surface_desc
.dwHeight
= 480;
12014 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
12015 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
12016 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12017 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12018 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12019 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12020 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12021 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12022 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12023 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#lx.\n", hr
);
12025 ds
= get_depth_stencil(device
);
12026 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
12027 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
12028 IDirectDrawSurface_Release(ds
);
12030 hr
= IDirect3DDevice2_SetRenderTarget(device
, offscreen
, 0);
12031 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
12033 red_background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 0.8f
);
12034 green_background
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.5f
);
12036 viewport
= create_viewport(device
, 0, 0, 640, 480);
12037 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12038 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12040 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12041 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12042 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12043 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
12044 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12045 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
12046 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12047 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#lx.\n", hr
);
12048 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12049 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
12050 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12051 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
12053 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
12054 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#lx.\n", hr
);
12055 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
12056 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#lx.\n", hr
);
12057 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
12058 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#lx.\n", hr
);
12060 viewport_set_background(device
, viewport
, red_background
);
12061 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12062 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12063 hr
= IDirect3DDevice2_BeginScene(device
);
12064 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12065 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12066 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12067 hr
= IDirect3DDevice2_EndScene(device
);
12068 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12069 color
= get_surface_color(offscreen
, 320, 240);
12070 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12072 viewport_set_background(device
, viewport
, green_background
);
12073 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12074 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12075 hr
= IDirect3DDevice2_BeginScene(device
);
12076 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12077 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12078 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12079 hr
= IDirect3DDevice2_EndScene(device
);
12080 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12081 color
= get_surface_color(offscreen
, 320, 240);
12082 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12084 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
12085 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#lx.\n", hr
);
12087 viewport_set_background(device
, viewport
, red_background
);
12088 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12089 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12090 hr
= IDirect3DDevice2_BeginScene(device
);
12091 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12092 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12093 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12094 hr
= IDirect3DDevice2_EndScene(device
);
12095 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12096 color
= get_surface_color(offscreen
, 320, 240);
12097 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12099 viewport_set_background(device
, viewport
, green_background
);
12100 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12101 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12102 hr
= IDirect3DDevice2_BeginScene(device
);
12103 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12104 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12105 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12106 hr
= IDirect3DDevice2_EndScene(device
);
12107 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12108 color
= get_surface_color(offscreen
, 320, 240);
12109 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12111 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
12112 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#lx.\n", hr
);
12114 viewport_set_background(device
, viewport
, red_background
);
12115 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12116 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12117 hr
= IDirect3DDevice2_BeginScene(device
);
12118 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12119 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12120 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12121 hr
= IDirect3DDevice2_EndScene(device
);
12122 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12123 color
= get_surface_color(offscreen
, 320, 240);
12124 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12126 viewport_set_background(device
, viewport
, green_background
);
12127 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12128 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12129 hr
= IDirect3DDevice2_BeginScene(device
);
12130 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12131 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12132 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12133 hr
= IDirect3DDevice2_EndScene(device
);
12134 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12135 color
= get_surface_color(offscreen
, 320, 240);
12136 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12138 IDirectDrawSurface_Release(offscreen
);
12139 destroy_viewport(device
, viewport
);
12140 destroy_material(red_background
);
12141 destroy_material(green_background
);
12142 refcount
= IDirect3DDevice2_Release(device
);
12143 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12144 IDirectDraw2_Release(ddraw
);
12145 DestroyWindow(window
);
12148 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
12149 * The stride is honored for navigating to the next vertex. 3 floats input position
12150 * are read, and 16 bytes extra vertex data are copied around. */
12151 struct transform_input
12153 float x
, y
, z
, unused1
; /* Position data, transformed. */
12154 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
12158 struct transform_output
12161 unsigned int v1
, v2
, v3
, v4
;
12162 unsigned int unused3
, unused4
;
12165 static void test_transform_vertices(void)
12167 IDirect3DDevice2
*device
;
12168 IDirectDrawSurface
*rt
;
12169 unsigned int color
, i
;
12170 IDirectDraw2
*ddraw
;
12174 IDirect3DViewport2
*viewport
;
12175 IDirect3DMaterial2
*background
;
12177 static struct transform_input position_tests
[] =
12179 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12180 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
12181 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
12182 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
12183 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
12184 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
12186 static struct transform_input cliptest
[] =
12188 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
12189 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
12190 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12191 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
12193 static struct transform_input offscreentest
[] =
12195 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12197 struct transform_output out
[ARRAY_SIZE(position_tests
)];
12198 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
12199 D3DTRANSFORMDATA transformdata
;
12200 static const D3DVIEWPORT vp_template
=
12202 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
12204 D3DVIEWPORT vp_data
=
12206 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
12208 D3DVIEWPORT2 vp2_data
;
12210 static D3DMATRIX mat_scale
=
12212 2.0f
, 0.0f
, 0.0f
, 0.0f
,
12213 0.0f
, 2.0f
, 0.0f
, 0.0f
,
12214 0.0f
, 0.0f
, 2.0f
, 0.0f
,
12215 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12219 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12220 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12221 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12222 1.0f
, 0.0f
, 0.0f
, 1.0f
,
12226 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12227 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12228 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12229 0.0f
, 1.0f
, 0.0f
, 1.0f
,
12233 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12234 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12235 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12236 0.0f
, 19.2f
, 0.0f
, 2.0f
,
12240 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12241 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12242 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12243 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12245 static D3DLVERTEX quad
[] =
12247 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12248 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12249 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12250 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12252 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12255 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
12257 out
[i
].unused3
= 0xdeadbeef;
12258 out
[i
].unused4
= 0xcafecafe;
12261 window
= create_window();
12262 ddraw
= create_ddraw();
12263 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12264 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12266 skip("Failed to create a 3D device, skipping test.\n");
12267 IDirectDraw2_Release(ddraw
);
12268 DestroyWindow(window
);
12271 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
12272 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12274 viewport
= create_viewport(device
, 0, 0, 256, 256);
12275 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12276 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12278 memset(&transformdata
, 0, sizeof(transformdata
));
12279 transformdata
.dwSize
= sizeof(transformdata
);
12280 transformdata
.lpIn
= position_tests
;
12281 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12282 transformdata
.lpOut
= out
;
12283 transformdata
.dwOutSize
= sizeof(out
[0]);
12284 transformdata
.lpHOut
= NULL
;
12286 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12287 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12288 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12289 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12291 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12293 static const struct vec4 cmp
[] =
12295 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
12296 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
12299 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12300 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12301 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12302 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
12303 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
12304 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
12305 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
12306 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
12309 vp_data
= vp_template
;
12310 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12311 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12312 offscreen
= 0xdeadbeef;
12313 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12314 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12315 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12316 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12318 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12320 static const struct vec4 cmp
[] =
12322 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
12323 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
12325 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12326 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12327 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12332 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12333 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12334 offscreen
= 0xdeadbeef;
12335 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12336 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12337 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12338 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12339 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12341 static const struct vec4 cmp
[] =
12343 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
12344 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12346 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12347 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12348 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12351 transformdata
.lpHOut
= out_h
;
12352 offscreen
= 0xdeadbeef;
12353 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12354 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12355 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12356 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12357 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12359 static const D3DHVERTEX cmp_h
[] =
12361 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
12362 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
12363 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
12365 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12366 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12367 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12368 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12369 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
12370 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12372 /* No scheme has been found behind those return values. It seems to be
12373 * whatever data windows has when throwing the vertex away. Modify the
12374 * input test vertices to test this more. Depending on the input data
12375 * it can happen that the z coord gets written into y, or similar things. */
12378 static const struct vec4 cmp
[] =
12380 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
12381 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12383 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12384 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12385 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12389 transformdata
.lpIn
= cliptest
;
12390 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12391 offscreen
= 0xdeadbeef;
12392 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12393 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12394 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12395 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12396 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12398 static const DWORD flags
[] =
12401 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
12403 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
12405 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12408 vp_data
= vp_template
;
12409 vp_data
.dwWidth
= 10;
12410 vp_data
.dwHeight
= 480;
12411 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12412 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12413 offscreen
= 0xdeadbeef;
12414 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12415 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12416 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12417 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12418 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12420 static const DWORD flags
[] =
12423 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
12425 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
12427 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12430 vp_data
= vp_template
;
12431 vp_data
.dwWidth
= 256;
12432 vp_data
.dwHeight
= 256;
12433 vp_data
.dvScaleX
= 1;
12434 vp_data
.dvScaleY
= 1;
12435 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12436 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12437 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12438 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12439 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12440 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12441 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12443 static const DWORD flags
[] =
12450 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12453 /* Finally try to figure out how the DWORD dwOffscreen works.
12454 * It is a logical AND of the vertices' dwFlags members. */
12455 vp_data
= vp_template
;
12456 vp_data
.dwWidth
= 5;
12457 vp_data
.dwHeight
= 5;
12458 vp_data
.dvScaleX
= 10000.0f
;
12459 vp_data
.dvScaleY
= 10000.0f
;
12460 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12461 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12462 transformdata
.lpIn
= cliptest
;
12463 offscreen
= 0xdeadbeef;
12464 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12465 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12466 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12467 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12469 offscreen
= 0xdeadbeef;
12470 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12471 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12472 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12473 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12474 offscreen
= 0xdeadbeef;
12475 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12476 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12477 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12478 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12479 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
12480 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12481 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12482 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12484 transformdata
.lpIn
= cliptest
+ 1;
12485 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12486 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12487 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12488 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12490 transformdata
.lpIn
= cliptest
+ 2;
12491 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12492 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12493 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12494 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12495 offscreen
= 0xdeadbeef;
12496 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12497 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12498 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12499 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12501 transformdata
.lpIn
= cliptest
+ 3;
12502 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12503 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12504 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12505 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12507 transformdata
.lpIn
= offscreentest
;
12508 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
12509 vp_data
= vp_template
;
12510 vp_data
.dwWidth
= 257;
12511 vp_data
.dwHeight
= 257;
12512 vp_data
.dvScaleX
= 1.0f
;
12513 vp_data
.dvScaleY
= 1.0f
;
12514 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12515 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12516 offscreen
= 0xdeadbeef;
12517 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12518 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12519 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12520 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12522 vp_data
.dwWidth
= 256;
12523 vp_data
.dwHeight
= 256;
12524 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12525 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12526 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12527 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12528 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12529 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %#lx.\n", offscreen
);
12531 /* Test the effect of Matrices.
12533 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
12534 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
12535 * the view matrix and the +1's from the world and projection matrix. */
12538 vp_data
.dwWidth
= 256;
12539 vp_data
.dwHeight
= 256;
12540 vp_data
.dvScaleX
= 5.0f
;
12541 vp_data
.dvScaleY
= 5.0f
;
12542 vp_data
.dvMinZ
= 0.0f
;
12543 vp_data
.dvMaxZ
= 1.0f
;
12544 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12545 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12547 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
12548 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12549 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
12550 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12551 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
12552 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12554 transformdata
.lpIn
= position_tests
;
12555 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12556 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12557 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12558 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12560 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12562 static const struct vec4 cmp
[] =
12564 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
12565 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
12568 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12569 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12570 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12573 /* Invalid flags. */
12574 offscreen
= 0xdeadbeef;
12575 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12576 &transformdata
, 0, &offscreen
);
12577 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12578 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12580 /* NULL transform data. */
12581 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12582 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12583 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12584 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12585 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12586 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12587 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12588 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12590 /* NULL transform data and NULL dwOffscreen.
12592 * Valid transform data + NULL dwOffscreen -> crash. */
12593 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12594 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
12595 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12598 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12599 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12600 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12601 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12602 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12603 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12604 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12605 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
12607 /* Invalid sizes. */
12608 offscreen
= 0xdeadbeef;
12609 transformdata
.dwSize
= sizeof(transformdata
) - 1;
12610 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12611 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12612 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12613 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12614 transformdata
.dwSize
= sizeof(transformdata
) + 1;
12615 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12616 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12617 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12618 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12620 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
12621 transformdata
.dwSize
= sizeof(transformdata
);
12622 transformdata
.lpIn
= NULL
;
12623 transformdata
.lpOut
= NULL
;
12624 offscreen
= 0xdeadbeef;
12625 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12626 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12627 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12628 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
12630 /* Test how vertices are transformed during draws. */
12633 vp_data
.dwWidth
= 200;
12634 vp_data
.dwHeight
= 400;
12635 vp_data
.dvScaleX
= 20.0f
;
12636 vp_data
.dvScaleY
= 50.0f
;
12637 vp_data
.dvMinZ
= 0.0f
;
12638 vp_data
.dvMaxZ
= 1.0f
;
12639 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12640 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12641 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12642 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12644 ok(SUCCEEDED(hr
), "Failed to clear the render target, hr %#lx.\n", hr
);
12645 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
12646 viewport_set_background(device
, viewport
, background
);
12647 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12648 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12650 hr
= IDirect3DDevice2_BeginScene(device
);
12651 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12652 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12653 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12654 hr
= IDirect3DDevice2_EndScene(device
);
12655 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12657 color
= get_surface_color(rt
, 128, 143);
12658 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12659 color
= get_surface_color(rt
, 132, 143);
12660 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12661 color
= get_surface_color(rt
, 128, 147);
12662 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12663 color
= get_surface_color(rt
, 132, 147);
12664 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12666 color
= get_surface_color(rt
, 177, 217);
12667 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12668 color
= get_surface_color(rt
, 181, 217);
12669 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12670 color
= get_surface_color(rt
, 177, 221);
12671 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12672 color
= get_surface_color(rt
, 181, 221);
12673 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12675 /* Test D3DVIEWPORT2 behavior. */
12676 vp2_data
.dwSize
= sizeof(vp2_data
);
12679 vp2_data
.dwWidth
= 200;
12680 vp2_data
.dwHeight
= 400;
12681 vp2_data
.dvClipX
= -0.5f
;
12682 vp2_data
.dvClipY
= 4.0f
;
12683 vp2_data
.dvClipWidth
= 5.0f
;
12684 vp2_data
.dvClipHeight
= 10.0f
;
12685 vp2_data
.dvMinZ
= 0.0f
;
12686 vp2_data
.dvMaxZ
= 2.0f
;
12687 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12688 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
12689 transformdata
.lpIn
= position_tests
;
12690 transformdata
.lpOut
= out
;
12691 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12692 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12693 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12694 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12696 static const struct vec4 cmp
[] =
12698 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
12699 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
12702 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12703 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12704 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12707 memset(&mat
, 0, sizeof(mat
));
12708 mat
.dwSize
= sizeof(mat
);
12709 U1(U(mat
).diffuse
).r
= 0.0f
;
12710 U2(U(mat
).diffuse
).g
= 1.0f
;
12711 U3(U(mat
).diffuse
).b
= 0.0f
;
12712 U4(U(mat
).diffuse
).a
= 0.0f
;
12713 hr
= IDirect3DMaterial2_SetMaterial(background
, &mat
);
12714 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
12715 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12716 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12718 hr
= IDirect3DDevice2_BeginScene(device
);
12719 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12720 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12721 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12722 hr
= IDirect3DDevice2_EndScene(device
);
12723 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12725 color
= get_surface_color(rt
, 58, 118);
12726 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12727 color
= get_surface_color(rt
, 62, 118);
12728 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12729 color
= get_surface_color(rt
, 58, 122);
12730 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12731 color
= get_surface_color(rt
, 62, 122);
12732 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12734 color
= get_surface_color(rt
, 157, 177);
12735 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12736 color
= get_surface_color(rt
, 161, 177);
12737 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12738 color
= get_surface_color(rt
, 157, 181);
12739 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12740 color
= get_surface_color(rt
, 161, 181);
12741 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12743 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
12744 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12745 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
12746 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12747 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
12748 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12750 vp2_data
.dwX
= 0.0;
12751 vp2_data
.dwY
= 0.0;
12752 vp2_data
.dwWidth
= 1;
12753 vp2_data
.dwHeight
= 1;
12754 vp2_data
.dvClipX
= -12.8f
;
12755 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
12756 vp2_data
.dvClipWidth
= 25.6f
;
12757 vp2_data
.dvClipHeight
= 25.6f
;
12758 vp2_data
.dvMinZ
= 0.0f
;
12759 vp2_data
.dvMaxZ
= 0.5f
;
12760 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12761 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
12762 transformdata
.lpIn
= cliptest
;
12763 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12764 offscreen
= 0xdeadbeef;
12765 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12766 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12767 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12768 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12769 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12771 static const D3DHVERTEX cmp_h
[] =
12773 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
12774 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
12775 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
12776 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
12778 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12779 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12780 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12781 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12782 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
12783 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12786 IDirectDrawSurface_Release(rt
);
12787 destroy_viewport(device
, viewport
);
12788 IDirect3DMaterial2_Release(background
);
12789 refcount
= IDirect3DDevice_Release(device
);
12790 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12791 IDirectDraw2_Release(ddraw
);
12792 DestroyWindow(window
);
12795 static void test_display_mode_surface_pixel_format(void)
12797 unsigned int width
, height
, bpp
;
12798 IDirectDrawSurface
*surface
;
12799 DDSURFACEDESC surface_desc
;
12800 IDirectDraw2
*ddraw
;
12805 if (!(ddraw
= create_ddraw()))
12807 skip("Failed to create ddraw.\n");
12811 surface_desc
.dwSize
= sizeof(surface_desc
);
12812 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
12813 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
12814 width
= surface_desc
.dwWidth
;
12815 height
= surface_desc
.dwHeight
;
12817 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
12818 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
12819 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
12820 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12823 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
12825 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
12827 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
12829 ok(bpp
, "Set display mode failed.\n");
12831 surface_desc
.dwSize
= sizeof(surface_desc
);
12832 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
12833 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
12834 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
12835 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
12836 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
12837 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12839 memset(&surface_desc
, 0, sizeof(surface_desc
));
12840 surface_desc
.dwSize
= sizeof(surface_desc
);
12841 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
12842 surface_desc
.dwBackBufferCount
= 1;
12843 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
12844 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12845 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
12846 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
12847 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12848 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
12849 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
12850 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
12851 surface_desc
.ddpfPixelFormat
.dwFlags
);
12852 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
12853 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12854 IDirectDrawSurface_Release(surface
);
12856 memset(&surface_desc
, 0, sizeof(surface_desc
));
12857 surface_desc
.dwSize
= sizeof(surface_desc
);
12858 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
12859 surface_desc
.dwWidth
= width
;
12860 surface_desc
.dwHeight
= height
;
12861 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12862 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12863 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
12864 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
12865 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12866 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
12867 surface_desc
.ddpfPixelFormat
.dwFlags
);
12868 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
12869 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
12870 IDirectDrawSurface_Release(surface
);
12872 refcount
= IDirectDraw2_Release(ddraw
);
12873 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12874 DestroyWindow(window
);
12877 static void test_surface_desc_size(void)
12882 DDSURFACEDESC desc1
;
12883 DDSURFACEDESC2 desc2
;
12886 IDirectDrawSurface7
*surface7
;
12887 IDirectDrawSurface2
*surface2
;
12888 IDirectDrawSurface
*surface
;
12889 DDSURFACEDESC surface_desc
;
12890 HRESULT expected_hr
, hr
;
12891 IDirectDraw2
*ddraw
;
12895 static const struct
12902 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
12903 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
12904 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
12906 static const unsigned int desc_sizes
[] =
12908 sizeof(DDSURFACEDESC
),
12909 sizeof(DDSURFACEDESC2
),
12910 sizeof(DDSURFACEDESC
) + 1,
12911 sizeof(DDSURFACEDESC2
) + 1,
12912 2 * sizeof(DDSURFACEDESC
),
12913 2 * sizeof(DDSURFACEDESC2
),
12914 sizeof(DDSURFACEDESC
) - 1,
12915 sizeof(DDSURFACEDESC2
) - 1,
12916 sizeof(DDSURFACEDESC
) / 2,
12917 sizeof(DDSURFACEDESC2
) / 2,
12922 sizeof(desc
) - 100,
12925 if (!(ddraw
= create_ddraw()))
12927 skip("Failed to create ddraw.\n");
12930 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
12931 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12933 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
12935 memset(&surface_desc
, 0, sizeof(surface_desc
));
12936 surface_desc
.dwSize
= sizeof(surface_desc
);
12937 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
12938 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
12939 surface_desc
.dwHeight
= 128;
12940 surface_desc
.dwWidth
= 128;
12941 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
12943 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
12946 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
12947 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface2, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
12948 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
12949 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
12951 /* GetSurfaceDesc() */
12952 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
12954 memset(&desc
, 0, sizeof(desc
));
12955 desc
.dwSize
= desc_sizes
[j
];
12956 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12957 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
12958 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
12959 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12961 memset(&desc
, 0, sizeof(desc
));
12962 desc
.dwSize
= desc_sizes
[j
];
12963 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12964 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface2
, &desc
.desc1
);
12965 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
12966 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12968 memset(&desc
, 0, sizeof(desc
));
12969 desc
.dwSize
= desc_sizes
[j
];
12970 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
12971 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
12972 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
12973 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12977 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
12979 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
12980 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
12981 DWORD expected_texture_stage
;
12983 memset(&desc
, 0, sizeof(desc
));
12984 desc
.dwSize
= desc_sizes
[j
];
12985 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
12986 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
12987 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
12988 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
12989 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
12990 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
12991 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
12992 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
12993 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
12994 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
12997 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
12998 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
12999 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13000 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13001 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13002 todo_wine_if(!expected_texture_stage
)
13003 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13004 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13005 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13006 IDirectDrawSurface_Unlock(surface
, NULL
);
13009 memset(&desc
, 0, sizeof(desc
));
13010 desc
.dwSize
= desc_sizes
[j
];
13011 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13012 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13013 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &desc
.desc1
, 0, 0);
13014 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13015 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13016 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13017 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
13018 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13019 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
13020 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13023 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
13024 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13025 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13026 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13027 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13028 todo_wine_if(!expected_texture_stage
)
13029 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13030 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13031 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13032 IDirectDrawSurface2_Unlock(surface2
, NULL
);
13035 memset(&desc
, 0, sizeof(desc
));
13036 desc
.dwSize
= desc_sizes
[j
];
13037 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13038 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13039 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
13040 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13041 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13042 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13043 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
13044 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13045 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
13046 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13049 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
13050 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13051 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13052 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13053 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13054 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13055 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13056 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13057 IDirectDrawSurface7_Unlock(surface7
, NULL
);
13061 IDirectDrawSurface7_Release(surface7
);
13062 IDirectDrawSurface2_Release(surface2
);
13063 IDirectDrawSurface_Release(surface
);
13066 /* GetDisplayMode() */
13067 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13069 memset(&desc
, 0xcc, sizeof(desc
));
13070 desc
.dwSize
= desc_sizes
[j
];
13071 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
13072 ? DD_OK
: DDERR_INVALIDPARAMS
;
13073 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
.desc1
);
13074 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
13077 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %lu for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
13078 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
13079 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
13083 refcount
= IDirectDraw2_Release(ddraw
);
13084 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13087 static void test_ck_operation(void)
13089 IDirectDrawSurface2
*src
, *dst
;
13090 IDirectDrawSurface7
*src7
, *dst7
;
13091 IDirectDrawSurface
*surface1
;
13092 DDSURFACEDESC surface_desc
;
13093 unsigned int i
, *color
;
13094 IDirectDraw2
*ddraw
;
13101 window
= create_window();
13102 ddraw
= create_ddraw();
13103 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13104 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13105 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13107 memset(&surface_desc
, 0, sizeof(surface_desc
));
13108 surface_desc
.dwSize
= sizeof(surface_desc
);
13109 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13110 surface_desc
.dwWidth
= 4;
13111 surface_desc
.dwHeight
= 1;
13112 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13113 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13114 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
13115 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
13116 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
13117 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
13118 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13119 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13120 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
13121 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13122 IDirectDrawSurface_Release(surface1
);
13124 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
13125 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
13126 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
13127 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13128 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13129 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
13130 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13131 IDirectDrawSurface_Release(surface1
);
13133 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13134 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13135 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13136 color
= surface_desc
.lpSurface
;
13137 color
[0] = 0x77010203;
13138 color
[1] = 0x00010203;
13139 color
[2] = 0x77ff00ff;
13140 color
[3] = 0x00ff00ff;
13141 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
13142 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13144 for (i
= 0; i
< 2; ++i
)
13146 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13147 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13148 color
= surface_desc
.lpSurface
;
13149 color
[0] = 0xcccccccc;
13150 color
[1] = 0xcccccccc;
13151 color
[2] = 0xcccccccc;
13152 color
[3] = 0xcccccccc;
13153 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13154 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13158 hr
= IDirectDrawSurface2_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
13159 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13163 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
13164 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13167 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
13168 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13169 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13170 color
= surface_desc
.lpSurface
;
13171 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
13172 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
13173 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
13174 * color keying nor copies it. */
13175 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
13176 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
13177 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13178 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
13179 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13180 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
13181 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
13182 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
13183 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
13184 color
[0], color
[1], color
[2], color
[3], i
);
13185 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13186 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13189 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13190 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13191 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
13192 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13194 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13195 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13196 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13198 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13199 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13200 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13201 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
13202 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13204 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
13205 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
13206 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
13207 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13208 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
13209 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
13210 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13211 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13213 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
13214 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13215 ckey
.dwColorSpaceHighValue
= 0x00000000;
13216 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13217 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13219 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13220 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13221 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13222 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13223 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13225 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13226 ckey
.dwColorSpaceHighValue
= 0x00000001;
13227 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13228 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13230 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13231 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13232 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13233 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13234 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13236 ckey
.dwColorSpaceLowValue
= 0x000000fe;
13237 ckey
.dwColorSpaceHighValue
= 0x000000fd;
13238 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13239 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13241 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13242 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13243 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13244 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
13245 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13247 IDirectDrawSurface2_Release(src
);
13248 IDirectDrawSurface2_Release(dst
);
13250 /* Test source and destination keys and where they are read from. Use a surface with alpha
13251 * to avoid driver-dependent content in the X channel. */
13252 memset(&surface_desc
, 0, sizeof(surface_desc
));
13253 surface_desc
.dwSize
= sizeof(surface_desc
);
13254 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13255 surface_desc
.dwWidth
= 6;
13256 surface_desc
.dwHeight
= 1;
13257 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13258 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13259 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
13260 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
13261 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
13262 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
13263 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
13264 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13265 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13266 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
13267 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13268 IDirectDrawSurface_Release(surface1
);
13270 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13271 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13272 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
13273 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13274 IDirectDrawSurface_Release(surface1
);
13276 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
13277 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13278 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
13279 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13280 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
13281 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
13282 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
13283 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#lx.\n", hr
);
13286 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
13287 skip("Failed to set destination color key, skipping related tests.\n");
13291 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13292 ckey
.dwColorSpaceHighValue
= 0x000000ff;
13293 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13294 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13295 ckey
.dwColorSpaceLowValue
= 0x000000aa;
13296 ckey
.dwColorSpaceHighValue
= 0x000000aa;
13297 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13298 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13300 memset(&fx
, 0, sizeof(fx
));
13301 fx
.dwSize
= sizeof(fx
);
13302 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
13303 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
13304 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
13305 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
13307 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13308 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13309 color
= surface_desc
.lpSurface
;
13310 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
13311 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
13312 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
13313 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
13314 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
13315 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
13316 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
13317 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13319 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13320 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13321 color
= surface_desc
.lpSurface
;
13322 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13323 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13324 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13326 /* Test a blit without keying. */
13327 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
13328 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13330 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13331 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13332 color
= surface_desc
.lpSurface
;
13333 /* Should have copied src data unmodified to dst. */
13334 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13335 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13336 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13337 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13339 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13340 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13341 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13344 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13345 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13347 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13348 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13349 color
= surface_desc
.lpSurface
;
13350 /* Src key applied to color[0]. It is unmodified, the others are copied. */
13351 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13352 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13353 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13354 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13356 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13357 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13358 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13360 /* Src override. */
13361 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
13362 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13364 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13365 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13366 color
= surface_desc
.lpSurface
;
13367 /* Override key applied to color[5]. It is unmodified, the others are copied. */
13368 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13369 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
13370 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13371 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13373 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13374 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13375 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13377 /* Src override AND src key. That is not supposed to work. */
13378 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
13379 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13381 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13382 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13383 color
= surface_desc
.lpSurface
;
13384 /* Ensure the destination was not changed. */
13385 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
13386 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
13387 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13388 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13390 /* Use different dst colors for the dst key test. */
13391 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13392 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13393 color
[2] = 0x00001100; /* Dest key in override. */
13394 color
[3] = 0x00001100; /* Dest key in override. */
13395 color
[4] = 0x000000aa; /* Dest key in src surface. */
13396 color
[5] = 0x000000aa; /* Dest key in src surface. */
13397 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13398 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13400 /* Dest key blit. The key is taken from the SOURCE surface in v2! */
13401 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13402 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13404 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13405 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13406 color
= surface_desc
.lpSurface
;
13407 /* Dst key applied to color[4,5], they are the only changed pixels. */
13408 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13409 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13410 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13411 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13413 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13414 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13415 color
[2] = 0x00001100; /* Dest key in override. */
13416 color
[3] = 0x00001100; /* Dest key in override. */
13417 color
[4] = 0x000000aa; /* Dest key in src surface. */
13418 color
[5] = 0x000000aa; /* Dest key in src surface. */
13419 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13420 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13422 /* What happens with a QI'd newer version of the interface? It takes the key
13423 * from the destination surface. */
13424 hr
= IDirectDrawSurface2_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
13425 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
13426 hr
= IDirectDrawSurface2_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
13427 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
13429 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
13430 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13432 IDirectDrawSurface7_Release(dst7
);
13433 IDirectDrawSurface7_Release(src7
);
13435 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13436 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13437 color
= surface_desc
.lpSurface
;
13438 /* Dst key applied to color[0,1], they are the only changed pixels. */
13439 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13440 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13441 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13442 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13444 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13445 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13446 color
[2] = 0x00001100; /* Dest key in override. */
13447 color
[3] = 0x00001100; /* Dest key in override. */
13448 color
[4] = 0x000000aa; /* Dest key in src surface. */
13449 color
[5] = 0x000000aa; /* Dest key in src surface. */
13450 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13451 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13453 /* Dest override key blit. */
13454 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
13455 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13457 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13458 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13459 color
= surface_desc
.lpSurface
;
13460 /* Dst key applied to color[2,3], they are the only changed pixels. */
13461 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
13462 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13463 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13464 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13466 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13467 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13468 color
[2] = 0x00001100; /* Dest key in override. */
13469 color
[3] = 0x00001100; /* Dest key in override. */
13470 color
[4] = 0x000000aa; /* Dest key in src surface. */
13471 color
[5] = 0x000000aa; /* Dest key in src surface. */
13472 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13473 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13475 /* Dest override together with surface key. Supposed to fail. */
13476 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
13477 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13479 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13480 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13481 color
= surface_desc
.lpSurface
;
13482 /* Destination is unchanged. */
13483 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13484 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13485 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13486 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13487 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13488 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13490 /* Source and destination key. This is driver dependent. New HW treats it like
13491 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
13494 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
13495 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13497 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13498 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13499 color
= surface_desc
.lpSurface
;
13500 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
13501 * the driver applies it. */
13502 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13503 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13504 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13505 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13507 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13508 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13509 color
[2] = 0x00001100; /* Dest key in override. */
13510 color
[3] = 0x00001100; /* Dest key in override. */
13511 color
[4] = 0x000000aa; /* Dest key in src surface. */
13512 color
[5] = 0x000000aa; /* Dest key in src surface. */
13513 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13514 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13517 /* Override keys without ddbltfx parameter fail */
13518 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
13519 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13520 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
13521 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13523 /* Try blitting without keys in the source surface. */
13524 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
13525 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13526 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
13527 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13529 /* That fails now. Do not bother to check that the data is unmodified. */
13530 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13531 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13533 /* Surprisingly this still works. It uses the old key from the src surface. */
13534 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13535 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13537 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13538 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13539 color
= surface_desc
.lpSurface
;
13540 /* Dst key applied to color[4,5], they are the only changed pixels. */
13541 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13542 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13543 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13544 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13545 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13546 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13548 /* This returns DDERR_NOCOLORKEY as expected. */
13549 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13550 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
13552 /* GetSurfaceDesc returns a zeroed key as expected. */
13553 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
13554 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
13555 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
13556 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13557 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
13558 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
13559 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13560 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13562 /* Try blitting without keys in the destination surface. */
13563 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
13564 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13565 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
13566 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13568 /* This fails, as sanity would dictate. */
13569 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13570 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13573 IDirectDrawSurface2_Release(src
);
13574 IDirectDrawSurface2_Release(dst
);
13575 refcount
= IDirectDraw2_Release(ddraw
);
13576 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13577 DestroyWindow(window
);
13580 static void test_set_render_state(void)
13582 IDirect3DDevice2
*device
;
13583 IDirectDraw2
*ddraw
;
13589 window
= create_window();
13590 ddraw
= create_ddraw();
13591 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13592 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13594 skip("Failed to create 3D device.\n");
13595 DestroyWindow(window
);
13599 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
13600 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13601 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
13602 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13604 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
13605 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13606 state
= 0xdeadbeef;
13607 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
13608 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13609 ok(!state
, "Got unexpected render state %#lx.\n", state
);
13610 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
13611 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13612 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
13613 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13614 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#lx.\n", state
);
13616 refcount
= IDirect3DDevice2_Release(device
);
13617 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13618 refcount
= IDirectDraw2_Release(ddraw
);
13619 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13620 DestroyWindow(window
);
13623 static void test_depth_readback(void)
13625 unsigned int depth
, expected_depth
, i
, x
, y
, max_diff
, passed_fmts
= 0;
13626 IDirect3DMaterial2
*blue_background
;
13627 IDirectDrawSurface
*rt
, *ds
;
13628 IDirect3DViewport2
*viewport
;
13629 DDSURFACEDESC surface_desc
;
13630 IDirect3DDevice2
*device
;
13631 IDirectDraw2
*ddraw
;
13638 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
13639 static D3DLVERTEX quad
[] =
13641 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
13642 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
13643 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
13644 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
13647 static const struct
13649 unsigned int z_depth
, z_mask
;
13658 window
= create_window();
13659 ok(!!window
, "Failed to create a window.\n");
13660 ddraw
= create_ddraw();
13661 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13662 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13664 skip("Failed to create a D3D device, skipping tests.\n");
13665 IDirectDraw2_Release(ddraw
);
13666 DestroyWindow(window
);
13670 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13671 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13672 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13673 viewport
= create_viewport(device
, 0, 0, 640, 480);
13674 viewport_set_background(device
, viewport
, blue_background
);
13675 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13676 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13678 ds
= get_depth_stencil(device
);
13679 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13680 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
13681 IDirectDrawSurface_Release(ds
);
13683 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13685 memset(&surface_desc
, 0, sizeof(surface_desc
));
13686 surface_desc
.dwSize
= sizeof(surface_desc
);
13687 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
13688 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
13689 U2(surface_desc
).dwZBufferBitDepth
= tests
[i
].z_depth
;
13690 surface_desc
.dwWidth
= 640;
13691 surface_desc
.dwHeight
= 480;
13692 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
13695 skip("Format %u not supported, skipping test.\n", i
);
13699 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
13700 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
13701 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
13702 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
13704 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
13705 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13706 hr
= IDirect3DDevice2_BeginScene(device
);
13707 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
13708 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
13709 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
13710 hr
= IDirect3DDevice2_EndScene(device
);
13711 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
13713 memset(&surface_desc
, 0, sizeof(surface_desc
));
13714 surface_desc
.dwSize
= sizeof(surface_desc
);
13715 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13716 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13719 for (y
= 60; y
< 480; y
+= 120)
13721 for (x
= 80; x
< 640; x
+= 160)
13723 ptr
= (BYTE
*)surface_desc
.lpSurface
13724 + y
* U1(surface_desc
).lPitch
13725 + x
* (tests
[i
].z_depth
== 16 ? 2 : 4);
13726 depth
= *((DWORD
*)ptr
) & tests
[i
].z_mask
;
13727 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
13728 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
13729 /* The ddraw2 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
13730 * except that we only have D16 (broken on geforce 9) and D24X8 (broken on geforce 7) available.
13731 * Accept all nvidia GPUs as broken here, but still expect one of the formats to pass. */
13732 ok(compare_uint(expected_depth
, depth
, max_diff
) || ddraw_is_nvidia(ddraw
)
13733 || (ddraw_is_amd(ddraw
) && tests
[i
].z_depth
== 24),
13734 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
13735 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
13736 if (!compare_uint(expected_depth
, depth
, max_diff
))
13741 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
13742 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13747 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13748 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
13749 IDirectDrawSurface_Release(ds
);
13752 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
13754 destroy_viewport(device
, viewport
);
13755 destroy_material(blue_background
);
13756 IDirectDrawSurface_Release(rt
);
13757 refcount
= IDirect3DDevice2_Release(device
);
13758 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13759 IDirectDraw2_Release(ddraw
);
13760 DestroyWindow(window
);
13763 static void test_clear(void)
13765 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
13766 IDirect3DViewport2
*viewport
, *viewport2
, *viewport3
;
13767 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
13768 IDirect3DDevice2
*device
;
13769 IDirectDrawSurface
*rt
;
13770 IDirectDraw2
*ddraw
;
13771 unsigned int color
;
13777 window
= create_window();
13778 ddraw
= create_ddraw();
13779 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13780 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13782 skip("Failed to create a 3D device, skipping test.\n");
13783 IDirectDraw2_Release(ddraw
);
13784 DestroyWindow(window
);
13787 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13788 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13790 viewport
= create_viewport(device
, 0, 0, 640, 480);
13791 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13792 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13794 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
13795 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13796 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
13797 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13799 viewport_set_background(device
, viewport
, white
);
13800 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13801 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13803 /* Positive x, negative y. */
13804 U1(rect
[0]).x1
= 0;
13805 U2(rect
[0]).y1
= 480;
13806 U3(rect
[0]).x2
= 320;
13807 U4(rect
[0]).y2
= 240;
13809 /* Positive x, positive y. */
13810 U1(rect
[1]).x1
= 0;
13811 U2(rect
[1]).y1
= 0;
13812 U3(rect
[1]).x2
= 320;
13813 U4(rect
[1]).y2
= 240;
13815 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
13816 * refuse negative rectangles, but it will not clear them either. */
13817 viewport_set_background(device
, viewport
, red
);
13818 hr
= IDirect3DViewport2_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
13819 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13821 color
= get_surface_color(rt
, 160, 360);
13822 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
13823 color
= get_surface_color(rt
, 160, 120);
13824 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
13825 color
= get_surface_color(rt
, 480, 360);
13826 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
13827 color
= get_surface_color(rt
, 480, 120);
13828 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
13830 viewport_set_background(device
, viewport
, white
);
13831 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13832 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13834 /* negative x, negative y.
13835 * Also ignored, except on WARP, which clears the entire screen. */
13836 U1(rect_negneg
).x1
= 640;
13837 U2(rect_negneg
).y1
= 240;
13838 U3(rect_negneg
).x2
= 320;
13839 U4(rect_negneg
).y2
= 0;
13840 viewport_set_background(device
, viewport
, green
);
13841 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
13842 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13844 color
= get_surface_color(rt
, 160, 360);
13845 ok(compare_color(color
, 0x00ffffff, 0)
13846 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13847 "Got unexpected color 0x%08x.\n", color
);
13848 color
= get_surface_color(rt
, 160, 120);
13849 ok(compare_color(color
, 0x00ffffff, 0)
13850 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13851 "Got unexpected color 0x%08x.\n", color
);
13852 color
= get_surface_color(rt
, 480, 360);
13853 ok(compare_color(color
, 0x00ffffff, 0)
13854 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13855 "Got unexpected color 0x%08x.\n", color
);
13856 color
= get_surface_color(rt
, 480, 120);
13857 ok(compare_color(color
, 0x00ffffff, 0)
13858 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
13859 "Got unexpected color 0x%08x.\n", color
);
13861 /* Test how the viewport affects clears. */
13862 viewport_set_background(device
, viewport
, white
);
13863 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13864 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13866 viewport2
= create_viewport(device
, 160, 120, 160, 120);
13867 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
13868 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13870 viewport_set_background(device
, viewport2
, blue
);
13871 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
13872 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13874 viewport3
= create_viewport(device
, 320, 240, 320, 240);
13875 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport3
);
13876 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13878 U1(rect
[0]).x1
= 160;
13879 U2(rect
[0]).y1
= 120;
13880 U3(rect
[0]).x2
= 480;
13881 U4(rect
[0]).y2
= 360;
13882 viewport_set_background(device
, viewport3
, green
);
13883 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
13884 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13886 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13887 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13889 color
= get_surface_color(rt
, 158, 118);
13890 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
13891 color
= get_surface_color(rt
, 162, 118);
13892 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
13893 color
= get_surface_color(rt
, 158, 122);
13894 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
13895 color
= get_surface_color(rt
, 162, 122);
13896 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
13898 color
= get_surface_color(rt
, 318, 238);
13899 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
13900 color
= get_surface_color(rt
, 322, 238);
13901 ok(compare_color(color
, 0x00ffffff, 0), "(322, 238) has color 0x%08x.\n", color
);
13902 color
= get_surface_color(rt
, 318, 242);
13903 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
13904 color
= get_surface_color(rt
, 322, 242);
13905 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
13907 color
= get_surface_color(rt
, 478, 358);
13908 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
13909 color
= get_surface_color(rt
, 482, 358);
13910 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
13911 color
= get_surface_color(rt
, 478, 362);
13912 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
13913 color
= get_surface_color(rt
, 482, 362);
13914 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
13916 /* The clear rectangle is rendertarget absolute, not relative to the
13918 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13919 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13920 U1(rect
[0]).x1
= 330;
13921 U2(rect
[0]).y1
= 250;
13922 U3(rect
[0]).x2
= 340;
13923 U4(rect
[0]).y2
= 260;
13924 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
13925 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13927 color
= get_surface_color(rt
, 328, 248);
13928 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
13929 color
= get_surface_color(rt
, 332, 248);
13930 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
13931 color
= get_surface_color(rt
, 328, 252);
13932 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
13933 color
= get_surface_color(rt
, 332, 252);
13934 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
13936 color
= get_surface_color(rt
, 338, 248);
13937 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
13938 color
= get_surface_color(rt
, 342, 248);
13939 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
13940 color
= get_surface_color(rt
, 338, 252);
13941 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
13942 color
= get_surface_color(rt
, 342, 252);
13943 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
13945 color
= get_surface_color(rt
, 328, 258);
13946 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
13947 color
= get_surface_color(rt
, 332, 258);
13948 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
13949 color
= get_surface_color(rt
, 328, 262);
13950 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
13951 color
= get_surface_color(rt
, 332, 262);
13952 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
13954 color
= get_surface_color(rt
, 338, 258);
13955 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
13956 color
= get_surface_color(rt
, 342, 258);
13957 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
13958 color
= get_surface_color(rt
, 338, 262);
13959 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
13960 color
= get_surface_color(rt
, 342, 262);
13961 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
13963 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
13966 IDirect3DViewport2_Release(viewport3
);
13967 IDirect3DViewport2_Release(viewport2
);
13968 IDirect3DViewport2_Release(viewport
);
13969 IDirect3DMaterial2_Release(white
);
13970 IDirect3DMaterial2_Release(red
);
13971 IDirect3DMaterial2_Release(green
);
13972 IDirect3DMaterial2_Release(blue
);
13973 IDirectDrawSurface_Release(rt
);
13974 refcount
= IDirect3DDevice2_Release(device
);
13975 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13976 refcount
= IDirectDraw2_Release(ddraw
);
13977 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
13978 DestroyWindow(window
);
13981 struct enum_surfaces_param
13983 IDirectDraw2
*ddraw
;
13984 DDSURFACEDESC modes
[20];
13985 unsigned int mode_count
;
13987 IDirectDrawSurface
*surfaces
[8];
13988 unsigned int count
;
13991 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC
*desc
, void *context
)
13993 struct enum_surfaces_param
*param
= context
;
13994 IDirectDrawSurface
*surface
;
13996 if (SUCCEEDED(IDirectDraw2_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
13998 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
13999 param
->modes
[param
->mode_count
] = *desc
;
14000 ++param
->mode_count
;
14001 IDirectDrawSurface_Release(surface
);
14004 return DDENUMRET_OK
;
14007 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
14009 struct enum_surfaces_param
*param
= context
;
14010 BOOL found
= FALSE
;
14013 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
14015 if (param
->surfaces
[i
] == surface
)
14022 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
14023 IDirectDrawSurface_Release(surface
);
14026 return DDENUMRET_OK
;
14029 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
14031 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
14032 struct enum_surfaces_param
*param
= context
;
14034 ok(!surface
, "Unexpected surface %p.\n", surface
);
14035 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#lx.\n", desc
->dwFlags
);
14036 if (param
->count
< ARRAY_SIZE(param
->modes
))
14038 const DDSURFACEDESC
*expect
= ¶m
->modes
[param
->count
];
14039 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %lu, got %lu.\n", expect
->dwWidth
, desc
->dwWidth
);
14040 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %lu, got %lu.\n", expect
->dwHeight
, desc
->dwHeight
);
14041 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
14042 "Pixel formats didn't match.\n");
14047 return DDENUMRET_OK
;
14050 static void test_enum_surfaces(void)
14052 struct enum_surfaces_param param
= {0};
14053 DDPIXELFORMAT current_format
;
14054 IDirectDraw2
*ddraw
;
14055 DDSURFACEDESC desc
;
14058 ddraw
= create_ddraw();
14059 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14060 param
.ddraw
= ddraw
;
14062 memset(&desc
, 0, sizeof(desc
));
14063 desc
.dwSize
= sizeof(desc
);
14064 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
);
14065 ok(hr
== DD_OK
, "Failed to get display mode, hr %#lx.\n", hr
);
14066 current_format
= desc
.ddpfPixelFormat
;
14068 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
14069 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#lx.\n", hr
);
14071 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
14072 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14074 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
14075 NULL
, NULL
, enum_surfaces_cb
);
14076 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14078 memset(&desc
, 0, sizeof(desc
));
14079 desc
.dwSize
= sizeof(desc
);
14080 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
14081 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
14082 U2(desc
).dwMipMapCount
= 3;
14084 desc
.dwHeight
= 32;
14085 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
14086 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
14088 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
14089 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
14090 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
14091 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
14092 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
14093 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14094 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
14097 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14098 &desc
, ¶m
, enum_surfaces_cb
);
14099 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14100 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14103 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14104 NULL
, ¶m
, enum_surfaces_cb
);
14105 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14106 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14108 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
14110 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14111 &desc
, ¶m
, enum_surfaces_cb
);
14112 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14113 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14116 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
14117 &desc
, ¶m
, enum_surfaces_cb
);
14118 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14119 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14123 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14124 &desc
, ¶m
, enum_surfaces_cb
);
14125 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14126 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14130 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
14131 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14132 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14134 IDirectDrawSurface_Release(param
.surfaces
[2]);
14135 IDirectDrawSurface_Release(param
.surfaces
[1]);
14136 IDirectDrawSurface_Release(param
.surfaces
[0]);
14139 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14140 NULL
, ¶m
, enum_surfaces_cb
);
14141 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14142 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14144 memset(&desc
, 0, sizeof(desc
));
14145 desc
.dwSize
= sizeof(desc
);
14146 desc
.dwFlags
= DDSD_CAPS
;
14147 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
14149 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
14150 &desc
, ¶m
, enum_surfaces_create_cb
);
14151 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14153 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
14154 &desc
, ¶m
, enum_surfaces_create_cb
);
14155 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14157 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
14158 &desc
, ¶m
, enum_surfaces_create_cb
);
14159 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14161 /* When not passed width and height, the callback is called with every
14162 * available display resolution. */
14164 param
.mode_count
= 0;
14165 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
14166 U4(desc
).ddpfPixelFormat
= current_format
;
14167 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
14168 ok(hr
== DD_OK
, "Failed to build mode list, hr %#lx.\n", hr
);
14171 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
14172 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14173 &desc
, ¶m
, enum_surfaces_create_cb
);
14174 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14175 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
14177 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
14178 desc
.dwWidth
= desc
.dwHeight
= 32;
14180 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
14183 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14184 &desc
, ¶m
, enum_surfaces_create_cb
);
14185 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14186 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14188 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
14189 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
14191 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14192 &desc
, ¶m
, enum_surfaces_create_cb
);
14193 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14194 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14195 IDirectDrawSurface2_Release(param
.surfaces
[0]);
14197 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
14198 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
14199 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
14200 desc
.ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
14203 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14204 &desc
, ¶m
, enum_surfaces_create_cb
);
14205 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14206 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14208 IDirectDraw2_Release(ddraw
);
14211 static void test_viewport(void)
14216 RECT expected_rect
;
14217 const char *message
;
14221 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
14222 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
14223 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
14224 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
14225 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
14226 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
14228 static const struct
14234 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
14236 static D3DMATRIX mat
=
14238 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14239 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14240 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14241 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14243 static D3DLVERTEX quad
[] =
14245 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14246 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14247 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14248 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14250 IDirect3DViewport2
*viewport
, *full_viewport
;
14251 IDirect3DMaterial2
*black_background
;
14252 IDirectDrawSurface
*rt
, *ds
;
14253 DDSURFACEDESC surface_desc
;
14254 IDirect3DDevice2
*device
;
14255 BOOL expected_failure
;
14256 IDirectDraw2
*ddraw
;
14257 DDPIXELFORMAT z_fmt
;
14258 D3DRECT clear_rect
;
14266 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14267 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
14268 ddraw
= create_ddraw();
14269 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14270 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14272 skip("Failed to create a 3D device, skipping test.\n");
14273 IDirectDraw2_Release(ddraw
);
14274 DestroyWindow(window
);
14278 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
14279 ok(SUCCEEDED(hr
), "Failed to get Direct3D2 interface, hr %#lx.\n", hr
);
14281 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
14282 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#lx.\n", hr
);
14283 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
14284 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
14286 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
14287 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14288 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
14289 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
14290 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
14291 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
14293 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
14295 ds
= get_depth_stencil(device
);
14296 memset(&surface_desc
, 0, sizeof(surface_desc
));
14297 surface_desc
.dwSize
= sizeof(surface_desc
);
14298 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &surface_desc
);
14299 z_fmt
= surface_desc
.ddpfPixelFormat
;
14301 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
14303 winetest_push_context("Size %ux%u", rt_sizes
[i
].x
, rt_sizes
[i
].y
);
14307 memset(&surface_desc
, 0, sizeof(surface_desc
));
14308 surface_desc
.dwSize
= sizeof(surface_desc
);
14309 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14310 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
14311 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
14312 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
14313 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
14314 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14316 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
14317 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14318 surface_desc
.ddpfPixelFormat
= z_fmt
;
14319 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
14320 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14321 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
14322 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14324 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
14325 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14329 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14330 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14333 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
14334 viewport_set_background(device
, full_viewport
, black_background
);
14336 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
14337 U3(clear_rect
).x2
= rt_sizes
[i
].x
;
14338 U4(clear_rect
).y2
= rt_sizes
[i
].y
;
14340 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
14342 winetest_push_context("%s", tests
[j
].message
);
14344 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
14345 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
14347 hr
= IDirect3DViewport2_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
14348 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14350 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
14351 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14352 hr
= IDirect3DViewport2_SetViewport2(viewport
, NULL
);
14353 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
14354 memset(&vp
, 0, sizeof(vp
));
14355 vp
.dwSize
= sizeof(vp
);
14356 vp
.dwX
= tests
[j
].vp
.dwX
;
14357 vp
.dwY
= tests
[j
].vp
.dwY
;
14358 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
14359 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
14360 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
14361 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
14364 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14365 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
14366 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
14367 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14368 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14369 ok(hr
== (expected_failure
? E_INVALIDARG
: DD_OK
), "Got unexpected hr %#lx.\n", hr
);
14371 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14372 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14373 if (expected_failure
)
14375 destroy_viewport(device
, viewport
);
14376 winetest_pop_context();
14380 hr
= IDirect3DDevice2_BeginScene(device
);
14381 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14382 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
14383 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14384 hr
= IDirect3DDevice2_EndScene(device
);
14385 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14387 check_rect(rt
, tests
[j
].expected_rect
);
14389 destroy_viewport(device
, viewport
);
14390 winetest_pop_context();
14393 destroy_viewport(device
, full_viewport
);
14395 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
14396 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx (i %u).\n", hr
, i
);
14397 IDirectDrawSurface_Release(ds
);
14399 IDirectDrawSurface_Release(rt
);
14401 winetest_pop_context();
14404 destroy_material(black_background
);
14405 refcount
= IDirect3DDevice2_Release(device
);
14406 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14407 IDirect3D2_Release(d3d
);
14408 IDirectDraw2_Release(ddraw
);
14409 DestroyWindow(window
);
14412 static void test_find_device(void)
14414 D3DFINDDEVICESEARCH search
= {0};
14415 D3DFINDDEVICERESULT result
= {0};
14416 IDirect3DDevice2
*device
;
14417 IDirectDraw2
*ddraw
;
14427 D3DDEVICEDESC_V1 hw_desc
;
14428 D3DDEVICEDESC_V1 sw_desc
;
14435 D3DDEVICEDESC_V2 hw_desc
;
14436 D3DDEVICEDESC_V2 sw_desc
;
14439 static const struct
14446 {&IID_IDirect3D
, DDERR_NOTFOUND
},
14447 {&IID_IDirect3DRampDevice
, D3D_OK
},
14448 {&IID_IDirect3DRGBDevice
, D3D_OK
},
14449 {&IID_IDirect3DMMXDevice
, D3D_OK
},
14450 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
14451 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
14452 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
14455 ddraw
= create_ddraw();
14456 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14458 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
14460 skip("D3D interface is not available, skipping test.\n");
14461 IDirectDraw2_Release(ddraw
);
14465 result
.dwSize
= sizeof(result
);
14466 search
.dwSize
= sizeof(search
);
14467 hr
= IDirect3D2_FindDevice(d3d
, NULL
, NULL
);
14468 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14469 hr
= IDirect3D2_FindDevice(d3d
, NULL
, &result
);
14470 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14471 hr
= IDirect3D2_FindDevice(d3d
, &search
, NULL
);
14472 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14473 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14474 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14475 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %lu.\n", result
.dwSize
);
14476 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14477 "Got unexpected HW desc size %lu.\n", result
.ddHwDesc
.dwSize
);
14478 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14479 "Got unexpected SW desc size %lu.\n", result
.ddSwDesc
.dwSize
);
14481 memset(&search
, 0, sizeof(search
));
14482 memset(&result
, 0, sizeof(result
));
14483 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14484 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14486 search
.dwSize
= sizeof(search
) + 1;
14487 result
.dwSize
= sizeof(result
) + 1;
14488 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14489 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14491 search
.dwSize
= sizeof(search
);
14493 memset(&result_v1
, 0, sizeof(result_v1
));
14494 result_v1
.size
= sizeof(result_v1
);
14495 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
14496 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14497 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14498 "Got unexpected HW desc size %lu.\n", result_v1
.hw_desc
.dwSize
);
14499 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14500 "Got unexpected SW desc size %lu.\n", result_v1
.sw_desc
.dwSize
);
14502 memset(&result_v2
, 0, sizeof(result_v2
));
14503 result_v2
.size
= sizeof(result_v2
);
14504 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
14505 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14506 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14507 "Got unexpected HW desc size %lu.\n", result_v2
.hw_desc
.dwSize
);
14508 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14509 "Got unexpected SW desc size %lu.\n", result_v2
.sw_desc
.dwSize
);
14511 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14513 memset(&search
, 0, sizeof(search
));
14514 search
.dwSize
= sizeof(search
);
14515 search
.dwFlags
= D3DFDS_GUID
;
14516 search
.guid
= *tests
[i
].guid
;
14518 memset(&result
, 0, sizeof(result
));
14519 result
.dwSize
= sizeof(result
);
14521 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14522 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
14523 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %lu.\n", i
, result
.dwSize
);
14526 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14527 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
14528 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14529 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
14533 ok(!result
.ddHwDesc
.dwSize
,
14534 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
14535 ok(!result
.ddSwDesc
.dwSize
,
14536 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
14540 /* The HAL device can only be enumerated if hardware acceleration is present. */
14541 search
.dwSize
= sizeof(search
);
14542 search
.dwFlags
= D3DFDS_GUID
;
14543 search
.guid
= IID_IDirect3DHALDevice
;
14544 result
.dwSize
= sizeof(result
);
14545 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14547 window
= create_window();
14548 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
14550 ok(!!device
, "Failed to create a 3D device.\n");
14552 ok(!device
, "Succeeded to create a 3D device.\n");
14554 IDirect3DDevice2_Release(device
);
14555 DestroyWindow(window
);
14557 /* Curiously the colour model criteria seem to be ignored. */
14558 search
.dwSize
= sizeof(search
);
14559 search
.dwFlags
= D3DFDS_COLORMODEL
;
14560 search
.dcmColorModel
= 0xdeadbeef;
14561 result
.dwSize
= sizeof(result
);
14562 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14563 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14565 IDirect3D2_Release(d3d
);
14566 IDirectDraw2_Release(ddraw
);
14569 static IDirectDraw2
*killfocus_ddraw
;
14570 static IDirectDrawSurface
*killfocus_surface
;
14572 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
14576 if (message
== WM_KILLFOCUS
)
14578 ref
= IDirectDrawSurface_Release(killfocus_surface
);
14579 ok(!ref
, "Unexpected surface refcount %lu.\n", ref
);
14580 ref
= IDirectDraw2_Release(killfocus_ddraw
);
14581 ok(!ref
, "Unexpected ddraw refcount %lu.\n", ref
);
14582 killfocus_ddraw
= NULL
;
14585 return DefWindowProcA(window
, message
, wparam
, lparam
);
14588 static void test_killfocus(void)
14590 DDSURFACEDESC surface_desc
;
14593 WNDCLASSA wc
= {0};
14595 wc
.lpfnWndProc
= killfocus_proc
;
14596 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
14597 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
14599 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
14600 0, 0, 640, 480, 0, 0, 0, 0);
14602 killfocus_ddraw
= create_ddraw();
14603 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
14605 hr
= IDirectDraw2_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
14606 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
14608 memset(&surface_desc
, 0, sizeof(surface_desc
));
14609 surface_desc
.dwSize
= sizeof(surface_desc
);
14610 surface_desc
.dwFlags
= DDSD_CAPS
;
14611 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14612 hr
= IDirectDraw2_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
14613 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
14615 SetForegroundWindow(GetDesktopWindow());
14616 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
14618 DestroyWindow(window
);
14619 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
14622 static void test_gdi_surface(void)
14624 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
14625 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
14626 DDSURFACEDESC surface_desc
;
14627 IDirectDraw2
*ddraw
;
14632 window
= create_window();
14633 ddraw
= create_ddraw();
14634 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14635 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14636 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14638 /* Retrieving the GDI surface requires a primary surface to exist. */
14639 gdi_surface
= (void *)0xc0dec0de;
14640 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14641 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14642 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
14644 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14645 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14647 memset(&surface_desc
, 0, sizeof(surface_desc
));
14648 surface_desc
.dwSize
= sizeof(surface_desc
);
14649 surface_desc
.dwFlags
= DDSD_CAPS
;
14650 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14651 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14652 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14654 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14655 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14656 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14657 IDirectDrawSurface_Release(gdi_surface
);
14659 /* Flipping to the GDI surface requires the primary surface to be
14661 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14662 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#lx.\n", hr
);
14664 IDirectDrawSurface_Release(primary
);
14666 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14667 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14669 memset(&surface_desc
, 0, sizeof(surface_desc
));
14670 surface_desc
.dwSize
= sizeof(surface_desc
);
14671 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14672 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
14673 U5(surface_desc
).dwBackBufferCount
= 1;
14674 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14675 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14676 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
14677 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14678 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
14680 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14681 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14682 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14683 IDirectDrawSurface_Release(gdi_surface
);
14685 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
14686 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14687 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14688 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14689 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
14690 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
14691 IDirectDrawSurface_Release(gdi_surface
);
14693 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14694 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14696 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14697 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14698 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14699 IDirectDrawSurface_Release(gdi_surface
);
14701 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14702 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14704 IDirectDrawSurface_Release(backbuffer
);
14705 IDirectDrawSurface_Release(primary
);
14707 refcount
= IDirectDraw2_Release(ddraw
);
14708 ok(!refcount
, "%lu references left.\n", refcount
);
14709 DestroyWindow(window
);
14712 static void test_alphatest(void)
14714 #define ALPHATEST_PASSED 0x0000ff00
14715 #define ALPHATEST_FAILED 0x00ff0000
14716 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
14717 IDirect3DMaterial2
*blue
, *failed
;
14718 IDirect3DViewport2
*viewport
;
14719 IDirect3DDevice2
*device
;
14720 IDirectDrawSurface
*rt
;
14721 unsigned int color
, i
;
14722 IDirectDraw2
*ddraw
;
14728 static const struct
14731 unsigned int color_less
, color_equal
, color_greater
;
14735 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14736 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14737 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14738 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14739 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14740 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14741 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14742 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14744 static D3DLVERTEX quad
[] =
14746 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14747 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14748 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14749 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14752 window
= create_window();
14753 ddraw
= create_ddraw();
14754 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14755 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14757 skip("Failed to create a 3D device.\n");
14758 IDirectDraw2_Release(ddraw
);
14759 DestroyWindow(window
);
14762 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14763 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14765 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
14766 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
14768 viewport
= create_viewport(device
, 0, 0, 640, 480);
14769 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14770 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14772 viewport_set_background(device
, viewport
, blue
);
14773 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14774 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14775 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14776 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14777 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
14778 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14779 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
14780 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14782 viewport_set_background(device
, viewport
, failed
);
14783 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
14785 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
14786 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14788 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14789 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14790 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
14791 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14792 hr
= IDirect3DDevice2_BeginScene(device
);
14793 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14794 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14795 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14796 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14797 hr
= IDirect3DDevice2_EndScene(device
);
14798 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14799 color
= get_surface_color(rt
, 320, 240);
14800 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14801 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14802 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14804 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14805 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14806 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
14807 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14808 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
14809 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14810 ok(value
== 0xff70, "Got unexpected value %#lx.\n", value
);
14811 hr
= IDirect3DDevice2_BeginScene(device
);
14812 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14813 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14814 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14815 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14816 hr
= IDirect3DDevice2_EndScene(device
);
14817 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14818 color
= get_surface_color(rt
, 320, 240);
14819 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14820 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14821 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14824 destroy_viewport(device
, viewport
);
14825 destroy_material(failed
);
14826 destroy_material(blue
);
14827 IDirectDrawSurface_Release(rt
);
14828 refcount
= IDirect3DDevice2_Release(device
);
14829 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14830 refcount
= IDirectDraw2_Release(ddraw
);
14831 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
14832 DestroyWindow(window
);
14835 static void test_clipper_refcount(void)
14837 IDirectDrawSurface
*surface
;
14838 IDirectDrawClipper
*clipper
, *clipper2
;
14839 DDSURFACEDESC surface_desc
;
14840 IDirectDraw2
*ddraw
;
14841 IDirectDraw
*ddraw1
;
14846 const IDirectDrawClipperVtbl
*orig_vtbl
;
14848 window
= create_window();
14849 ddraw
= create_ddraw();
14850 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14851 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14852 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14854 memset(&surface_desc
, 0, sizeof(surface_desc
));
14855 surface_desc
.dwSize
= sizeof(surface_desc
);
14856 surface_desc
.dwFlags
= DDSD_CAPS
;
14857 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14858 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14859 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14861 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14862 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14863 refcount
= get_refcount((IUnknown
*)clipper
);
14864 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14866 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
14868 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
14869 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14870 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
14871 clipper
->lpVtbl
, clipper2
->lpVtbl
);
14872 orig_vtbl
= clipper
->lpVtbl
;
14873 IDirectDrawClipper_Release(clipper2
);
14875 /* Surfaces hold a reference to clippers. No surprises there. */
14876 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14877 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14878 refcount
= get_refcount((IUnknown
*)clipper
);
14879 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14881 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14882 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
14883 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14884 refcount
= IDirectDrawClipper_Release(clipper2
);
14885 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14887 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
14888 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14889 refcount
= get_refcount((IUnknown
*)clipper
);
14890 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14892 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14893 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14894 refcount
= get_refcount((IUnknown
*)clipper
);
14895 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14897 refcount
= IDirectDrawSurface_Release(surface
);
14898 ok(!refcount
, "%lu references left.\n", refcount
);
14899 refcount
= get_refcount((IUnknown
*)clipper
);
14900 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14902 /* SetClipper with an invalid pointer crashes. */
14904 /* Clipper methods work with a broken vtable, with the exception of Release. */
14905 clipper
->lpVtbl
= (void *)0xdeadbeef;
14906 refcount
= orig_vtbl
->AddRef(clipper
);
14907 todo_wine
ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14908 refcount
= orig_vtbl
->Release(clipper
);
14909 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
14911 clipper
->lpVtbl
= orig_vtbl
;
14912 refcount
= orig_vtbl
->Release(clipper
);
14913 todo_wine
ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14915 /* Fix the refcount difference because Wine did not increase the ref in the
14916 * AddRef call above. */
14919 refcount
= IDirectDrawClipper_Release(clipper
);
14920 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
14923 /* Steal the reference and see what happens - releasing the surface works fine.
14924 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
14925 * release it after the GetClipper call is likely to crash, and certain to crash
14926 * if we allocate and zero as much heap memory as we can get. */
14927 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14928 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14929 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14930 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14931 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14932 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14934 IDirectDrawClipper_Release(clipper
);
14935 IDirectDrawClipper_Release(clipper
);
14939 /* Disabled because it causes heap corruption (HeapValidate fails and random
14940 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
14941 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
14942 * is affected too. Some testbot machines have crashes directly in GetClipper
14943 * or proceed with a corrupted heap too.
14945 * The same Windows and driver versions run the test without heap corruption on
14946 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
14947 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14948 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
14949 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14952 /* Show that invoking the Release method does not crash, but don't get the
14953 * vtable through the clipper pointer because it is no longer pointing to
14955 refcount
= orig_vtbl
->Release(clipper
);
14956 ok(!refcount
, "%lu references left.\n", refcount
);
14958 refcount
= IDirectDrawSurface_Release(surface
);
14959 ok(!refcount
, "%lu references left.\n", refcount
);
14961 /* It looks like the protection against invalid thispointers is part of
14962 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
14963 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
14964 ok(!!clipper
, "failed to allocate memory\n");
14966 /* Assigning the vtable to our fake clipper does NOT make a difference on
14967 * native - there is a different member of the clipper implementation struct
14968 * that is used to determine if a clipper is valid. */
14969 clipper
->lpVtbl
= orig_vtbl
;
14971 refcount
= orig_vtbl
->AddRef(clipper
);
14972 todo_wine
ok(!refcount
, "Got refcount %lu.\n", refcount
);
14973 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
14974 ok(!refcount
, "Got refcount %lu.\n", refcount
);
14977 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
14978 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14979 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14982 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
14983 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14984 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14986 /* Nope, we can't initialize our fake clipper. */
14987 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
14988 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#lx.\n", hr
);
14990 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
14991 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14993 IDirectDraw_Release(ddraw1
);
14995 HeapFree(GetProcessHeap(), 0, clipper
);
14997 refcount
= IDirectDraw2_Release(ddraw
);
14998 ok(!refcount
, "%lu references left.\n", refcount
);
14999 DestroyWindow(window
);
15002 static void test_caps(void)
15004 DWORD caps_never
, caps_always
, caps_hal
;
15005 DDCAPS hal_caps
, hel_caps
;
15006 IDirectDraw2
*ddraw
;
15007 IDirectDraw
*ddraw1
;
15011 caps_never
= DDSCAPS_RESERVED1
15013 | DDSCAPS_PRIMARYSURFACELEFT
15014 | DDSCAPS_SYSTEMMEMORY
15016 | DDSCAPS_WRITEONLY
15017 | DDSCAPS_LIVEVIDEO
15020 | DDSCAPS_RESERVED2
15023 | DDSCAPS_ALLOCONLOAD
15024 | DDSCAPS_VIDEOPORT
15025 | DDSCAPS_STANDARDVGAMODE
15026 | DDSCAPS_OPTIMIZED
;
15028 caps_always
= DDSCAPS_FLIP
15029 | DDSCAPS_OFFSCREENPLAIN
15030 | DDSCAPS_PRIMARYSURFACE
15035 caps_hal
= DDSCAPS_BACKBUFFER
15037 | DDSCAPS_FRONTBUFFER
15039 | DDSCAPS_VIDEOMEMORY
15040 | DDSCAPS_LOCALVIDMEM
15041 | DDSCAPS_NONLOCALVIDMEM
;
15043 ddraw
= create_ddraw();
15044 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15046 memset(&hal_caps
, 0, sizeof(hal_caps
));
15047 memset(&hel_caps
, 0, sizeof(hel_caps
));
15048 hal_caps
.dwSize
= sizeof(hal_caps
);
15049 hel_caps
.dwSize
= sizeof(hel_caps
);
15050 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15051 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15052 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15053 "Got unexpected caps %#lx, expected %#lx.\n",
15054 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15055 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15056 "Got unexpected caps %#lx, expected %#lx.\n",
15057 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15059 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
15060 if (hal_caps
.ddsCaps
.dwCaps
)
15062 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15063 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15064 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
15065 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15067 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15068 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15069 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15070 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15072 IDirectDraw2_Release(ddraw
);
15074 if (hal_caps
.ddsCaps
.dwCaps
)
15076 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw1
, NULL
);
15077 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15078 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
15079 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15080 IDirectDraw_Release(ddraw1
);
15082 memset(&hal_caps
, 0, sizeof(hal_caps
));
15083 memset(&hel_caps
, 0, sizeof(hel_caps
));
15084 hal_caps
.dwSize
= sizeof(hal_caps
);
15085 hel_caps
.dwSize
= sizeof(hel_caps
);
15086 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15087 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15088 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15089 "Got unexpected caps %#lx, expected %#lx.\n",
15090 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15091 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15092 "Got unexpected caps %#lx, expected %#lx.\n",
15093 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15095 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15096 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15097 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
15098 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15101 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15102 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15103 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15104 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15108 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15111 IDirectDraw2_Release(ddraw
);
15114 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw1
, NULL
);
15115 ok(hr
== DD_OK
|| (is_ddraw64
&& hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
15118 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
15119 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15120 IDirectDraw_Release(ddraw1
);
15122 memset(&hal_caps
, 0, sizeof(hal_caps
));
15123 memset(&hel_caps
, 0, sizeof(hel_caps
));
15124 hal_caps
.dwSize
= sizeof(hal_caps
);
15125 hel_caps
.dwSize
= sizeof(hel_caps
);
15126 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15127 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15128 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15129 "Got unexpected caps %#lx, expected %#lx.\n",
15130 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15131 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15132 "Got unexpected caps %#lx, expected %#lx.\n",
15133 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15135 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15136 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15137 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15138 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15139 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15141 IDirectDraw2_Release(ddraw
);
15145 static void test_d32_support(void)
15147 IDirectDrawSurface
*surface
;
15148 DDSURFACEDESC surface_desc
;
15149 IDirectDraw2
*ddraw
;
15154 window
= create_window();
15155 ddraw
= create_ddraw();
15156 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15157 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15158 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15160 memset(&surface_desc
, 0, sizeof(surface_desc
));
15161 surface_desc
.dwSize
= sizeof(surface_desc
);
15162 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
15163 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
15164 U2(surface_desc
).dwZBufferBitDepth
= 32;
15165 surface_desc
.dwWidth
= 64;
15166 surface_desc
.dwHeight
= 64;
15167 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15168 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15170 memset(&surface_desc
, 0, sizeof(surface_desc
));
15171 surface_desc
.dwSize
= sizeof(surface_desc
);
15172 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
15173 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15174 ok((surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "Got unexpected flags %#lx.\n", surface_desc
.dwFlags
);
15175 ok(U2(surface_desc
).dwZBufferBitDepth
== 32,
15176 "Got unexpected dwZBufferBitDepth %lu.\n", U2(surface_desc
).dwZBufferBitDepth
);
15177 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
15178 "Got unexpected surface caps %#lx.\n", surface_desc
.ddsCaps
.dwCaps
);
15179 IDirectDrawSurface_Release(surface
);
15181 refcount
= IDirectDraw2_Release(ddraw
);
15182 ok(!refcount
, "%lu references left.\n", refcount
);
15183 DestroyWindow(window
);
15186 struct find_different_mode_param
15188 unsigned int old_width
;
15189 unsigned int old_height
;
15190 unsigned int old_frequency
;
15191 unsigned int new_width
;
15192 unsigned int new_height
;
15193 unsigned int new_frequency
;
15194 unsigned int new_bpp
;
15197 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC
*surface_desc
, void *context
)
15199 struct find_different_mode_param
*param
= context
;
15201 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
15202 return DDENUMRET_OK
;
15204 /* See comment in ddraw7 about the frequency. */
15205 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
15206 (!compare_uint(surface_desc
->dwRefreshRate
, param
->old_frequency
, 1) || !param
->old_frequency
))
15208 param
->new_width
= surface_desc
->dwWidth
;
15209 param
->new_height
= surface_desc
->dwHeight
;
15210 param
->new_frequency
= surface_desc
->dwRefreshRate
;
15211 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
15212 return DDENUMRET_CANCEL
;
15215 return DDENUMRET_OK
;
15218 static void test_cursor_clipping(void)
15220 struct find_different_mode_param param
;
15221 DDSURFACEDESC surface_desc
;
15222 RECT rect
, clip_rect
;
15223 IDirectDraw2
*ddraw
;
15228 window
= create_window();
15229 ok(!!window
, "Failed to create a window.\n");
15230 ddraw
= create_ddraw();
15231 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15233 memset(&surface_desc
, 0, sizeof(surface_desc
));
15234 surface_desc
.dwSize
= sizeof(surface_desc
);
15235 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15236 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15238 memset(¶m
, 0, sizeof(param
));
15239 param
.old_width
= surface_desc
.dwWidth
;
15240 param
.old_height
= surface_desc
.dwHeight
;
15241 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
15242 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
15243 if (!(param
.new_width
&& param
.new_height
))
15245 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
15249 ret
= ClipCursor(NULL
);
15250 ok(ret
, "ClipCursor failed, error %lu.\n", GetLastError());
15251 get_virtual_rect(&rect
);
15252 ret
= GetClipCursor(&clip_rect
);
15253 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15254 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15255 wine_dbgstr_rect(&clip_rect
));
15257 /* Set cooperative level to normal */
15258 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15259 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15261 get_virtual_rect(&rect
);
15262 ret
= GetClipCursor(&clip_rect
);
15263 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15264 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15265 wine_dbgstr_rect(&clip_rect
));
15267 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15268 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15271 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
15275 get_virtual_rect(&rect
);
15276 ret
= GetClipCursor(&clip_rect
);
15277 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15278 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15279 wine_dbgstr_rect(&clip_rect
));
15281 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15282 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
15284 get_virtual_rect(&rect
);
15285 ret
= GetClipCursor(&clip_rect
);
15286 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15287 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15288 wine_dbgstr_rect(&clip_rect
));
15290 /* Switch to full screen cooperative level */
15291 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15292 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15294 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15295 ret
= GetClipCursor(&clip_rect
);
15296 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15297 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15298 wine_dbgstr_rect(&clip_rect
));
15300 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15301 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15304 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
15308 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
15309 ret
= GetClipCursor(&clip_rect
);
15310 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15311 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15312 wine_dbgstr_rect(&clip_rect
));
15314 /* Restore display mode */
15315 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15316 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
15318 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15319 ret
= GetClipCursor(&clip_rect
);
15320 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15321 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15322 wine_dbgstr_rect(&clip_rect
));
15324 /* Switch to normal cooperative level */
15325 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15326 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15328 get_virtual_rect(&rect
);
15329 ret
= GetClipCursor(&clip_rect
);
15330 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15331 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15332 wine_dbgstr_rect(&clip_rect
));
15335 IDirectDraw2_Release(ddraw
);
15336 DestroyWindow(window
);
15339 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15342 RECT primary_rect
, window_rect
, new_rect
;
15343 IDirectDraw2
*ddraw
;
15348 ddraw
= create_ddraw();
15349 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15350 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
15351 monitor_rect
->top
, monitor_rect
->right
- monitor_rect
->left
,
15352 monitor_rect
->bottom
- monitor_rect
->top
, NULL
, NULL
, NULL
, NULL
);
15353 ok(!!window
, "Failed to create a window.\n");
15356 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15357 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15359 ret
= GetWindowRect(window
, &window_rect
);
15360 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15361 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
15362 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15363 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15365 new_rect
= window_rect
;
15369 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
15370 new_rect
.bottom
- new_rect
.top
, TRUE
);
15371 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15372 ret
= GetWindowRect(window
, &window_rect
);
15373 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15374 ok(EqualRect(&window_rect
, &new_rect
),
15375 "Expected window rect %s, got %s.\n",
15376 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15377 /* After processing window events window rectangle gets restored. But only once, the size set
15378 * on the second resize remains. */
15380 ret
= GetWindowRect(window
, &window_rect
);
15381 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15382 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
15383 * it may get adjusted depending on window manager. */
15384 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
15385 "Expected window rect %s, got %s.\n",
15386 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15388 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
15389 new_rect
.bottom
- new_rect
.top
, TRUE
);
15390 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15391 ret
= GetWindowRect(window
, &window_rect
);
15392 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15393 ok(EqualRect(&window_rect
, &new_rect
),
15394 "Expected window rect %s, got %s.\n",
15395 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15397 ret
= GetWindowRect(window
, &window_rect
);
15398 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15399 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
15400 "Expected window rect %s, got %s.\n",
15401 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15403 /* Window activation should restore the window to fit the whole primary monitor */
15404 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15405 SWP_NOZORDER
| SWP_NOSIZE
);
15406 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
15407 ret
= SetForegroundWindow(GetDesktopWindow());
15408 ok(ret
, "Failed to set foreground window.\n");
15410 ret
= ShowWindow(window
, SW_RESTORE
);
15411 ok(ret
, "Failed to restore window, error %lu.\n", GetLastError());
15413 ret
= SetForegroundWindow(window
);
15414 ok(ret
, "SetForegroundWindow failed, error %lu.\n", GetLastError());
15416 ret
= GetWindowRect(window
, &window_rect
);
15417 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15418 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15419 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15421 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15422 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15423 ret
= GetWindowRect(window
, &window_rect
);
15424 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15425 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15426 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15428 DestroyWindow(window
);
15429 IDirectDraw2_Release(ddraw
);
15433 static void test_window_position(void)
15435 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
15438 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15441 DDSURFACEDESC surface_desc
;
15442 IDirectDraw2
*ddraw
;
15447 ddraw
= create_ddraw();
15448 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15449 window
= create_window();
15450 ok(!!window
, "Failed to create a window.\n");
15452 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
15453 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15454 SWP_NOZORDER
| SWP_NOSIZE
);
15455 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
15457 surface_desc
.dwSize
= sizeof(surface_desc
);
15458 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15459 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15460 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %lu.\n",
15461 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
15462 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %lu.\n",
15463 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
15465 DestroyWindow(window
);
15466 IDirectDraw2_Release(ddraw
);
15470 static void test_get_display_mode(void)
15472 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
15473 struct find_different_mode_param param
;
15474 DDSURFACEDESC surface_desc
;
15475 IDirectDraw2
*ddraw
;
15481 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
15483 ddraw
= create_ddraw();
15484 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15485 window
= create_window();
15486 ok(!!window
, "Failed to create a window.\n");
15488 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15489 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15491 memset(&devmode
, 0, sizeof(devmode
));
15492 devmode
.dmSize
= sizeof(devmode
);
15493 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
15494 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
15496 surface_desc
.dwSize
= sizeof(surface_desc
);
15497 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15498 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15499 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Got dwSize %lu.\n", surface_desc
.dwSize
);
15500 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#lx, got %#lx.\n", flags
,
15501 surface_desc
.dwFlags
);
15502 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %lu, got %lu.\n",
15503 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
15504 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %lu, got %lu.\n",
15505 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
15506 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %lu, got %lu.\n",
15507 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
15508 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
15509 "Got ddpfPixelFormat.dwSize %lu.\n", surface_desc
.ddpfPixelFormat
.dwSize
);
15510 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
15511 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
15512 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15513 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15514 "Expected pitch %lu, got %lu.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15515 surface_desc
.lPitch
);
15517 memset(¶m
, 0, sizeof(param
));
15518 param
.old_frequency
= surface_desc
.dwRefreshRate
;
15519 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
15520 find_different_mode_callback
);
15521 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
15522 if (!param
.new_frequency
)
15524 skip("Failed to find a display mode with a different frequency.\n");
15528 hr
= IDirectDraw2_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
15529 param
.new_frequency
, 0);
15530 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15531 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15532 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15533 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %lu.\n", param
.new_width
,
15534 surface_desc
.dwWidth
);
15535 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %lu.\n", param
.new_height
,
15536 surface_desc
.dwHeight
);
15537 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %lu.\n",
15538 param
.new_frequency
, surface_desc
.dwRefreshRate
);
15539 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
15540 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
15541 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15544 DestroyWindow(window
);
15545 IDirectDraw2_Release(ddraw
);
15548 static void test_texture_wrong_caps(const GUID
*device_guid
)
15550 static D3DLVERTEX quad
[] =
15552 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
15553 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
15554 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
15555 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
15557 static DDPIXELFORMAT fmt
=
15559 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
15560 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
15562 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
15563 unsigned int color
, expected_color
;
15564 IDirectDrawSurface
*surface
, *rt
;
15565 D3DTEXTUREHANDLE texture_handle
;
15566 IDirect3DMaterial2
*background
;
15567 IDirect3DViewport2
*viewport
;
15568 IDirect3DTexture2
*texture
;
15569 IDirect3DDevice2
*device
;
15570 IDirectDraw2
*ddraw
;
15571 DDSURFACEDESC ddsd
;
15576 window
= create_window();
15577 ddraw
= create_ddraw();
15578 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15579 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
15581 skip("Failed to create a 3D device, skipping test.\n");
15582 DestroyWindow(window
);
15585 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
15586 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15588 viewport
= create_viewport(device
, 0, 0, 640, 480);
15589 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
15590 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15592 memset(&ddsd
, 0, sizeof(ddsd
));
15593 ddsd
.dwSize
= sizeof(ddsd
);
15594 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
15595 ddsd
.dwHeight
= 16;
15597 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
15598 U4(ddsd
).ddpfPixelFormat
= fmt
;
15599 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
15600 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15601 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
15602 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15603 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
15604 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15606 fill_surface(surface
, 0xff00ff00);
15608 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
15609 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15610 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
15611 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15613 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
15614 viewport_set_background(device
, viewport
, background
);
15616 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
15617 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15618 if (is_software_device_type(device_guid
))
15619 fill_surface(rt
, 0xffff0000);
15621 hr
= IDirect3DDevice2_BeginScene(device
);
15622 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15623 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
15624 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15625 hr
= IDirect3DDevice2_EndScene(device
);
15626 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15628 expected_color
= is_software_device_type(device_guid
) ? 0x0000ff00 : 0x00ffffff;
15629 color
= get_surface_color(rt
, 320, 240);
15630 ok(compare_color(color
, expected_color
, 1), "Got color 0x%08x, expected 0x%08x.\n", color
, expected_color
);
15632 IDirect3DTexture2_Release(texture
);
15633 IDirectDrawSurface_Release(surface
);
15634 IDirectDrawSurface_Release(rt
);
15635 destroy_viewport(device
, viewport
);
15636 destroy_material(background
);
15637 IDirectDraw2_Release(ddraw
);
15638 refcount
= IDirect3DDevice2_Release(device
);
15639 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15640 DestroyWindow(window
);
15643 static void test_filling_convention(void)
15645 IDirectDrawSurface
*rt
, *backbuffer
, *cur
, *ds
;
15646 static const DWORD colour_bottom
= 0x00ffff00;
15647 static const DWORD colour_clear
= 0x000000ff;
15648 static const DWORD colour_right
= 0x00000000;
15649 static const DWORD colour_left
= 0x00ff0000;
15650 static const DWORD colour_top
= 0x0000ff00;
15651 unsigned int colour
, expected
, i
, j
, x
, y
;
15652 IDirect3DMaterial2
*background
;
15653 IDirect3DViewport2
*viewport
;
15654 IDirect3DDevice2
*device
;
15655 IDirectDraw2
*ddraw
;
15656 DDSURFACEDESC desc
;
15663 static const unsigned int vp_size
= 8;
15664 D3DRECT clear_rect
= {{0}, {0}, {vp_size
}, {vp_size
}};
15666 /* This test data follows the examples in MSDN's
15667 * "Rasterization Rules (Direct3D 9)" article.
15669 * See the d3d9 test for a comment about the eps value. */
15670 static const float eps
= 1.0f
/ 64.0f
;
15671 D3DLVERTEX center_tris
[] =
15674 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15675 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15676 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15679 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15680 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15681 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15684 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15685 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15686 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15689 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15690 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15691 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15696 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15697 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15698 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15701 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15702 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15703 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15706 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15707 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15708 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15711 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15712 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15713 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15715 nudge_right_tris
[] =
15718 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15719 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15720 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15723 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15724 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15725 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15728 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15729 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15730 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15733 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15734 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15735 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15737 nudge_left_tris
[] =
15739 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15740 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15741 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15744 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15745 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15746 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15749 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15750 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15751 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15754 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15755 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15756 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15761 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15762 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15763 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15766 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15767 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15768 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15771 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15772 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15773 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15776 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15777 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15778 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15780 nudge_bottom_tris
[] =
15783 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15784 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15785 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15788 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15789 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15790 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15793 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15794 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15795 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15798 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15799 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15800 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15803 D3DTLVERTEX center_tris_t
[] =
15806 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15807 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15808 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15811 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15812 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15813 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15816 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15817 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15818 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15821 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15822 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15823 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15828 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15829 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15830 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15833 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15834 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15835 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15838 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15839 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15840 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15843 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15844 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15845 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15852 const char *expected
[8];
15970 window
= create_window();
15971 ddraw
= create_ddraw();
15972 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15973 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
15975 skip("Failed to create a 3D device.\n");
15976 IDirectDraw2_Release(ddraw
);
15977 DestroyWindow(window
);
15981 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
15982 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15983 hr
= IDirect3DDevice2_GetRenderTarget(device
, &backbuffer
);
15984 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15986 viewport
= create_viewport(device
, 0, 0, vp_size
, vp_size
);
15987 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
15988 viewport_set_background(device
, viewport
, background
);
15989 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
15990 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15992 memset(&desc
, 0, sizeof(desc
));
15993 desc
.dwSize
= sizeof(desc
);
15994 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
15995 desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
15996 desc
.dwWidth
= vp_size
;
15997 desc
.dwHeight
= vp_size
;
15998 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
15999 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
16000 desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
16001 desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
16002 desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
16003 desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
16004 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, &rt
, NULL
);
16005 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16007 /* Nvidia on Windows 10 refuses to set the offscreen RT
16008 * if it does not have an attached depth stencil. */
16009 ds
= get_depth_stencil(device
);
16010 memset(&desc
, 0, sizeof(desc
));
16011 desc
.dwSize
= sizeof(desc
);
16012 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
16013 hr
= IDirectDrawSurface_GetPixelFormat(ds
, &desc
.ddpfPixelFormat
);
16014 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16015 IDirectDrawSurface4_Release(ds
);
16017 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16018 desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16019 desc
.dwWidth
= vp_size
;
16020 desc
.dwHeight
= vp_size
;
16021 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, &ds
, NULL
);
16022 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16023 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
16024 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
16026 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16027 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16028 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
16029 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16031 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16033 for (j
= 0; j
< 2; ++j
)
16035 cur
= j
? rt
: backbuffer
;
16037 hr
= IDirect3DDevice2_SetRenderTarget(device
, cur
, 0);
16038 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16039 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
16040 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16042 hr
= IDirect3DDevice2_BeginScene(device
);
16043 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16044 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLELIST
,
16045 tests
[i
].fvf
, tests
[i
].geometry
, 12, 0);
16046 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16047 hr
= IDirect3DDevice2_EndScene(device
);
16048 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16050 for (y
= 0; y
< 8; y
++)
16052 for (x
= 0; x
< 8; x
++)
16055 switch (tests
[i
].expected
[y
][x
])
16057 case 'l': todo
= TRUE
;
16059 expected
= colour_left
;
16061 case 't': todo
= TRUE
;
16063 expected
= colour_top
;
16065 case 'r': todo
= TRUE
;
16067 expected
= colour_right
;
16069 case 'b': todo
= TRUE
;
16071 expected
= colour_bottom
;
16074 expected
= colour_clear
;
16077 ok(0, "Unexpected entry in expected test char\n");
16078 expected
= 0xdeadbeef;
16080 colour
= get_surface_color(cur
, x
, y
);
16081 /* The nudge-to-bottom test fails on cards that give us a bottom-left
16082 * filling convention. The cause isn't the bottom part of the filling
16083 * convention, but because wined3d will nudge geometry to the left to
16084 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
16085 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
16086 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
16087 colour
, x
, y
, i
, j
);
16093 destroy_viewport(device
, viewport
);
16094 IDirectDrawSurface_Release(backbuffer
);
16095 IDirectDrawSurface_Release(rt
);
16096 IDirectDrawSurface_Release(ds
);
16097 IDirect3D2_Release(d3d
);
16098 refcount
= IDirect3DDevice2_Release(device
);
16099 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16100 refcount
= IDirectDraw2_Release(ddraw
);
16101 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16102 DestroyWindow(window
);
16105 static HRESULT WINAPI
test_enum_devices_caps_callback(GUID
*guid
, char *device_desc
,
16106 char *device_name
, D3DDEVICEDESC
*hal
, D3DDEVICEDESC
*hel
, void *ctx
)
16108 if(IsEqualGUID(&IID_IDirect3DRGBDevice
, guid
))
16110 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16111 "RGB Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16112 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16113 "RGB Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16114 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16115 "RGB Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16116 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16117 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16119 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16120 "RGB Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16121 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16122 "RGB Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16123 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16124 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16125 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16126 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16128 ok(hal
->dcmColorModel
== 0, "RGB Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16129 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "RGB Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16131 ok(hal
->dwFlags
== 0, "RGB Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16132 ok(hel
->dwFlags
!= 0, "RGB Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16134 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16135 "RGB Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16136 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16137 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16138 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16139 "RGB Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16140 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16141 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16143 else if(IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
16145 ok(hal
->dcmColorModel
== D3DCOLOR_RGB
, "HAL Device hal caps has colormodel %lu\n", hel
->dcmColorModel
);
16146 ok(hel
->dcmColorModel
== 0, "HAL Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16148 ok(hal
->dwFlags
!= 0, "HAL Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16149 ok(hel
->dwFlags
!= 0, "HAL Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16151 ok(hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
,
16152 "HAL Device hal device caps does not have D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16153 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16154 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16155 ok(hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
,
16156 "HAL Device hal device caps does not have D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16157 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16158 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16160 else if(IsEqualGUID(&IID_IDirect3DRefDevice
, guid
))
16162 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16163 "REF Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16164 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16165 "REF Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16166 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16167 "REF Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16168 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16169 "REF Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16171 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16172 "REF Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16173 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16174 "REF Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16175 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16176 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16177 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16178 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16180 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16181 "REF Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16182 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16183 "REF Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16184 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16185 "REF Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16186 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16187 "REF Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16189 else if(IsEqualGUID(&IID_IDirect3DRampDevice
, guid
))
16191 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16192 "Ramp Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16193 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16194 "Ramp Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16195 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16196 "Ramp Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16197 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16198 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16200 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16201 "Ramp Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16202 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16203 "Ramp Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16204 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16205 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16206 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16207 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16209 ok(hal
->dcmColorModel
== 0, "Ramp Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16210 ok(hel
->dcmColorModel
== D3DCOLOR_MONO
, "Ramp Device hel caps has colormodel %lu\n",
16211 hel
->dcmColorModel
);
16213 ok(hal
->dwFlags
== 0, "Ramp Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16214 ok(hel
->dwFlags
!= 0, "Ramp Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16216 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16217 "Ramp Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16218 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16219 "Ramp Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16220 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16221 "Ramp Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16222 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16223 "Ramp Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16225 else if(IsEqualGUID(&IID_IDirect3DMMXDevice
, guid
))
16227 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16228 "MMX Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16229 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16230 "MMX Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16231 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16232 "MMX Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16233 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16234 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16236 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16237 "MMX Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16238 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16239 "MMX Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16240 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16241 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16242 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16243 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16245 ok(hal
->dcmColorModel
== 0, "MMX Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16246 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "MMX Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16248 ok(hal
->dwFlags
== 0, "MMX Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16249 ok(hel
->dwFlags
!= 0, "MMX Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16251 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16252 "MMX Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16253 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16254 "MMX Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16255 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16256 "MMX Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16257 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16258 "MMX Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16262 ok(FALSE
, "Unexpected device enumerated: \"%s\" \"%s\"\n", device_desc
, device_name
);
16263 if (hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16264 trace("hal line has pow2 set\n");
16266 trace("hal line does NOT have pow2 set\n");
16267 if (hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16268 trace("hal tri has pow2 set\n");
16270 trace("hal tri does NOT have pow2 set\n");
16271 if (hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16272 trace("hel line has pow2 set\n");
16274 trace("hel line does NOT have pow2 set\n");
16275 if (hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16276 trace("hel tri has pow2 set\n");
16278 trace("hel tri does NOT have pow2 set\n");
16281 return DDENUMRET_OK
;
16284 static void test_enum_devices(void)
16286 IDirectDraw2
*ddraw
;
16291 ddraw
= create_ddraw();
16292 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16294 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
16297 skip("D3D interface is not available, skipping test.\n");
16298 IDirectDraw2_Release(ddraw
);
16302 hr
= IDirect3D2_EnumDevices(d3d
, NULL
, NULL
);
16303 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
16305 hr
= IDirect3D2_EnumDevices(d3d
, test_enum_devices_caps_callback
, NULL
);
16306 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
16308 IDirect3D2_Release(d3d
);
16309 refcount
= IDirectDraw2_Release(ddraw
);
16310 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16313 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
16315 test_func(&IID_IDirect3DHALDevice
);
16316 test_func(&IID_IDirect3DRGBDevice
);
16321 DDDEVICEIDENTIFIER identifier
;
16322 DEVMODEW current_mode
;
16323 IDirectDraw2
*ddraw
;
16326 if (!(ddraw
= create_ddraw()))
16328 skip("Failed to create a ddraw object, skipping tests.\n");
16332 if (ddraw_get_identifier(ddraw
, &identifier
))
16334 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
16335 trace("Description string: \"%s\"\n", identifier
.szDescription
);
16336 trace("Driver version %d.%d.%d.%d\n",
16337 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
16338 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
16340 IDirectDraw2_Release(ddraw
);
16342 memset(¤t_mode
, 0, sizeof(current_mode
));
16343 current_mode
.dmSize
= sizeof(current_mode
);
16344 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
16345 registry_mode
.dmSize
= sizeof(registry_mode
);
16346 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
16347 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
16348 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
16350 skip("Current mode does not match registry mode, skipping test.\n");
16354 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
16355 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
16357 test_coop_level_create_device_window();
16358 test_clipper_blt();
16359 test_coop_level_d3d_state();
16360 test_surface_interface_mismatch();
16361 test_coop_level_threaded();
16362 run_for_each_device_type(test_depth_blit
);
16363 test_texture_load_ckey();
16364 test_viewport_object();
16365 run_for_each_device_type(test_zenable
);
16366 run_for_each_device_type(test_ck_rgba
);
16372 test_window_style();
16373 test_redundant_mode_set();
16374 test_coop_level_mode_set();
16375 test_coop_level_mode_set_multi();
16377 test_coop_level_surf_create();
16378 test_coop_level_multi_window();
16379 test_clear_rect_count();
16380 test_coop_level_versions();
16381 test_lighting_interface_versions();
16382 test_coop_level_activateapp();
16383 test_unsupported_formats();
16384 run_for_each_device_type(test_rt_caps
);
16385 test_primary_caps();
16386 test_surface_lock();
16387 test_surface_discard();
16389 test_set_surface_desc();
16390 test_user_memory_getdc();
16391 test_sysmem_overlay();
16392 test_primary_palette();
16393 test_surface_attachment();
16394 test_pixel_format();
16395 test_create_surface_pitch();
16397 test_palette_complex();
16401 test_specular_lighting();
16402 test_palette_gdi();
16403 test_palette_alpha();
16404 test_lost_device();
16405 test_surface_desc_lock();
16406 test_texturemapblend();
16407 test_viewport_clear_rect();
16409 test_colorkey_precision();
16410 test_range_colorkey();
16412 test_lockrect_invalid();
16413 test_yv12_overlay();
16414 test_offscreen_overlay();
16415 test_overlay_rect();
16417 test_blt_z_alpha();
16418 test_cross_device_blt();
16420 test_draw_primitive();
16421 test_edge_antialiasing_blending();
16422 test_transform_vertices();
16423 test_display_mode_surface_pixel_format();
16424 test_surface_desc_size();
16425 test_ck_operation();
16426 test_set_render_state();
16427 test_depth_readback();
16429 test_enum_surfaces();
16431 test_find_device();
16433 test_gdi_surface();
16435 test_clipper_refcount();
16437 test_d32_support();
16438 test_cursor_clipping();
16439 test_window_position();
16440 test_get_display_mode();
16441 run_for_each_device_type(test_texture_wrong_caps
);
16442 test_filling_convention();
16443 test_enum_devices();