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"
30 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
31 static DEVMODEW registry_mode
;
33 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
45 struct create_window_thread_param
48 HANDLE window_created
;
49 HANDLE destroy_window
;
53 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
55 unsigned int diff
= x
> y
? x
- y
: y
- x
;
57 return diff
<= max_diff
;
60 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
70 return compare_uint(x
, y
, ulps
);
73 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
75 return compare_float(vec
->x
, x
, ulps
)
76 && compare_float(vec
->y
, y
, ulps
)
77 && compare_float(vec
->z
, z
, ulps
)
78 && compare_float(vec
->w
, w
, ulps
);
81 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
83 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
84 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
85 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
86 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
89 static void get_virtual_rect(RECT
*rect
)
91 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
92 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
93 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
94 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
97 /* Try to make sure pending X events have been processed before continuing */
98 static void flush_events(void)
104 time
= GetTickCount() + diff
;
107 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
109 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
110 DispatchMessageA(&msg
);
111 diff
= time
- GetTickCount();
115 static BOOL
ddraw_get_identifier(IDirectDraw2
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
117 IDirectDraw4
*ddraw4
;
120 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
121 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#lx.\n", hr
);
122 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
123 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#lx.\n", hr
);
124 IDirectDraw4_Release(ddraw4
);
126 return SUCCEEDED(hr
);
129 static BOOL
ddraw_is_warp(IDirectDraw2
*ddraw
)
131 DDDEVICEIDENTIFIER identifier
;
133 return strcmp(winetest_platform
, "wine")
134 && ddraw_get_identifier(ddraw
, &identifier
)
135 && strstr(identifier
.szDriver
, "warp");
138 static BOOL
ddraw_is_vendor(IDirectDraw2
*ddraw
, DWORD vendor
)
140 DDDEVICEIDENTIFIER identifier
;
142 return strcmp(winetest_platform
, "wine")
143 && ddraw_get_identifier(ddraw
, &identifier
)
144 && identifier
.dwVendorId
== vendor
;
147 static BOOL
ddraw_is_amd(IDirectDraw2
*ddraw
)
149 return ddraw_is_vendor(ddraw
, 0x1002);
152 static BOOL
ddraw_is_intel(IDirectDraw2
*ddraw
)
154 return ddraw_is_vendor(ddraw
, 0x8086);
157 static BOOL
ddraw_is_nvidia(IDirectDraw2
*ddraw
)
159 return ddraw_is_vendor(ddraw
, 0x10de);
162 static BOOL
ddraw_is_vmware(IDirectDraw2
*ddraw
)
164 return ddraw_is_vendor(ddraw
, 0x15ad);
167 static BOOL
is_software_device_type(const GUID
*device_guid
)
169 return device_guid
!= &IID_IDirect3DHALDevice
;
172 static IDirectDrawSurface
*create_overlay(IDirectDraw2
*ddraw
,
173 unsigned int width
, unsigned int height
, DWORD format
)
175 IDirectDrawSurface
*surface
;
178 memset(&desc
, 0, sizeof(desc
));
179 desc
.dwSize
= sizeof(desc
);
180 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
181 desc
.dwWidth
= width
;
182 desc
.dwHeight
= height
;
183 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
184 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
185 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
186 desc
.ddpfPixelFormat
.dwFourCC
= format
;
188 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
193 static HWND
create_window(void)
195 RECT r
= {0, 0, 640, 480};
197 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
199 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
200 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
203 static DWORD WINAPI
create_window_thread_proc(void *param
)
205 struct create_window_thread_param
*p
= param
;
209 p
->window
= create_window();
210 ret
= SetEvent(p
->window_created
);
211 ok(ret
, "SetEvent failed, last error %lu.\n", GetLastError());
217 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
218 DispatchMessageA(&msg
);
219 res
= WaitForSingleObject(p
->destroy_window
, 100);
220 if (res
== WAIT_OBJECT_0
)
222 if (res
!= WAIT_TIMEOUT
)
224 ok(0, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
229 DestroyWindow(p
->window
);
234 static void create_window_thread(struct create_window_thread_param
*p
)
238 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
239 ok(!!p
->window_created
, "CreateEvent failed, last error %lu.\n", GetLastError());
240 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
241 ok(!!p
->destroy_window
, "CreateEvent failed, last error %lu.\n", GetLastError());
242 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
243 ok(!!p
->thread
, "Failed to create thread, last error %lu.\n", GetLastError());
244 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
245 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
248 static void destroy_window_thread(struct create_window_thread_param
*p
)
250 SetEvent(p
->destroy_window
);
251 WaitForSingleObject(p
->thread
, INFINITE
);
252 CloseHandle(p
->destroy_window
);
253 CloseHandle(p
->window_created
);
254 CloseHandle(p
->thread
);
257 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice2
*device
)
259 IDirectDrawSurface
*rt
, *ret
;
260 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
263 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
264 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
265 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
266 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#lx.\n", hr
);
267 IDirectDrawSurface_Release(rt
);
271 /* Free original_modes after finished using it */
272 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
274 unsigned int number
, size
= 2, count
= 0, index
= 0;
275 DISPLAY_DEVICEW display_device
;
276 DEVMODEW
*modes
, *tmp
;
278 if (!(modes
= malloc(size
* sizeof(*modes
))))
281 display_device
.cb
= sizeof(display_device
);
282 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
284 /* Skip software devices */
285 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
288 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
294 if (!(tmp
= realloc(modes
, size
* sizeof(*modes
))))
302 memset(&modes
[count
], 0, sizeof(modes
[count
]));
303 modes
[count
].dmSize
= sizeof(modes
[count
]);
304 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
310 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
313 *original_modes
= modes
;
314 *display_count
= count
;
318 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
323 for (index
= 0; index
< count
; ++index
)
325 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
326 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
327 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
330 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
331 return ret
== DISP_CHANGE_SUCCESSFUL
;
334 static HRESULT
set_display_mode(IDirectDraw2
*ddraw
, DWORD width
, DWORD height
)
336 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
338 return IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
341 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
343 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
344 DDSURFACEDESC surface_desc
;
348 memset(&surface_desc
, 0, sizeof(surface_desc
));
349 surface_desc
.dwSize
= sizeof(surface_desc
);
351 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
352 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
356 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
358 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
359 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
364 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
366 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
371 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
372 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
374 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
376 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* surface_desc
.lPitch
);
377 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
383 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
384 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
387 static void check_rect(IDirectDrawSurface
*surface
, RECT r
)
389 LONG x_coords
[2][2] =
391 {r
.left
- 1, r
.left
+ 1},
392 {r
.right
+ 1, r
.right
- 1},
394 LONG y_coords
[2][2] =
396 {r
.top
- 1, r
.top
+ 1},
397 {r
.bottom
+ 1, r
.bottom
- 1}
399 unsigned int i
, j
, x_side
, y_side
, color
;
402 for (i
= 0; i
< 2; ++i
)
404 for (j
= 0; j
< 2; ++j
)
406 for (x_side
= 0; x_side
< 2; ++x_side
)
408 for (y_side
= 0; y_side
< 2; ++y_side
)
410 unsigned int expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
412 x
= x_coords
[i
][x_side
];
413 y
= y_coords
[j
][y_side
];
414 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
416 color
= get_surface_color(surface
, x
, y
);
417 ok(color
== expected
, "Pixel (%ld, %ld) has color %08x, expected %08x.\n", x
, y
, color
, expected
);
424 static DWORD
get_device_z_depth(IDirect3DDevice2
*device
)
426 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
427 IDirectDrawSurface
*ds
, *rt
;
431 if (FAILED(IDirect3DDevice2_GetRenderTarget(device
, &rt
)))
434 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
435 IDirectDrawSurface_Release(rt
);
439 desc
.dwSize
= sizeof(desc
);
440 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
441 IDirectDrawSurface_Release(ds
);
445 return desc
.dwZBufferBitDepth
;
448 static IDirectDraw2
*create_ddraw(void)
450 IDirectDraw2
*ddraw2
;
454 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
457 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
458 IDirectDraw_Release(ddraw1
);
465 static IDirect3DDevice2
*create_device_ex(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
, const GUID
*device_guid
,
466 IDirectDrawSurface
**ret_surface
)
468 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
469 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
470 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
472 static const DWORD z_depths
[] = {16, 32, 24};
473 IDirectDrawSurface
*surface
, *ds
;
474 IDirect3DDevice2
*device
= NULL
;
475 DDSURFACEDESC surface_desc
;
480 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, coop_level
);
481 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
483 memset(&surface_desc
, 0, sizeof(surface_desc
));
484 surface_desc
.dwSize
= sizeof(surface_desc
);
485 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
486 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
487 if (is_software_device_type(device_guid
))
488 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
489 surface_desc
.dwWidth
= 640;
490 surface_desc
.dwHeight
= 480;
492 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
493 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
495 if (coop_level
& DDSCL_NORMAL
)
497 IDirectDrawClipper
*clipper
;
499 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
500 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
501 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
502 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
503 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
504 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#lx.\n", hr
);
505 IDirectDrawClipper_Release(clipper
);
508 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
511 IDirectDrawSurface_Release(surface
);
515 /* We used to use EnumDevices() for this, but it seems
516 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
517 * relationship with reality. */
518 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
520 memset(&surface_desc
, 0, sizeof(surface_desc
));
521 surface_desc
.dwSize
= sizeof(surface_desc
);
522 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
523 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
524 if (is_software_device_type(device_guid
))
525 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
526 surface_desc
.dwZBufferBitDepth
= z_depths
[i
];
527 surface_desc
.dwWidth
= 640;
528 surface_desc
.dwHeight
= 480;
529 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
532 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
533 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
534 IDirectDrawSurface_Release(ds
);
538 if (SUCCEEDED(IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
)))
541 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
544 IDirect3D2_Release(d3d
);
546 *ret_surface
= surface
;
548 IDirectDrawSurface_Release(surface
);
553 static IDirect3DDevice2
*create_device(IDirectDraw2
*ddraw
, HWND window
, DWORD coop_level
)
555 return create_device_ex(ddraw
, window
, coop_level
, &IID_IDirect3DHALDevice
, NULL
);
558 static IDirect3DViewport2
*create_viewport(IDirect3DDevice2
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
560 IDirect3DViewport2
*viewport
;
565 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
566 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
567 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
568 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
569 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
570 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
571 memset(&vp
, 0, sizeof(vp
));
572 vp
.dwSize
= sizeof(vp
);
579 vp
.dvClipWidth
= 2.0f
;
580 vp
.dvClipHeight
= 2.0f
;
583 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp
);
584 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
585 IDirect3D2_Release(d3d
);
590 static void viewport_set_background(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
,
591 IDirect3DMaterial2
*material
)
593 D3DMATERIALHANDLE material_handle
;
596 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
597 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
598 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
599 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
602 static void destroy_viewport(IDirect3DDevice2
*device
, IDirect3DViewport2
*viewport
)
606 hr
= IDirect3DDevice2_DeleteViewport(device
, viewport
);
607 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
608 IDirect3DViewport2_Release(viewport
);
611 static IDirect3DMaterial2
*create_material(IDirect3DDevice2
*device
, D3DMATERIAL
*mat
)
613 IDirect3DMaterial2
*material
;
617 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
618 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
619 hr
= IDirect3D2_CreateMaterial(d3d
, &material
, NULL
);
620 ok(SUCCEEDED(hr
), "Failed to create material, hr %#lx.\n", hr
);
621 hr
= IDirect3DMaterial2_SetMaterial(material
, mat
);
622 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
623 IDirect3D2_Release(d3d
);
628 static IDirect3DMaterial2
*create_diffuse_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
632 memset(&mat
, 0, sizeof(mat
));
633 mat
.dwSize
= sizeof(mat
);
639 return create_material(device
, &mat
);
642 static IDirect3DMaterial2
*create_diffuse_and_ambient_material(IDirect3DDevice2
*device
,
643 float r
, float g
, float b
, float a
)
647 memset(&mat
, 0, sizeof(mat
));
648 mat
.dwSize
= sizeof(mat
);
659 return create_material(device
, &mat
);
662 static IDirect3DMaterial2
*create_specular_material(IDirect3DDevice2
*device
,
663 float r
, float g
, float b
, float a
, float power
)
667 memset(&mat
, 0, sizeof(mat
));
668 mat
.dwSize
= sizeof(mat
);
675 return create_material(device
, &mat
);
678 static IDirect3DMaterial2
*create_emissive_material(IDirect3DDevice2
*device
, float r
, float g
, float b
, float a
)
682 memset(&mat
, 0, sizeof(mat
));
683 mat
.dwSize
= sizeof(mat
);
689 return create_material(device
, &mat
);
692 static void destroy_material(IDirect3DMaterial2
*material
)
694 IDirect3DMaterial2_Release(material
);
701 WPARAM expect_wparam
;
704 static const struct message
*expect_messages
;
706 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
708 if (expect_messages
&& message
== expect_messages
->message
)
710 if (expect_messages
->check_wparam
)
711 ok (wparam
== expect_messages
->expect_wparam
,
712 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
713 wparam
, message
, expect_messages
->expect_wparam
);
718 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
721 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
722 * interface. This prevents subsequent SetCooperativeLevel() calls on a
723 * different window from failing with DDERR_HWNDALREADYSET. */
724 static void fix_wndproc(HWND window
, LONG_PTR proc
)
729 if (!(ddraw
= create_ddraw()))
732 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
733 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
734 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
735 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
736 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
738 IDirectDraw2_Release(ddraw
);
741 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
743 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
744 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#lx.\n", hr
);
745 IDirectDrawSurface_Release(surface
);
750 static HRESULT
restore_surfaces(IDirectDraw2
*ddraw
)
752 return IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
753 NULL
, NULL
, restore_callback
);
756 static void test_coop_level_create_device_window(void)
758 HWND focus_window
, device_window
;
762 focus_window
= create_window();
763 ddraw
= create_ddraw();
764 ok(!!ddraw
, "Failed to create a ddraw object.\n");
766 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
767 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
768 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
769 ok(!device_window
, "Unexpected device window found.\n");
770 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
771 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
772 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
773 ok(!device_window
, "Unexpected device window found.\n");
774 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
775 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
776 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
777 ok(!device_window
, "Unexpected device window found.\n");
778 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
779 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
780 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
781 ok(!device_window
, "Unexpected device window found.\n");
782 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
783 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#lx.\n", hr
);
784 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
785 ok(!device_window
, "Unexpected device window found.\n");
787 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
788 if (broken(hr
== DDERR_INVALIDPARAMS
))
790 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
791 IDirectDraw2_Release(ddraw
);
792 DestroyWindow(focus_window
);
796 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
797 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
798 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
799 ok(!device_window
, "Unexpected device window found.\n");
800 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
801 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
802 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
803 ok(!device_window
, "Unexpected device window found.\n");
805 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
806 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
807 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
808 ok(!device_window
, "Unexpected device window found.\n");
809 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
810 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
811 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#lx.\n", hr
);
812 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
813 ok(!!device_window
, "Device window not found.\n");
815 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
816 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
817 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
818 ok(!device_window
, "Unexpected device window found.\n");
819 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
820 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
821 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
822 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
823 ok(!!device_window
, "Device window not found.\n");
825 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
826 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
827 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
828 ok(!device_window
, "Unexpected device window found.\n");
829 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
830 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#lx.\n", hr
);
831 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
832 ok(!device_window
, "Unexpected device window found.\n");
833 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
834 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
835 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
836 ok(!device_window
, "Unexpected device window found.\n");
837 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
838 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
839 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
840 ok(!!device_window
, "Device window not found.\n");
842 IDirectDraw2_Release(ddraw
);
843 DestroyWindow(focus_window
);
846 static void test_clipper_blt(void)
848 IDirectDrawSurface
*src_surface
, *dst_surface
;
849 unsigned int color
, i
, j
, x
, y
;
850 RECT client_rect
, src_rect
;
851 IDirectDrawClipper
*clipper
;
852 DDSURFACEDESC surface_desc
;
863 static const DWORD src_data
[] =
865 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
866 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
867 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
869 static const unsigned int expected1
[] =
871 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
872 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
873 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
874 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
876 /* Nvidia on Windows seems to have an off-by-one error
877 * when processing source rectangles. Our left = 1 and
878 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
879 * read as well, but only for the edge pixels on the
880 * output image. The bug happens on the y axis as well,
881 * but we only read one row there, and all source rows
882 * contain the same data. This bug is not dependent on
883 * the presence of a clipper. */
884 static const D3DCOLOR expected1_broken
[] =
886 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
887 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
888 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
889 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
891 static const unsigned int expected2
[] =
893 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
894 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
895 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
896 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
899 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
900 10, 10, 640, 480, 0, 0, 0, 0);
901 ShowWindow(window
, SW_SHOW
);
902 ddraw
= create_ddraw();
903 ok(!!ddraw
, "Failed to create a ddraw object.\n");
905 ret
= GetClientRect(window
, &client_rect
);
906 ok(ret
, "Failed to get client rect.\n");
907 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
908 ok(ret
, "Failed to map client rect.\n");
910 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
911 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
913 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
914 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
915 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
916 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
917 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
918 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
919 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
920 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
921 rgn_data
= malloc(ret
);
922 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
923 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#lx.\n", hr
);
924 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#lx.\n", rgn_data
->rdh
.dwSize
);
925 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#lx.\n", rgn_data
->rdh
.iType
);
926 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %lu.\n", rgn_data
->rdh
.nCount
);
927 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
928 "Got unexpected bounding rect %s, expected %s.\n",
929 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
932 r1
= CreateRectRgn(0, 0, 320, 240);
933 ok(!!r1
, "Failed to create region.\n");
934 r2
= CreateRectRgn(320, 240, 640, 480);
935 ok(!!r2
, "Failed to create region.\n");
936 CombineRgn(r1
, r1
, r2
, RGN_OR
);
937 ret
= GetRegionData(r1
, 0, NULL
);
938 rgn_data
= malloc(ret
);
939 ret
= GetRegionData(r1
, ret
, rgn_data
);
940 ok(!!ret
, "Failed to get region data.\n");
945 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
946 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#lx.\n", hr
);
947 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
948 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
949 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
950 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
954 memset(&surface_desc
, 0, sizeof(surface_desc
));
955 surface_desc
.dwSize
= sizeof(surface_desc
);
956 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
957 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
958 surface_desc
.dwWidth
= 640;
959 surface_desc
.dwHeight
= 480;
960 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
961 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
962 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
963 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
964 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
965 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
967 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
968 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
969 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
970 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
972 memset(&fx
, 0, sizeof(fx
));
973 fx
.dwSize
= sizeof(fx
);
974 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
975 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
976 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
977 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
979 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
980 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
981 ok(surface_desc
.lPitch
== 2560, "Got unexpected surface pitch %lu.\n", surface_desc
.lPitch
);
982 ptr
= surface_desc
.lpSurface
;
983 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
984 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
985 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
986 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
987 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
989 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
990 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
992 SetRect(&src_rect
, 1, 1, 5, 2);
993 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
994 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
995 for (i
= 0; i
< 4; ++i
)
997 for (j
= 0; j
< 4; ++j
)
999 x
= 80 * ((2 * j
) + 1);
1000 y
= 60 * ((2 * i
) + 1);
1001 color
= get_surface_color(dst_surface
, x
, y
);
1002 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1003 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1004 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1008 fx
.dwFillColor
= 0xff0000ff;
1009 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1010 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1011 for (i
= 0; i
< 4; ++i
)
1013 for (j
= 0; j
< 4; ++j
)
1015 x
= 80 * ((2 * j
) + 1);
1016 y
= 60 * ((2 * i
) + 1);
1017 color
= get_surface_color(dst_surface
, x
, y
);
1018 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1019 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1023 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1024 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#lx.\n", hr
);
1026 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1027 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1028 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1029 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1030 DestroyWindow(window
);
1031 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1032 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
1033 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1034 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1035 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1036 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1037 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1038 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1039 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1040 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1041 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1042 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1044 IDirectDrawSurface_Release(dst_surface
);
1045 IDirectDrawSurface_Release(src_surface
);
1046 refcount
= IDirectDrawClipper_Release(clipper
);
1047 ok(!refcount
, "Clipper has %lu references left.\n", refcount
);
1048 IDirectDraw2_Release(ddraw
);
1051 static void test_coop_level_d3d_state(void)
1053 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1054 IDirectDrawSurface
*rt
, *surface
;
1055 IDirect3DMaterial2
*background
;
1056 IDirect3DViewport2
*viewport
;
1057 IDirect3DDevice2
*device
;
1058 D3DMATERIAL material
;
1059 IDirectDraw2
*ddraw
;
1066 static D3DLVERTEX quad
[] =
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}},
1071 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0x800000ff}},
1074 window
= create_window();
1075 ddraw
= create_ddraw();
1076 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1078 if (ddraw_is_warp(ddraw
))
1080 /* ddraw2 crashes in EndScene, and if it doesn't crash it fails with
1081 * DDERR_SURFACELOST on WARP. */
1082 win_skip("Skipping test that crashes WARP occasionally.\n");
1083 IDirectDraw2_Release(ddraw
);
1084 DestroyWindow(window
);
1088 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1090 skip("Failed to create a 3D device, skipping test.\n");
1091 IDirectDraw2_Release(ddraw
);
1092 DestroyWindow(window
);
1096 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1097 viewport
= create_viewport(device
, 0, 0, 640, 480);
1098 viewport_set_background(device
, viewport
, background
);
1100 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1101 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1102 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
1103 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1105 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1106 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1107 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1108 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1109 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1110 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1111 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1112 ok(!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1113 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1114 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1115 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1116 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1117 color
= get_surface_color(rt
, 320, 240);
1118 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1120 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1121 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1122 hr
= IDirectDrawSurface_IsLost(rt
);
1123 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1125 memset(&lock
, 0, sizeof(lock
));
1126 lock
.dwSize
= sizeof(lock
);
1127 lock
.lpSurface
= (void *)0xdeadbeef;
1128 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1129 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1130 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1132 hr
= restore_surfaces(ddraw
);
1133 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1135 hr
= IDirectDrawSurface2_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1136 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1137 hr
= IDirectDrawSurface2_Unlock(rt
, NULL
);
1138 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1140 memset(&material
, 0, sizeof(material
));
1141 material
.dwSize
= sizeof(material
);
1142 material
.diffuse
.r
= 0.0f
;
1143 material
.diffuse
.g
= 1.0f
;
1144 material
.diffuse
.b
= 0.0f
;
1145 material
.diffuse
.a
= 1.0f
;
1146 hr
= IDirect3DMaterial2_SetMaterial(background
, &material
);
1147 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1149 hr
= IDirect3DDevice2_GetRenderTarget(device
, &surface
);
1150 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1151 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1152 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1153 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1154 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1155 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1156 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1157 ok(!!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1158 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1159 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1160 color
= get_surface_color(rt
, 320, 240);
1161 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1162 "Got unexpected color 0x%08x.\n", color
);
1164 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1165 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1166 hr
= IDirect3DDevice2_BeginScene(device
);
1167 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1168 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
1169 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1170 hr
= IDirect3DDevice2_EndScene(device
);
1171 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1172 color
= get_surface_color(rt
, 320, 240);
1173 ok(compare_color(color
, 0x0000ff80, 1), "Got unexpected color 0x%08x.\n", color
);
1175 destroy_viewport(device
, viewport
);
1176 destroy_material(background
);
1177 IDirectDrawSurface_Release(surface
);
1178 IDirectDrawSurface_Release(rt
);
1179 IDirect3DDevice2_Release(device
);
1180 IDirectDraw2_Release(ddraw
);
1181 DestroyWindow(window
);
1184 static void test_surface_interface_mismatch(void)
1186 IDirectDraw2
*ddraw
= NULL
;
1187 IDirect3D2
*d3d
= NULL
;
1188 IDirectDrawSurface
*surface
= NULL
, *ds
;
1189 IDirectDrawSurface3
*surface3
= NULL
;
1190 IDirect3DDevice2
*device
= NULL
;
1191 IDirect3DViewport2
*viewport
= NULL
;
1192 IDirect3DMaterial2
*background
= NULL
;
1193 DDSURFACEDESC surface_desc
;
1199 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1201 window
= create_window();
1202 ddraw
= create_ddraw();
1203 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1204 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1206 skip("Failed to create a 3D device, skipping test.\n");
1207 IDirectDraw2_Release(ddraw
);
1208 DestroyWindow(window
);
1211 z_depth
= get_device_z_depth(device
);
1212 ok(!!z_depth
, "Failed to get device z depth.\n");
1213 IDirect3DDevice2_Release(device
);
1216 memset(&surface_desc
, 0, sizeof(surface_desc
));
1217 surface_desc
.dwSize
= sizeof(surface_desc
);
1218 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1219 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1220 surface_desc
.dwWidth
= 640;
1221 surface_desc
.dwHeight
= 480;
1223 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1224 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
1226 hr
= IDirectDrawSurface2_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1229 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1233 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
1235 skip("D3D interface is not available, skipping test.\n");
1239 memset(&surface_desc
, 0, sizeof(surface_desc
));
1240 surface_desc
.dwSize
= sizeof(surface_desc
);
1241 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1242 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1243 surface_desc
.dwZBufferBitDepth
= z_depth
;
1244 surface_desc
.dwWidth
= 640;
1245 surface_desc
.dwHeight
= 480;
1246 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1247 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
1251 /* Using a different surface interface version still works */
1252 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1253 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
1254 refcount
= IDirectDrawSurface_Release(ds
);
1255 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
1260 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface
*)surface3
, &device
);
1261 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1265 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1266 viewport
= create_viewport(device
, 0, 0, 640, 480);
1267 viewport_set_background(device
, viewport
, background
);
1269 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1270 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
1271 color
= get_surface_color(surface
, 320, 240);
1272 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1276 destroy_viewport(device
, viewport
);
1278 destroy_material(background
);
1279 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1280 if (surface
) IDirectDrawSurface_Release(surface
);
1281 if (device
) IDirect3DDevice2_Release(device
);
1282 if (d3d
) IDirect3D2_Release(d3d
);
1283 if (ddraw
) IDirectDraw2_Release(ddraw
);
1284 DestroyWindow(window
);
1287 static void test_coop_level_threaded(void)
1289 struct create_window_thread_param p
;
1290 IDirectDraw2
*ddraw
;
1293 ddraw
= create_ddraw();
1294 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1295 create_window_thread(&p
);
1297 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1298 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1300 destroy_window_thread(&p
);
1301 IDirectDraw2_Release(ddraw
);
1304 static void test_depth_blit(const GUID
*device_guid
)
1306 static D3DLVERTEX quad1
[] =
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}},
1311 {{ 1.0}, {-1.0}, {0.50f
}, 0, {0xff00ff00}},
1313 static const unsigned int expected_colors
[4][4] =
1315 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1316 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1317 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1318 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1320 DDSURFACEDESC ddsd_new
, ddsd_existing
;
1322 IDirect3DDevice2
*device
;
1323 IDirectDrawSurface
*ds1
, *ds2
, *ds3
, *rt
;
1324 BOOL depth_fill_broken
= FALSE
;
1325 IDirect3DViewport2
*viewport
;
1326 RECT src_rect
, dst_rect
;
1327 unsigned int color
, i
, j
;
1329 IDirectDraw2
*ddraw
;
1333 IDirect3DMaterial2
*background
;
1335 window
= create_window();
1336 ddraw
= create_ddraw();
1337 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1338 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
, NULL
)))
1340 skip("Failed to create a 3D device, skipping test.\n");
1341 IDirectDraw2_Release(ddraw
);
1342 DestroyWindow(window
);
1346 ds1
= get_depth_stencil(device
);
1348 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1349 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1350 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1351 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1352 hr
= IDirectDrawSurface_GetSurfaceDesc(ds1
, &ddsd_existing
);
1353 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1354 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1355 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1356 if (is_software_device_type(device_guid
))
1357 ddsd_new
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1358 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1359 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1360 ddsd_new
.ddpfPixelFormat
= ddsd_existing
.ddpfPixelFormat
;
1361 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1362 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1363 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1364 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1366 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1367 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1368 viewport_set_background(device
, viewport
, background
);
1369 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1370 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
1372 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1373 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#lx.\n", hr
);
1374 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1375 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#lx.\n", hr
);
1377 d3drect
.x1
= d3drect
.y1
= 0;
1378 d3drect
.x2
= ddsd_existing
.dwWidth
; d3drect
.y2
= ddsd_existing
.dwHeight
;
1379 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
);
1380 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#lx.\n", hr
);
1383 SetRect(&src_rect
, 0, 0, 320, 240);
1384 SetRect(&dst_rect
, 0, 0, 320, 240);
1385 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1386 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1387 /* Different locations. */
1388 SetRect(&src_rect
, 0, 0, 320, 240);
1389 SetRect(&dst_rect
, 320, 240, 640, 480);
1390 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1391 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1393 SetRect(&src_rect
, 0, 0, 320, 240);
1394 SetRect(&dst_rect
, 0, 0, 640, 480);
1395 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1396 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1398 SetRect(&src_rect
, 0, 480, 640, 0);
1399 SetRect(&dst_rect
, 0, 0, 640, 480);
1400 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1401 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1402 SetRect(&src_rect
, 0, 0, 640, 480);
1403 SetRect(&dst_rect
, 0, 480, 640, 0);
1404 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1405 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1406 /* Full, explicit. */
1407 SetRect(&src_rect
, 0, 0, 640, 480);
1408 SetRect(&dst_rect
, 0, 0, 640, 480);
1409 hr
= IDirectDrawSurface_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1410 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1411 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1413 /* Depth blit inside a BeginScene / EndScene pair */
1414 hr
= IDirect3DDevice2_BeginScene(device
);
1415 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#lx.\n", hr
);
1416 /* From the current depth stencil */
1417 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1418 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1419 /* To the current depth stencil */
1420 hr
= IDirectDrawSurface_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1421 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1422 /* Between unbound surfaces */
1423 hr
= IDirectDrawSurface_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1424 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1425 hr
= IDirect3DDevice2_EndScene(device
);
1426 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#lx.\n", hr
);
1428 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1429 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1430 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1431 * a reliable result(z = 0.0) */
1432 memset(&fx
, 0, sizeof(fx
));
1433 fx
.dwSize
= sizeof(fx
);
1435 hr
= IDirectDrawSurface_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1436 ok(hr
== D3D_OK
|| broken(is_software_device_type(device_guid
)
1437 && hr
== 0x8876086c /* D3DERR_INVALIDCALL */), "Got unexpected hr %#lx.\n", hr
);
1439 depth_fill_broken
= TRUE
;
1441 /* This clears the Z buffer with 1.0 */
1442 hr
= IDirect3DViewport2_Clear(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
);
1443 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1445 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1446 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1448 color
= get_surface_color(rt
, 80, 60);
1449 /* For some reason clears and colour fill blits randomly fail with software render target. */
1450 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1451 "Got unexpected colour 0x%08x.\n", color
);
1454 fill_surface(rt
, 0xffff0000);
1456 color
= get_surface_color(rt
, 80, 60);
1457 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1460 SetRect(&dst_rect
, 0, 0, 320, 240);
1461 hr
= IDirectDrawSurface_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1462 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1463 IDirectDrawSurface_Release(ds3
);
1464 IDirectDrawSurface_Release(ds2
);
1465 IDirectDrawSurface_Release(ds1
);
1467 hr
= IDirect3DDevice2_BeginScene(device
);
1468 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1469 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad1
, 4, 0);
1470 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1471 hr
= IDirect3DDevice2_EndScene(device
);
1472 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1474 for (i
= 0; i
< 4; ++i
)
1476 for (j
= 0; j
< 4; ++j
)
1478 unsigned int x
= 80 * ((2 * j
) + 1);
1479 unsigned int y
= 60 * ((2 * i
) + 1);
1480 color
= get_surface_color(rt
, x
, y
);
1481 ok(compare_color(color
, expected_colors
[i
][j
], 1) || broken(depth_fill_broken
&& color
== 0x0000ff00),
1482 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1485 IDirectDrawSurface_Release(rt
);
1487 destroy_viewport(device
, viewport
);
1488 destroy_material(background
);
1489 IDirect3DDevice2_Release(device
);
1490 IDirectDraw2_Release(ddraw
);
1491 DestroyWindow(window
);
1494 static void test_texture_load_ckey(void)
1496 IDirectDraw2
*ddraw
= NULL
;
1497 IDirectDrawSurface
*src
= NULL
;
1498 IDirectDrawSurface
*dst
= NULL
;
1499 IDirect3DTexture
*src_tex
= NULL
;
1500 IDirect3DTexture
*dst_tex
= NULL
;
1505 ddraw
= create_ddraw();
1506 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1507 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1508 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1510 memset(&ddsd
, 0, sizeof(ddsd
));
1511 ddsd
.dwSize
= sizeof(ddsd
);
1512 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1513 ddsd
.dwHeight
= 128;
1515 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1516 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1517 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#lx.\n", hr
);
1518 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1519 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1520 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#lx.\n", hr
);
1522 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirect3DTexture
, (void **)&src_tex
);
1523 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture interface, hr %#lx.\n", hr
);
1526 /* 64 bit ddraw does not support d3d */
1527 skip("Could not get Direct3DTexture interface, skipping texture::Load color keying tests.\n");
1530 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirect3DTexture
, (void **)&dst_tex
);
1531 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture interface, hr %#lx.\n", hr
);
1533 /* No surface has a color key */
1534 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1535 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDCAPS
), "Got unexpected hr %#lx.\n", hr
);
1538 /* Testbot Windows NT VMs */
1539 skip("IDirect3DTexture::Load does not work, skipping color keying tests.\n");
1543 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1544 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1545 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1546 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1547 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1549 /* Source surface has a color key */
1550 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1551 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1552 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1553 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1554 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1555 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1556 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1557 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1558 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1560 /* Both surfaces have a color key: Dest ckey is overwritten */
1561 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1562 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1563 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1564 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1565 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1566 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1567 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1568 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1569 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1571 /* Only the destination has a color key: It is not deleted */
1572 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1573 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1574 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1575 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1576 hr
= IDirect3DTexture_Load(dst_tex
, src_tex
);
1577 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1578 hr
= IDirectDrawSurface_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1579 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1580 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1581 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1584 if (dst_tex
) IDirect3DTexture_Release(dst_tex
);
1585 if (src_tex
) IDirect3DTexture_Release(src_tex
);
1586 if (dst
) IDirectDrawSurface_Release(dst
);
1587 if (src
) IDirectDrawSurface_Release(src
);
1588 if (ddraw
) IDirectDraw2_Release(ddraw
);
1591 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1593 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1594 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1595 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1596 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1599 static ULONG
get_refcount(IUnknown
*test_iface
)
1601 IUnknown_AddRef(test_iface
);
1602 return IUnknown_Release(test_iface
);
1605 static void test_viewport_object(void)
1607 IDirectDraw2
*ddraw
;
1610 ULONG ref
, old_d3d_ref
;
1613 IDirect3DViewport
*viewport
;
1614 IDirect3DViewport2
*viewport2
, *another_vp
, *test_vp
;
1615 IDirect3DViewport3
*viewport3
;
1616 IDirectDrawGammaControl
*gamma
;
1618 IDirect3DDevice2
*device
;
1627 window
= create_window();
1628 ddraw
= create_ddraw();
1629 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1630 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1632 skip("Failed to create a 3D device, skipping test.\n");
1633 IDirectDraw2_Release(ddraw
);
1634 DestroyWindow(window
);
1638 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
1639 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#lx.\n", hr
);
1642 skip("D3D interface is not available, skipping test.\n");
1643 IDirectDraw2_Release(ddraw
);
1646 old_d3d_ref
= get_refcount((IUnknown
*)d3d
);
1648 hr
= IDirect3D2_CreateViewport(d3d
, &viewport2
, NULL
);
1649 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
1650 ref
= get_refcount((IUnknown
*)viewport2
);
1651 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1652 ref
= get_refcount((IUnknown
*)d3d
);
1653 ok(ref
== old_d3d_ref
, "Got unexpected refcount %lu.\n", ref
);
1655 memset(&desc
, 0, sizeof(desc
));
1656 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1657 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1658 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1659 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1660 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1661 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1662 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1663 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1664 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1665 hr
= IDirect3DViewport2_GetViewport(viewport2
, &desc
.vp1
);
1666 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1667 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %lu.\n", desc
.vp1
.dwSize
);
1668 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1669 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1670 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %lu.\n", desc
.vp2
.dwSize
);
1671 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1672 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &desc
.vp2
);
1673 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1675 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1676 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1677 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
1678 ok(!gamma
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1679 /* NULL iid: Segfaults */
1681 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport
, (void **)&viewport
);
1682 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#lx.\n", hr
);
1683 ref
= get_refcount((IUnknown
*)viewport
);
1684 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1685 ref
= get_refcount((IUnknown
*)viewport2
);
1686 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1687 IDirect3DViewport_Release(viewport
);
1690 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1691 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to QI IDirect3DViewport3, hr %#lx.\n", hr
);
1694 ref
= get_refcount((IUnknown
*)viewport2
);
1695 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1696 ref
= get_refcount((IUnknown
*)viewport3
);
1697 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1698 IDirect3DViewport3_Release(viewport3
);
1701 hr
= IDirect3DViewport2_QueryInterface(viewport2
, &IID_IUnknown
, (void **)&unknown
);
1702 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#lx.\n", hr
);
1703 ref
= get_refcount((IUnknown
*)viewport2
);
1704 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1705 ref
= get_refcount(unknown
);
1706 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1707 IUnknown_Release(unknown
);
1709 hr
= IDirect3DDevice2_DeleteViewport(device
, NULL
);
1710 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1711 hr
= IDirect3DDevice2_GetCurrentViewport(device
, NULL
);
1712 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1714 hr
= IDirect3D2_CreateViewport(d3d
, &another_vp
, NULL
);
1715 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
1717 /* Setting a viewport not in the viewport list fails */
1718 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1719 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1721 /* AddViewport(NULL): Segfault */
1722 hr
= IDirect3DDevice2_AddViewport(device
, viewport2
);
1723 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#lx.\n", hr
);
1724 ref
= get_refcount((IUnknown
*) viewport2
);
1725 ok(ref
== 2, "viewport2 refcount is %lu.\n", ref
);
1726 hr
= IDirect3DDevice2_AddViewport(device
, another_vp
);
1727 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#lx.\n", hr
);
1728 ref
= get_refcount((IUnknown
*) another_vp
);
1729 ok(ref
== 2, "another_vp refcount is %lu.\n", ref
);
1731 test_vp
= (IDirect3DViewport2
*) 0xbaadc0de;
1732 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1733 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1734 ok(test_vp
== (IDirect3DViewport2
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1736 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1737 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1738 ref
= get_refcount((IUnknown
*) viewport2
);
1739 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1740 ref
= get_refcount((IUnknown
*) device
);
1741 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1744 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1745 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1746 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1747 ref
= get_refcount((IUnknown
*) viewport2
);
1748 ok(ref
== 4, "Got unexpected refcount %lu.\n", ref
);
1750 IDirect3DViewport2_Release(test_vp
);
1752 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1754 /* Cannot set the viewport to NULL */
1755 hr
= IDirect3DDevice2_SetCurrentViewport(device
, NULL
);
1756 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#lx.\n", hr
);
1758 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1759 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1760 ok(test_vp
== viewport2
, "Got unexpected viewport %p\n", test_vp
);
1762 IDirect3DViewport2_Release(test_vp
);
1764 /* SetCurrentViewport properly releases the old viewport's reference */
1765 hr
= IDirect3DDevice2_SetCurrentViewport(device
, another_vp
);
1766 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1767 ref
= get_refcount((IUnknown
*) viewport2
);
1768 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1769 ref
= get_refcount((IUnknown
*) another_vp
);
1770 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1772 /* Deleting the viewport removes the reference added by AddViewport, but not
1773 * the one added by SetCurrentViewport. */
1774 hr
= IDirect3DDevice2_DeleteViewport(device
, another_vp
);
1775 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#lx.\n", hr
);
1776 ref
= get_refcount((IUnknown
*) another_vp
);
1777 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1779 /* GetCurrentViewport fails though */
1781 hr
= IDirect3DDevice2_GetCurrentViewport(device
, &test_vp
);
1782 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1783 ok(!test_vp
, "Got unexpected viewport %p\n", test_vp
);
1785 /* Setting a different viewport does not free the leaked reference. How
1786 * do I get rid of it? Leak the viewport for now. */
1787 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
1788 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
1789 ref
= get_refcount((IUnknown
*) viewport2
);
1790 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1791 ref
= get_refcount((IUnknown
*) another_vp
);
1792 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1794 memset(&vp
, 0, sizeof(vp
));
1795 memset(&vp
, 0, sizeof(vp2
));
1796 vp
.dwX
= vp2
.dwX
= 0;
1797 vp
.dwY
= vp2
.dwY
= 0;
1798 vp
.dwWidth
= vp2
.dwWidth
= 640;
1799 vp
.dwHeight
= vp2
.dwHeight
= 480;
1800 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1801 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1802 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1803 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1806 vp2
.dvClipX
= -1.0f
;
1808 vp2
.dvClipWidth
= 2.0f
;
1809 vp2
.dvClipHeight
= 2.0f
;
1810 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1811 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1812 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1813 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1815 vp
.dwSize
= sizeof(vp
);
1816 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1817 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
1818 vp2
.dwSize
= sizeof(vp2
);
1819 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1820 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
1822 /* Destroying the device removes the viewport, but does not free the reference
1823 * added by SetCurrentViewport. */
1824 IDirect3DDevice2_Release(device
);
1825 ref
= get_refcount((IUnknown
*) viewport2
);
1826 todo_wine
ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1828 vp
.dwSize
= sizeof(vp
);
1829 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1830 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1831 vp2
.dwSize
= sizeof(vp2
);
1832 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1833 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1835 IDirect3DViewport2_Release(another_vp
);
1836 IDirect3DViewport2_Release(viewport2
);
1837 IDirect3D2_Release(d3d
);
1838 DestroyWindow(window
);
1839 IDirectDraw2_Release(ddraw
);
1842 static void test_zenable(const GUID
*device_guid
)
1844 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1845 static D3DTLVERTEX tquad
[] =
1847 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1848 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1849 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1850 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1852 IDirect3DMaterial2
*background
;
1853 unsigned int color
, x
, y
, i
, j
;
1854 IDirect3DViewport2
*viewport
;
1855 IDirect3DDevice2
*device
;
1856 IDirectDrawSurface
*rt
;
1857 IDirectDraw2
*ddraw
;
1861 window
= create_window();
1862 ddraw
= create_ddraw();
1863 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1864 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
, NULL
)))
1866 skip("Failed to create a 3D device, skipping test.\n");
1867 IDirectDraw2_Release(ddraw
);
1868 DestroyWindow(window
);
1872 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1873 viewport
= create_viewport(device
, 0, 0, 640, 480);
1874 viewport_set_background(device
, viewport
, background
);
1875 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1876 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1878 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1879 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1881 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1882 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1884 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
1885 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1887 color
= get_surface_color(rt
, 80, 60);
1888 /* For some reason clears and colour fill blits randomly fail with software render target. */
1889 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1890 "Got unexpected colour 0x%08x.\n", color
);
1893 fill_surface(rt
, 0xffff0000);
1895 color
= get_surface_color(rt
, 80, 60);
1896 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1899 hr
= IDirect3DDevice2_BeginScene(device
);
1900 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1901 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, tquad
, 4, 0);
1902 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1903 hr
= IDirect3DDevice2_EndScene(device
);
1904 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1906 for (i
= 0; i
< 4; ++i
)
1908 for (j
= 0; j
< 4; ++j
)
1910 x
= 80 * ((2 * j
) + 1);
1911 y
= 60 * ((2 * i
) + 1);
1912 color
= get_surface_color(rt
, x
, y
);
1913 ok(compare_color(color
, 0x0000ff00, 1),
1914 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1917 IDirectDrawSurface_Release(rt
);
1919 destroy_viewport(device
, viewport
);
1920 destroy_material(background
);
1921 IDirect3DDevice2_Release(device
);
1922 IDirectDraw2_Release(ddraw
);
1923 DestroyWindow(window
);
1926 static void test_ck_rgba(const GUID
*device_guid
)
1928 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1929 static D3DTLVERTEX tquad
[] =
1931 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1932 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1933 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1934 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1935 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1936 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1937 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1938 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1942 D3DCOLOR fill_color
;
1945 unsigned int result1
, result1_broken
;
1946 unsigned int result2
, result2_broken
;
1950 /* r200 on Windows doesn't check the alpha component when applying the color
1951 * key, so the key matches on every texel. */
1952 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1953 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1954 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1955 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1956 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1957 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1958 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1959 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1962 D3DTEXTUREHANDLE texture_handle
;
1963 IDirect3DMaterial2
*background
;
1964 IDirectDrawSurface
*surface
;
1965 IDirect3DViewport2
*viewport
;
1966 IDirect3DTexture2
*texture
;
1967 DDSURFACEDESC surface_desc
;
1968 IDirect3DDevice2
*device
;
1969 IDirectDrawSurface
*rt
;
1970 unsigned int color
, i
;
1971 IDirectDraw2
*ddraw
;
1976 window
= create_window();
1977 ddraw
= create_ddraw();
1978 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1979 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
, NULL
)))
1981 skip("Failed to create a 3D device, skipping test.\n");
1982 IDirectDraw2_Release(ddraw
);
1983 DestroyWindow(window
);
1987 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1988 viewport
= create_viewport(device
, 0, 0, 640, 480);
1989 viewport_set_background(device
, viewport
, background
);
1990 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
1991 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1993 memset(&surface_desc
, 0, sizeof(surface_desc
));
1994 surface_desc
.dwSize
= sizeof(surface_desc
);
1995 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1996 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1997 if (is_software_device_type(device_guid
))
1998 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1999 surface_desc
.dwWidth
= 256;
2000 surface_desc
.dwHeight
= 256;
2001 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2002 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
2003 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
2004 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
2005 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
2006 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
2007 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
2008 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
2009 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
2010 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2011 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2012 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2013 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2014 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
2015 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2016 IDirect3DTexture2_Release(texture
);
2018 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2019 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2020 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
2021 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2022 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2023 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2025 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2026 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2028 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2030 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
2031 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2032 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
2033 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2035 memset(&fx
, 0, sizeof(fx
));
2036 fx
.dwSize
= sizeof(fx
);
2037 fx
.dwFillColor
= tests
[i
].fill_color
;
2038 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2039 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2041 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
2042 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2043 /* RT clears are broken on Windows for software render target. */
2044 if (is_software_device_type(device_guid
))
2045 fill_surface(rt
, 0xffff0000);
2047 hr
= IDirect3DDevice2_BeginScene(device
);
2048 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2049 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2050 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2051 hr
= IDirect3DDevice2_EndScene(device
);
2052 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2054 color
= get_surface_color(rt
, 320, 240);
2055 ok(compare_color(color
, tests
[i
].result1
, 2) || compare_color(color
, tests
[i
].result1_broken
, 1),
2056 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2057 tests
[i
].result1
, i
, color
);
2059 fx
.dwFillColor
= 0xff0000ff;
2060 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2061 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2063 hr
= IDirect3DDevice2_BeginScene(device
);
2064 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2065 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[4], 4, 0);
2066 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2067 hr
= IDirect3DDevice2_EndScene(device
);
2068 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2070 /* This tests that fragments that are masked out by the color key are
2071 * discarded, instead of just fully transparent. */
2072 color
= get_surface_color(rt
, 320, 240);
2073 ok(compare_color(color
, tests
[i
].result2
, 2) || compare_color(color
, tests
[i
].result2_broken
, 1),
2074 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2075 tests
[i
].result2
, i
, color
);
2078 IDirectDrawSurface_Release(rt
);
2079 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2080 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2081 IDirectDrawSurface_Release(surface
);
2082 destroy_viewport(device
, viewport
);
2083 destroy_material(background
);
2084 IDirect3DDevice2_Release(device
);
2085 IDirectDraw2_Release(ddraw
);
2086 DestroyWindow(window
);
2089 static void test_ck_default(void)
2091 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2092 static D3DTLVERTEX tquad
[] =
2094 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
2095 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
2096 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
2097 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
2099 IDirectDrawSurface
*surface
, *rt
;
2100 D3DTEXTUREHANDLE texture_handle
;
2101 IDirect3DMaterial2
*background
;
2102 IDirect3DViewport2
*viewport
;
2103 DDSURFACEDESC surface_desc
;
2104 IDirect3DTexture2
*texture
;
2105 IDirect3DDevice2
*device
;
2106 IDirectDraw2
*ddraw
;
2113 window
= create_window();
2114 ddraw
= create_ddraw();
2115 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2116 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2118 skip("Failed to create a 3D device, skipping test.\n");
2119 IDirectDraw2_Release(ddraw
);
2120 DestroyWindow(window
);
2124 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
2125 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
2127 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
2128 viewport
= create_viewport(device
, 0, 0, 640, 480);
2129 viewport_set_background(device
, viewport
, background
);
2130 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
2131 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
2133 memset(&surface_desc
, 0, sizeof(surface_desc
));
2134 surface_desc
.dwSize
= sizeof(surface_desc
);
2135 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2137 surface_desc
.dwWidth
= 256;
2138 surface_desc
.dwHeight
= 256;
2139 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2140 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2141 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
2142 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
2143 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
2144 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
2145 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2146 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2147 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2148 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2149 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2150 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
2151 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
2152 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
2153 IDirect3DTexture_Release(texture
);
2155 memset(&fx
, 0, sizeof(fx
));
2156 fx
.dwSize
= sizeof(fx
);
2157 fx
.dwFillColor
= 0x000000ff;
2158 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2159 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
2161 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2162 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2163 hr
= IDirect3DDevice2_BeginScene(device
);
2164 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2165 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2166 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
2167 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2168 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2169 ok(!value
, "Got unexpected color keying state %#lx.\n", value
);
2170 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2171 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2172 hr
= IDirect3DDevice2_EndScene(device
);
2173 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2174 color
= get_surface_color(rt
, 320, 240);
2175 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2177 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2178 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2179 hr
= IDirect3DDevice2_BeginScene(device
);
2180 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2181 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2182 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
2183 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &tquad
[0], 4, 0);
2184 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2185 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2186 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2187 ok(!!value
, "Got unexpected color keying state %#lx.\n", value
);
2188 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2189 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
2190 hr
= IDirect3DDevice2_EndScene(device
);
2191 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2192 color
= get_surface_color(rt
, 320, 240);
2193 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2195 IDirectDrawSurface_Release(surface
);
2196 destroy_viewport(device
, viewport
);
2197 destroy_material(background
);
2198 IDirectDrawSurface_Release(rt
);
2199 IDirect3DDevice2_Release(device
);
2200 IDirectDraw2_Release(ddraw
);
2201 DestroyWindow(window
);
2204 static void test_ck_complex(void)
2206 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
2207 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
2208 DDSURFACEDESC surface_desc
;
2209 IDirect3DDevice2
*device
;
2210 DDCOLORKEY color_key
;
2211 IDirectDraw2
*ddraw
;
2217 window
= create_window();
2218 ddraw
= create_ddraw();
2219 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2220 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2222 skip("Failed to create a 3D device, skipping test.\n");
2223 DestroyWindow(window
);
2224 IDirectDraw2_Release(ddraw
);
2227 IDirect3DDevice2_Release(device
);
2229 memset(&surface_desc
, 0, sizeof(surface_desc
));
2230 surface_desc
.dwSize
= sizeof(surface_desc
);
2231 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2232 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2233 surface_desc
.dwWidth
= 128;
2234 surface_desc
.dwHeight
= 128;
2235 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2236 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2238 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2239 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2240 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2241 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2242 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2243 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2244 memset(&color_key
, 0, sizeof(color_key
));
2245 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2246 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2247 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2248 color_key
.dwColorSpaceLowValue
);
2249 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2250 color_key
.dwColorSpaceHighValue
);
2253 IDirectDrawSurface_AddRef(mipmap
);
2254 for (i
= 0; i
< 7; ++i
)
2256 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2257 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
2259 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2260 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2261 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2262 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2263 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2264 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx, i %u.\n", hr
, i
);
2265 memset(&color_key
, 0, sizeof(color_key
));
2266 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2267 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx, i %u.\n", hr
, i
);
2268 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2269 color_key
.dwColorSpaceLowValue
, i
);
2270 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2271 color_key
.dwColorSpaceHighValue
, i
);
2273 IDirectDrawSurface_Release(mipmap
);
2277 memset(&color_key
, 0, sizeof(color_key
));
2278 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2279 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2280 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2281 color_key
.dwColorSpaceLowValue
);
2282 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2283 color_key
.dwColorSpaceHighValue
);
2285 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2286 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
2287 IDirectDrawSurface_Release(mipmap
);
2288 refcount
= IDirectDrawSurface_Release(surface
);
2289 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2291 memset(&surface_desc
, 0, sizeof(surface_desc
));
2292 surface_desc
.dwSize
= sizeof(surface_desc
);
2293 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2294 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2295 surface_desc
.dwBackBufferCount
= 1;
2296 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2297 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2299 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2300 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2301 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2302 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2303 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2304 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2305 memset(&color_key
, 0, sizeof(color_key
));
2306 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2307 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2308 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2309 color_key
.dwColorSpaceLowValue
);
2310 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2311 color_key
.dwColorSpaceHighValue
);
2313 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2314 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
2316 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2317 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2318 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2319 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2320 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2321 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2322 memset(&color_key
, 0, sizeof(color_key
));
2323 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2324 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2325 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2326 color_key
.dwColorSpaceLowValue
);
2327 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2328 color_key
.dwColorSpaceHighValue
);
2330 IDirectDrawSurface_Release(tmp
);
2332 refcount
= IDirectDrawSurface_Release(surface
);
2333 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2334 refcount
= IDirectDraw2_Release(ddraw
);
2335 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2336 DestroyWindow(window
);
2342 REFIID refcount_iid
;
2346 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2347 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2349 ULONG refcount
, expected_refcount
;
2350 IUnknown
*iface1
, *iface2
;
2354 for (i
= 0; i
< entry_count
; ++i
)
2356 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2357 ok(hr
== tests
[i
].hr
, "Got hr %#lx for test \"%s\" %u.\n", hr
, test_name
, i
);
2360 for (j
= 0; j
< entry_count
; ++j
)
2362 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2363 ok(hr
== tests
[j
].hr
, "Got hr %#lx for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2366 expected_refcount
= 0;
2367 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2368 ++expected_refcount
;
2369 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2370 ++expected_refcount
;
2371 refcount
= IUnknown_Release(iface2
);
2372 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
2373 refcount
, test_name
, i
, j
, expected_refcount
);
2377 expected_refcount
= 0;
2378 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2379 ++expected_refcount
;
2380 refcount
= IUnknown_Release(iface1
);
2381 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
2382 refcount
, test_name
, i
, expected_refcount
);
2387 static void test_surface_qi(void)
2389 static const struct qi_test tests
[] =
2391 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2392 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2393 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2394 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2395 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2396 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2397 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2398 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2399 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2400 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2401 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2402 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2403 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2404 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2405 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2406 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2407 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2408 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2409 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2410 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2411 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2412 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2413 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2414 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2415 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2416 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2417 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2418 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2419 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2420 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2421 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2422 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2423 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2424 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2425 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2426 {NULL
, NULL
, E_INVALIDARG
},
2429 IDirectDrawSurface
*surface
;
2430 DDSURFACEDESC surface_desc
;
2431 IDirect3DDevice2
*device
;
2432 IDirectDraw2
*ddraw
;
2436 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2438 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2442 window
= create_window();
2443 ddraw
= create_ddraw();
2444 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2445 /* Try to create a D3D device to see if the ddraw implementation supports
2446 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2447 * doesn't support e.g. the IDirect3DTexture interfaces. */
2448 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2450 skip("Failed to create a 3D device, skipping test.\n");
2451 IDirectDraw2_Release(ddraw
);
2452 DestroyWindow(window
);
2455 IDirect3DDevice_Release(device
);
2457 memset(&surface_desc
, 0, sizeof(surface_desc
));
2458 surface_desc
.dwSize
= sizeof(surface_desc
);
2459 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2460 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2461 surface_desc
.dwWidth
= 512;
2462 surface_desc
.dwHeight
= 512;
2463 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2464 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
2465 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2466 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2468 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2470 IDirectDrawSurface_Release(surface
);
2471 IDirectDraw2_Release(ddraw
);
2472 DestroyWindow(window
);
2475 static void test_device_qi(void)
2477 static const struct qi_test tests
[] =
2479 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2480 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2481 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2482 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2483 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2484 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2485 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2486 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2487 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2488 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2489 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2490 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice2
, S_OK
},
2491 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice2
, S_OK
},
2492 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2493 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2494 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2495 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2496 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2497 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2498 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2499 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2500 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2501 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2502 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2503 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2504 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2505 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2506 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2507 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2508 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2509 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2510 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2511 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2512 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2513 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2514 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2515 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2516 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2517 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2518 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2519 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2520 {&IID_IUnknown
, &IID_IDirect3DDevice2
, S_OK
},
2523 IDirect3DDevice2
*device
;
2524 IDirectDraw2
*ddraw
;
2527 window
= create_window();
2528 ddraw
= create_ddraw();
2529 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2530 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2532 skip("Failed to create a 3D device, skipping test.\n");
2533 IDirectDraw2_Release(ddraw
);
2534 DestroyWindow(window
);
2538 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice2
, tests
, ARRAY_SIZE(tests
));
2540 IDirect3DDevice2_Release(device
);
2541 IDirectDraw2_Release(ddraw
);
2542 DestroyWindow(window
);
2545 static void test_wndproc(void)
2547 LONG_PTR proc
, ddraw_proc
;
2548 IDirectDraw2
*ddraw
;
2554 static struct message messages
[] =
2556 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2557 {WM_MOVE
, FALSE
, 0},
2558 {WM_SIZE
, FALSE
, 0},
2559 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2560 {WM_ACTIVATE
, FALSE
, 0},
2561 {WM_SETFOCUS
, FALSE
, 0},
2565 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2566 ddraw
= create_ddraw();
2567 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2569 wc
.lpfnWndProc
= test_proc
;
2570 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2571 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2573 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2574 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2576 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2577 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2578 (LONG_PTR
)test_proc
, proc
);
2579 expect_messages
= messages
;
2580 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2581 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2582 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2583 expect_messages
= NULL
;
2584 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2585 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2586 (LONG_PTR
)test_proc
, proc
);
2587 ref
= IDirectDraw2_Release(ddraw
);
2588 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2589 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2590 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2591 (LONG_PTR
)test_proc
, proc
);
2593 /* DDSCL_NORMAL doesn't. */
2594 ddraw
= create_ddraw();
2595 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2596 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2597 (LONG_PTR
)test_proc
, proc
);
2598 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2599 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2600 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2601 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2602 (LONG_PTR
)test_proc
, proc
);
2603 ref
= IDirectDraw2_Release(ddraw
);
2604 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2605 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2606 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2607 (LONG_PTR
)test_proc
, proc
);
2609 /* The original window proc is only restored by ddraw if the current
2610 * window proc matches the one ddraw set. This also affects switching
2611 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2612 ddraw
= create_ddraw();
2613 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2614 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2615 (LONG_PTR
)test_proc
, proc
);
2616 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2617 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2618 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2619 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2620 (LONG_PTR
)test_proc
, proc
);
2622 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2623 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2624 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2625 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2626 (LONG_PTR
)test_proc
, proc
);
2627 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2628 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2629 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2630 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2631 (LONG_PTR
)test_proc
, proc
);
2632 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2633 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2634 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2635 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2636 (LONG_PTR
)DefWindowProcA
, proc
);
2637 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2638 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2639 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2640 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2641 (LONG_PTR
)DefWindowProcA
, proc
);
2642 ref
= IDirectDraw2_Release(ddraw
);
2643 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2644 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2645 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2646 (LONG_PTR
)test_proc
, proc
);
2648 ddraw
= create_ddraw();
2649 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2650 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2651 (LONG_PTR
)test_proc
, proc
);
2652 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2653 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2654 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2655 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2656 (LONG_PTR
)test_proc
, proc
);
2657 ref
= IDirectDraw2_Release(ddraw
);
2658 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2659 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2660 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2661 (LONG_PTR
)DefWindowProcA
, proc
);
2663 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2664 expect_messages
= NULL
;
2665 DestroyWindow(window
);
2666 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2669 static void test_window_style(void)
2671 LONG style
, exstyle
, tmp
, expected_style
;
2672 RECT fullscreen_rect
, r
;
2673 HWND window
, window2
;
2674 IDirectDraw2
*ddraw
;
2679 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2680 0, 0, 100, 100, 0, 0, 0, 0);
2681 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2682 0, 0, 50, 50, 0, 0, 0, 0);
2683 ddraw
= create_ddraw();
2684 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2686 style
= GetWindowLongA(window
, GWL_STYLE
);
2687 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2688 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2690 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2691 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2693 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2694 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2695 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2696 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2698 GetWindowRect(window
, &r
);
2699 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2700 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2701 GetClientRect(window
, &r
);
2702 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2704 ret
= SetForegroundWindow(GetDesktopWindow());
2705 ok(ret
, "Failed to set foreground window.\n");
2707 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2708 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2709 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2710 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2712 ret
= SetForegroundWindow(window
);
2713 ok(ret
, "Failed to set foreground window.\n");
2714 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2715 * the next tests expect this. */
2716 ShowWindow(window
, SW_HIDE
);
2718 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2719 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2721 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2722 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2723 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2724 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2726 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2727 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2729 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2730 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2731 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2732 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2734 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2735 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2737 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2738 expected_style
= style
| WS_VISIBLE
;
2739 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2740 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2741 expected_style
= exstyle
| WS_EX_TOPMOST
;
2742 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2744 ShowWindow(window
, SW_HIDE
);
2745 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2746 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2747 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2748 expected_style
= exstyle
| WS_EX_TOPMOST
;
2749 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2751 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2752 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2754 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2755 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2756 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2757 expected_style
= exstyle
| WS_EX_TOPMOST
;
2758 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2760 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2761 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2763 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2764 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2765 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2766 expected_style
= exstyle
| WS_EX_TOPMOST
;
2767 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2769 ret
= SetForegroundWindow(window
);
2770 ok(ret
, "Failed to set foreground window.\n");
2772 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2773 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2775 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2776 expected_style
= style
| WS_VISIBLE
;
2777 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2778 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2779 expected_style
= exstyle
| WS_EX_TOPMOST
;
2780 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2782 ShowWindow(window
, SW_HIDE
);
2783 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2784 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2786 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2787 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2788 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2789 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2791 ShowWindow(window
, SW_SHOW
);
2792 ret
= SetForegroundWindow(GetDesktopWindow());
2793 ok(ret
, "Failed to set foreground window.\n");
2794 SetActiveWindow(window
);
2795 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
2796 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2797 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2799 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2800 expected_style
= style
| WS_VISIBLE
;
2801 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2802 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2803 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2805 GetWindowRect(window
, &r
);
2806 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2807 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2809 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2810 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2812 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
2813 GetWindowRect(window
, &r
);
2814 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
2815 wine_dbgstr_rect(&r
));
2817 ret
= SetForegroundWindow(window2
);
2818 ok(ret
, "Failed to set foreground window.\n");
2819 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2820 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2822 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2823 expected_style
= style
| WS_VISIBLE
;
2824 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2825 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2826 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2828 GetWindowRect(window
, &r
);
2829 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2830 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2832 ret
= SetForegroundWindow(window
);
2833 ok(ret
, "Failed to set foreground window.\n");
2834 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2835 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2837 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2838 expected_style
= style
| WS_VISIBLE
;
2839 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2840 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2841 expected_style
= exstyle
| WS_EX_TOPMOST
;
2842 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2844 ShowWindow(window
, SW_HIDE
);
2845 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2846 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2848 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2849 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2850 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2851 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2853 ShowWindow(window
, SW_SHOW
);
2854 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2855 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2857 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2858 expected_style
= style
| WS_VISIBLE
;
2859 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2860 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2861 expected_style
= exstyle
| WS_EX_TOPMOST
;
2862 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2864 ret
= SetForegroundWindow(GetDesktopWindow());
2865 ok(ret
, "Failed to set foreground window.\n");
2866 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2867 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2868 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2869 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2870 expected_style
= exstyle
| WS_EX_TOPMOST
;
2871 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2873 /* Test that there is a ~1.5s timer that checks and restores WS_EX_TOPMOST if it's missing */
2874 ret
= ShowWindow(window
, SW_RESTORE
);
2875 ok(ret
, "ShowWindow failed, error %#lx.\n", GetLastError());
2876 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2877 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2880 /* Remove WS_VISIBLE and WS_EX_TOPMOST */
2881 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2882 ok(tmp
& WS_VISIBLE
, "Expected WS_VISIBLE.\n");
2883 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2884 ok(tmp
& WS_EX_TOPMOST
, "Expected WS_EX_TOPMOST.\n");
2885 ret
= ShowWindow(window
, SW_HIDE
);
2886 ok(ret
, "ShowWindow failed, error %#lx.\n", GetLastError());
2887 ret
= SetWindowPos(window
, HWND_NOTOPMOST
, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
);
2888 ok(ret
, "SetWindowPos failed, error %#lx.\n", GetLastError());
2889 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2890 ok(!(tmp
& WS_VISIBLE
), "Got unexpected WS_VISIBLE.\n");
2891 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2892 ok(!(tmp
& WS_EX_TOPMOST
), "Got unexpected WS_EX_TOPMOST.\n");
2897 /* WS_VISIBLE is not restored but WS_EX_TOPMOST is */
2898 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2899 ok(!(tmp
& WS_VISIBLE
), "Got unexpected WS_VISIBLE.\n");
2900 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2901 ok(tmp
& WS_EX_TOPMOST
, "Expected WS_EX_TOPMOST.\n");
2903 ref
= IDirectDraw2_Release(ddraw
);
2904 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2906 DestroyWindow(window2
);
2907 DestroyWindow(window
);
2910 static void test_redundant_mode_set(void)
2912 DDSURFACEDESC surface_desc
= {0};
2913 IDirectDraw2
*ddraw
;
2919 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2920 0, 0, 100, 100, 0, 0, 0, 0);
2921 ddraw
= create_ddraw();
2922 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2924 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2925 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2927 surface_desc
.dwSize
= sizeof(surface_desc
);
2928 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
2929 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
2931 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2932 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, 0, 0);
2933 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2935 GetWindowRect(window
, &q
);
2939 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2940 GetWindowRect(window
, &s
);
2941 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2943 hr
= IDirectDraw2_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2944 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, 0, 0);
2945 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2947 GetWindowRect(window
, &s
);
2948 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2949 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2951 ref
= IDirectDraw2_Release(ddraw
);
2952 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2954 DestroyWindow(window
);
2957 static SIZE screen_size
, screen_size2
;
2959 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2961 if (message
== WM_SIZE
)
2963 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2964 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2967 return test_proc(hwnd
, message
, wparam
, lparam
);
2970 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2972 if (message
== WM_SIZE
)
2974 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2975 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2978 return test_proc(hwnd
, message
, wparam
, lparam
);
2981 struct test_coop_level_mode_set_enum_param
2983 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2986 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2988 struct test_coop_level_mode_set_enum_param
*param
= context
;
2990 if (surface_desc
->ddpfPixelFormat
.dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2991 return DDENUMRET_OK
;
2992 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2993 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2994 return DDENUMRET_OK
;
2996 if (!param
->ddraw_width
)
2998 param
->ddraw_width
= surface_desc
->dwWidth
;
2999 param
->ddraw_height
= surface_desc
->dwHeight
;
3000 return DDENUMRET_OK
;
3002 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
3003 return DDENUMRET_OK
;
3005 /* The docs say the DDENUMRET_CANCEL below cancels the enumeration, so the check should be
3006 * redundant. However, since Windows 10 this no longer works and the enumeration continues
3007 * until all supported modes are enumerated. Win8 and earlier do cancel.
3009 * Unrelatedly, some testbot machines report high res modes like 1920x1080, but suffer from
3010 * some problems when we actually try to set them (w10pro64 and its localization siblings).
3011 * Try to stay below the registry mode if possible. */
3012 if (!param
->user32_width
|| (surface_desc
->dwWidth
< registry_mode
.dmPelsWidth
3013 && surface_desc
->dwHeight
< registry_mode
.dmPelsHeight
))
3015 param
->user32_width
= surface_desc
->dwWidth
;
3016 param
->user32_height
= surface_desc
->dwHeight
;
3018 return DDENUMRET_CANCEL
;
3021 static void test_coop_level_mode_set(void)
3023 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
3024 unsigned int display_count
= 0;
3025 IDirectDrawSurface
*primary
;
3026 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
3027 IDirectDraw2
*ddraw
;
3030 HWND window
, window2
;
3034 struct test_coop_level_mode_set_enum_param param
;
3038 static const struct message exclusive_messages
[] =
3040 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3041 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3042 {WM_SIZE
, FALSE
, 0},
3043 {WM_DISPLAYCHANGE
, FALSE
, 0},
3046 static const struct message exclusive_focus_loss_messages
[] =
3048 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
3049 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
3050 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3051 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
3052 {WM_DISPLAYCHANGE
, FALSE
, 0},
3053 {WM_KILLFOCUS
, FALSE
, 0},
3054 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
3055 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
3056 * SW_MINIMIZED, causing a recursive window activation that does not
3057 * produce the same result in Wine yet. Ignore the difference for now.
3058 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
3059 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3060 {WM_MOVE
, FALSE
, 0},
3061 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3062 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
3065 static const struct message exclusive_focus_restore_messages
[] =
3067 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
3068 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
3069 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
3070 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
3071 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
3072 /* Native redundantly sets the window size here. */
3073 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
3074 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
3075 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
3076 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
3079 static const struct message sc_restore_messages
[] =
3081 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
3082 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3083 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3084 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
3087 static const struct message sc_minimize_messages
[] =
3089 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
3090 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3091 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3092 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3095 static const struct message sc_maximize_messages
[] =
3097 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
3098 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3099 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3100 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
3104 static const struct message normal_messages
[] =
3106 {WM_DISPLAYCHANGE
, FALSE
, 0},
3110 memset(&devmode
, 0, sizeof(devmode
));
3111 devmode
.dmSize
= sizeof(devmode
);
3112 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3113 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3114 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3115 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3116 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3117 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3119 ret
= save_display_modes(&original_modes
, &display_count
);
3120 ok(ret
, "Failed to save original display modes.\n");
3122 ddraw
= create_ddraw();
3123 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3125 memset(¶m
, 0, sizeof(param
));
3126 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
3127 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3128 ref
= IDirectDraw2_Release(ddraw
);
3129 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3131 if (!param
.user32_height
)
3133 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
3134 free(original_modes
);
3138 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3139 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
3140 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
3142 memset(&devmode
, 0, sizeof(devmode
));
3143 devmode
.dmSize
= sizeof(devmode
);
3144 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3145 devmode
.dmPelsWidth
= param
.user32_width
;
3146 devmode
.dmPelsHeight
= param
.user32_height
;
3147 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3148 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3150 ddraw
= create_ddraw();
3151 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3153 wc
.lpfnWndProc
= mode_set_proc
;
3154 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3155 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3156 wc
.lpfnWndProc
= mode_set_proc2
;
3157 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
3158 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3160 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3161 0, 0, 100, 100, 0, 0, 0, 0);
3162 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3163 0, 0, 100, 100, 0, 0, 0, 0);
3165 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3166 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3168 GetWindowRect(window
, &r
);
3169 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3170 wine_dbgstr_rect(&r
));
3172 memset(&ddsd
, 0, sizeof(ddsd
));
3173 ddsd
.dwSize
= sizeof(ddsd
);
3174 ddsd
.dwFlags
= DDSD_CAPS
;
3175 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3177 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3178 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3179 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3180 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3181 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3182 param
.user32_width
, ddsd
.dwWidth
);
3183 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3184 param
.user32_height
, ddsd
.dwHeight
);
3186 GetWindowRect(window
, &r
);
3187 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3188 wine_dbgstr_rect(&r
));
3190 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3191 expect_messages
= exclusive_messages
;
3195 hr
= IDirectDrawSurface_IsLost(primary
);
3196 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3197 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3198 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3199 hr
= IDirectDrawSurface_IsLost(primary
);
3200 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3202 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3203 expect_messages
= NULL
;
3204 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3205 "Expected screen size %lux%lu, got %lux%lu.\n",
3206 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3208 GetWindowRect(window
, &r
);
3209 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3210 wine_dbgstr_rect(&r
));
3212 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3213 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3214 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3215 param
.user32_width
, ddsd
.dwWidth
);
3216 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3217 param
.user32_height
, ddsd
.dwHeight
);
3218 IDirectDrawSurface_Release(primary
);
3220 memset(&ddsd
, 0, sizeof(ddsd
));
3221 ddsd
.dwSize
= sizeof(ddsd
);
3222 ddsd
.dwFlags
= DDSD_CAPS
;
3223 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3225 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3226 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3227 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3228 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3229 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3230 param
.ddraw_width
, ddsd
.dwWidth
);
3231 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3232 param
.ddraw_height
, ddsd
.dwHeight
);
3234 GetWindowRect(window
, &r
);
3235 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3236 wine_dbgstr_rect(&r
));
3238 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3239 expect_messages
= exclusive_messages
;
3243 hr
= IDirectDrawSurface_IsLost(primary
);
3244 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3245 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3246 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3247 hr
= IDirectDrawSurface_IsLost(primary
);
3248 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3250 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3251 expect_messages
= NULL
;
3252 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3253 "Expected screen size %lux%lu, got %lux%lu.\n",
3254 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3256 GetWindowRect(window
, &r
);
3257 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3258 wine_dbgstr_rect(&r
));
3260 expect_messages
= exclusive_focus_loss_messages
;
3261 ret
= SetForegroundWindow(GetDesktopWindow());
3262 ok(ret
, "Failed to set foreground window.\n");
3263 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3264 memset(&devmode
, 0, sizeof(devmode
));
3265 devmode
.dmSize
= sizeof(devmode
);
3266 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3267 ok(ret
, "Failed to get display mode.\n");
3268 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3269 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3270 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3272 expect_messages
= exclusive_focus_restore_messages
;
3273 ShowWindow(window
, SW_RESTORE
);
3274 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3276 GetWindowRect(window
, &r
);
3277 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3278 wine_dbgstr_rect(&r
));
3279 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3280 ok(ret
, "Failed to get display mode.\n");
3281 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3282 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %lux%lu.\n",
3283 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3285 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3286 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3287 /* Normally the primary should be restored here. Unfortunately this causes the
3288 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3289 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3290 * the point of the GetSurfaceDesc call. */
3292 expect_messages
= sc_minimize_messages
;
3293 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3294 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3295 expect_messages
= NULL
;
3297 expect_messages
= sc_restore_messages
;
3298 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3299 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3300 expect_messages
= NULL
;
3302 expect_messages
= sc_maximize_messages
;
3303 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3304 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3305 expect_messages
= NULL
;
3307 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3308 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3310 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3311 expect_messages
= exclusive_messages
;
3315 hr
= IDirectDrawSurface_IsLost(primary
);
3316 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3317 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3318 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3319 hr
= IDirectDrawSurface_IsLost(primary
);
3320 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3323 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3324 expect_messages
= NULL
;
3326 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3327 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3328 "Expected screen size %lux%lu, got %lux%lu.\n",
3329 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3331 GetWindowRect(window
, &r
);
3333 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3334 wine_dbgstr_rect(&r
));
3336 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3337 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3338 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3339 param
.ddraw_width
, ddsd
.dwWidth
);
3340 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3341 param
.ddraw_height
, ddsd
.dwHeight
);
3342 IDirectDrawSurface_Release(primary
);
3345 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3346 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3349 if (IsIconic(window
)) /* make sure the window is restored, working around some Wine/X11 race condition */
3351 ShowWindow(window
, SW_RESTORE
);
3355 memset(&ddsd
, 0, sizeof(ddsd
));
3356 ddsd
.dwSize
= sizeof(ddsd
);
3357 ddsd
.dwFlags
= DDSD_CAPS
;
3358 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3360 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3361 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3362 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3363 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3364 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3365 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3366 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3367 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3369 GetWindowRect(window
, &r
);
3371 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3372 wine_dbgstr_rect(&r
));
3374 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3375 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3377 GetWindowRect(window
, &r
);
3379 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3380 wine_dbgstr_rect(&r
));
3382 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3383 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3384 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3385 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3386 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3387 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3388 IDirectDrawSurface_Release(primary
);
3390 memset(&ddsd
, 0, sizeof(ddsd
));
3391 ddsd
.dwSize
= sizeof(ddsd
);
3392 ddsd
.dwFlags
= DDSD_CAPS
;
3393 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3395 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3396 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3397 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3398 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3399 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3400 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3401 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3402 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3404 GetWindowRect(window
, &r
);
3406 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3407 wine_dbgstr_rect(&r
));
3409 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3410 expect_messages
= normal_messages
;
3414 hr
= IDirectDrawSurface_IsLost(primary
);
3415 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3416 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3417 devmode
.dmPelsWidth
= param
.user32_width
;
3418 devmode
.dmPelsHeight
= param
.user32_height
;
3419 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3420 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3421 hr
= IDirectDrawSurface_IsLost(primary
);
3422 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3424 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3425 expect_messages
= NULL
;
3426 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3428 GetWindowRect(window
, &r
);
3430 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3431 wine_dbgstr_rect(&r
));
3433 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3434 expect_messages
= normal_messages
;
3438 hr
= IDirectDrawSurface_Restore(primary
);
3439 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3440 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3441 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3443 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3444 IDirectDrawSurface_Release(primary
);
3445 IDirectDraw2_Release(ddraw
);
3448 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3449 hr
= IDirectDrawSurface_Restore(primary
);
3450 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3451 hr
= IDirectDrawSurface_IsLost(primary
);
3452 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3454 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3455 expect_messages
= NULL
;
3456 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3458 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
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3466 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3467 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3468 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3469 IDirectDrawSurface_Release(primary
);
3471 memset(&ddsd
, 0, sizeof(ddsd
));
3472 ddsd
.dwSize
= sizeof(ddsd
);
3473 ddsd
.dwFlags
= DDSD_CAPS
;
3474 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3476 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3477 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3478 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3479 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3480 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3481 param
.ddraw_width
, ddsd
.dwWidth
);
3482 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3483 param
.ddraw_height
, ddsd
.dwHeight
);
3485 GetWindowRect(window
, &r
);
3487 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3488 wine_dbgstr_rect(&r
));
3490 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3491 expect_messages
= normal_messages
;
3495 hr
= IDirectDrawSurface_IsLost(primary
);
3496 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3497 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3498 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3499 hr
= IDirectDrawSurface_IsLost(primary
);
3500 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3502 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3503 expect_messages
= NULL
;
3504 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3506 GetWindowRect(window
, &r
);
3508 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3509 wine_dbgstr_rect(&r
));
3511 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3512 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3513 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3514 param
.ddraw_width
, ddsd
.dwWidth
);
3515 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3516 param
.ddraw_height
, ddsd
.dwHeight
);
3517 IDirectDrawSurface_Release(primary
);
3519 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3520 ok(ret
, "Failed to get display mode.\n");
3521 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3522 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3523 "Expected resolution %lux%lu, got %lux%lu.\n",
3524 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3525 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3526 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3527 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3529 memset(&ddsd
, 0, sizeof(ddsd
));
3530 ddsd
.dwSize
= sizeof(ddsd
);
3531 ddsd
.dwFlags
= DDSD_CAPS
;
3532 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3534 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3535 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3536 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3537 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3538 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3539 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3540 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3541 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3543 GetWindowRect(window
, &r
);
3545 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3546 wine_dbgstr_rect(&r
));
3548 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3549 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3550 * not DDSCL_FULLSCREEN. */
3551 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3552 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3554 GetWindowRect(window
, &r
);
3556 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3557 wine_dbgstr_rect(&r
));
3559 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3560 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3561 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3562 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3563 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3564 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3565 IDirectDrawSurface_Release(primary
);
3567 memset(&ddsd
, 0, sizeof(ddsd
));
3568 ddsd
.dwSize
= sizeof(ddsd
);
3569 ddsd
.dwFlags
= DDSD_CAPS
;
3570 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3572 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3573 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3574 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3575 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3576 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3577 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3578 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3579 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3581 GetWindowRect(window
, &r
);
3583 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3584 wine_dbgstr_rect(&r
));
3586 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3587 expect_messages
= normal_messages
;
3591 hr
= IDirectDrawSurface_IsLost(primary
);
3592 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3593 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3594 devmode
.dmPelsWidth
= param
.user32_width
;
3595 devmode
.dmPelsHeight
= param
.user32_height
;
3596 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3597 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3598 hr
= IDirectDrawSurface_IsLost(primary
);
3599 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3601 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3602 expect_messages
= NULL
;
3603 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3605 GetWindowRect(window
, &r
);
3607 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3608 wine_dbgstr_rect(&r
));
3610 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3611 expect_messages
= normal_messages
;
3615 hr
= IDirectDrawSurface_Restore(primary
);
3616 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3617 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3618 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3619 hr
= IDirectDrawSurface_Restore(primary
);
3620 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3621 hr
= IDirectDrawSurface_IsLost(primary
);
3622 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3624 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3625 expect_messages
= NULL
;
3626 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3628 GetWindowRect(window
, &r
);
3630 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3631 wine_dbgstr_rect(&r
));
3633 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3634 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3635 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3636 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3637 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3638 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3639 IDirectDrawSurface_Release(primary
);
3641 memset(&ddsd
, 0, sizeof(ddsd
));
3642 ddsd
.dwSize
= sizeof(ddsd
);
3643 ddsd
.dwFlags
= DDSD_CAPS
;
3644 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3646 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3647 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3648 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3649 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3650 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3651 param
.ddraw_width
, ddsd
.dwWidth
);
3652 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3653 param
.ddraw_height
, ddsd
.dwHeight
);
3655 GetWindowRect(window
, &r
);
3657 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3658 wine_dbgstr_rect(&r
));
3660 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3661 expect_messages
= normal_messages
;
3665 hr
= IDirectDrawSurface_IsLost(primary
);
3666 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3667 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3668 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3669 hr
= IDirectDrawSurface_IsLost(primary
);
3670 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3672 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3673 expect_messages
= NULL
;
3674 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3676 GetWindowRect(window
, &r
);
3678 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3679 wine_dbgstr_rect(&r
));
3681 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3682 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3683 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3684 param
.ddraw_width
, ddsd
.dwWidth
);
3685 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3686 param
.ddraw_height
, ddsd
.dwHeight
);
3687 IDirectDrawSurface_Release(primary
);
3689 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3690 ok(ret
, "Failed to get display mode.\n");
3691 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3692 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3693 "Expected resolution %lux%lu, got %lux%lu.\n",
3694 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3695 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3696 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3697 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3699 memset(&ddsd
, 0, sizeof(ddsd
));
3700 ddsd
.dwSize
= sizeof(ddsd
);
3701 ddsd
.dwFlags
= DDSD_CAPS
;
3702 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3704 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3705 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3706 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3707 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3708 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3709 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3710 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3711 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3712 IDirectDrawSurface_Release(primary
);
3714 GetWindowRect(window
, &r
);
3716 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3717 wine_dbgstr_rect(&r
));
3719 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3720 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3721 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3722 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3723 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3725 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3726 expect_messages
= exclusive_messages
;
3730 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3731 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3733 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3734 expect_messages
= NULL
;
3735 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3736 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3737 "Expected screen size %lux%lu, got %lux%lu.\n",
3738 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3739 screen_size
.cx
, screen_size
.cy
);
3741 GetWindowRect(window
, &r
);
3742 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3743 wine_dbgstr_rect(&r
));
3745 memset(&ddsd
, 0, sizeof(ddsd
));
3746 ddsd
.dwSize
= sizeof(ddsd
);
3747 ddsd
.dwFlags
= DDSD_CAPS
;
3748 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3750 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3751 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3752 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3753 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3754 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3755 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3756 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3757 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3758 IDirectDrawSurface_Release(primary
);
3760 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3761 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3762 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3763 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3764 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3766 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3767 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3769 memset(&ddsd
, 0, sizeof(ddsd
));
3770 ddsd
.dwSize
= sizeof(ddsd
);
3771 ddsd
.dwFlags
= DDSD_CAPS
;
3772 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3774 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3775 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3776 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3777 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3778 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3779 param
.ddraw_width
, ddsd
.dwWidth
);
3780 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3781 param
.ddraw_height
, ddsd
.dwHeight
);
3782 IDirectDrawSurface_Release(primary
);
3784 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3785 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3787 flush_events(); /* flush any pending window resize X11 event */
3789 /* If the window is changed at the same time, messages are sent to the new window. */
3790 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3791 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3792 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3793 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3795 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3796 expect_messages
= exclusive_messages
;
3799 screen_size2
.cx
= 0;
3800 screen_size2
.cy
= 0;
3802 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3803 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3805 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3806 expect_messages
= NULL
;
3807 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n",
3808 screen_size
.cx
, screen_size
.cy
);
3809 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3810 "Expected screen size 2 %lux%lu, got %lux%lu.\n",
3811 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3813 GetWindowRect(window
, &r
);
3814 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3815 wine_dbgstr_rect(&r
));
3816 GetWindowRect(window2
, &r
);
3817 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3818 wine_dbgstr_rect(&r
));
3820 memset(&ddsd
, 0, sizeof(ddsd
));
3821 ddsd
.dwSize
= sizeof(ddsd
);
3822 ddsd
.dwFlags
= DDSD_CAPS
;
3823 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3825 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3826 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3827 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3828 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3829 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3830 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3831 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3832 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3833 IDirectDrawSurface_Release(primary
);
3835 ref
= IDirectDraw2_Release(ddraw
);
3836 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3838 GetWindowRect(window
, &r
);
3839 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3840 wine_dbgstr_rect(&r
));
3842 ret
= restore_display_modes(original_modes
, display_count
);
3843 ok(ret
, "Failed to restore display modes.\n");
3845 /* Test that no mode restorations if no mode changes happened */
3846 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3847 devmode
.dmPelsWidth
= param
.user32_width
;
3848 devmode
.dmPelsHeight
= param
.user32_height
;
3849 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3850 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3852 ddraw
= create_ddraw();
3853 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3854 ref
= IDirectDraw2_Release(ddraw
);
3855 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3857 memset(&devmode2
, 0, sizeof(devmode2
));
3858 devmode2
.dmSize
= sizeof(devmode2
);
3859 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3860 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3861 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3862 ret
= restore_display_modes(original_modes
, display_count
);
3863 ok(ret
, "Failed to restore display modes.\n");
3865 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3866 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3867 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3869 ddraw
= create_ddraw();
3870 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3871 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3872 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3873 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3874 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3875 ref
= IDirectDraw2_Release(ddraw
);
3876 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3878 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3879 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3880 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3881 ret
= restore_display_modes(original_modes
, display_count
);
3882 ok(ret
, "Failed to restore display modes.\n");
3884 /* Test that mode restorations use display settings in the registry after ddraw object releases
3885 * if SetDisplayMode() was called */
3886 ddraw
= create_ddraw();
3887 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3888 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3889 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3891 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3892 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3894 ref
= IDirectDraw2_Release(ddraw
);
3895 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3897 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3898 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3899 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3900 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3901 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3902 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3903 ret
= restore_display_modes(original_modes
, display_count
);
3904 ok(ret
, "Failed to restore display modes.\n");
3906 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3907 ddraw
= create_ddraw();
3908 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3909 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3910 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3912 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3913 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3915 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
3916 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3918 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3919 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3920 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3921 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3922 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3923 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3925 ref
= IDirectDraw2_Release(ddraw
);
3926 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3929 expect_messages
= NULL
;
3930 DestroyWindow(window
);
3931 DestroyWindow(window2
);
3932 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3933 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3934 ret
= restore_display_modes(original_modes
, display_count
);
3935 ok(ret
, "Failed to restore display modes.\n");
3936 free(original_modes
);
3939 static void test_coop_level_mode_set_multi(void)
3941 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3942 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3943 WCHAR second_monitor_name
[CCHDEVICENAME
];
3944 IDirectDraw2
*ddraw1
, *ddraw2
;
3952 memset(&devmode
, 0, sizeof(devmode
));
3953 devmode
.dmSize
= sizeof(devmode
);
3954 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3955 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3956 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3957 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3958 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3959 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3961 ret
= save_display_modes(&original_modes
, &display_count
);
3962 ok(ret
, "Failed to save original display modes.\n");
3964 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3965 0, 0, 100, 100, 0, 0, 0, 0);
3966 ddraw1
= create_ddraw();
3967 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3969 /* With just a single ddraw object, the display mode is restored on
3971 hr
= set_display_mode(ddraw1
, 800, 600);
3972 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3974 win_skip("Broken SetDisplayMode(), skipping test.\n");
3975 IDirectDraw2_Release(ddraw1
);
3976 DestroyWindow(window
);
3979 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3980 w
= GetSystemMetrics(SM_CXSCREEN
);
3981 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3982 h
= GetSystemMetrics(SM_CYSCREEN
);
3983 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3985 ref
= IDirectDraw2_Release(ddraw1
);
3986 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3987 w
= GetSystemMetrics(SM_CXSCREEN
);
3988 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3989 h
= GetSystemMetrics(SM_CYSCREEN
);
3990 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3992 /* When there are multiple ddraw objects, the display mode is restored to
3993 * the initial mode, before the first SetDisplayMode() call. */
3994 ddraw1
= create_ddraw();
3995 hr
= set_display_mode(ddraw1
, 800, 600);
3996 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3997 w
= GetSystemMetrics(SM_CXSCREEN
);
3998 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3999 h
= GetSystemMetrics(SM_CYSCREEN
);
4000 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4002 ddraw2
= create_ddraw();
4003 hr
= set_display_mode(ddraw2
, 640, 480);
4004 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4005 w
= GetSystemMetrics(SM_CXSCREEN
);
4006 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4007 h
= GetSystemMetrics(SM_CYSCREEN
);
4008 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4010 ref
= IDirectDraw2_Release(ddraw2
);
4011 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4012 w
= GetSystemMetrics(SM_CXSCREEN
);
4013 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4014 h
= GetSystemMetrics(SM_CYSCREEN
);
4015 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4017 ref
= IDirectDraw2_Release(ddraw1
);
4018 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4019 w
= GetSystemMetrics(SM_CXSCREEN
);
4020 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4021 h
= GetSystemMetrics(SM_CYSCREEN
);
4022 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4024 /* Regardless of release ordering. */
4025 ddraw1
= create_ddraw();
4026 hr
= set_display_mode(ddraw1
, 800, 600);
4027 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4028 w
= GetSystemMetrics(SM_CXSCREEN
);
4029 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4030 h
= GetSystemMetrics(SM_CYSCREEN
);
4031 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4033 ddraw2
= create_ddraw();
4034 hr
= set_display_mode(ddraw2
, 640, 480);
4035 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4036 w
= GetSystemMetrics(SM_CXSCREEN
);
4037 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4038 h
= GetSystemMetrics(SM_CYSCREEN
);
4039 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4041 ref
= IDirectDraw2_Release(ddraw1
);
4042 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4043 w
= GetSystemMetrics(SM_CXSCREEN
);
4044 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4045 h
= GetSystemMetrics(SM_CYSCREEN
);
4046 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4048 ref
= IDirectDraw2_Release(ddraw2
);
4049 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4050 w
= GetSystemMetrics(SM_CXSCREEN
);
4051 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4052 h
= GetSystemMetrics(SM_CYSCREEN
);
4053 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4055 /* But only for ddraw objects that called SetDisplayMode(). */
4056 ddraw1
= create_ddraw();
4057 ddraw2
= create_ddraw();
4058 hr
= set_display_mode(ddraw2
, 640, 480);
4059 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4060 w
= GetSystemMetrics(SM_CXSCREEN
);
4061 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4062 h
= GetSystemMetrics(SM_CYSCREEN
);
4063 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4065 ref
= IDirectDraw2_Release(ddraw1
);
4066 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4067 w
= GetSystemMetrics(SM_CXSCREEN
);
4068 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4069 h
= GetSystemMetrics(SM_CYSCREEN
);
4070 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4072 ref
= IDirectDraw2_Release(ddraw2
);
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 /* If there's a ddraw object that's currently in exclusive mode, it blocks
4080 * restoring the display mode. */
4081 ddraw1
= create_ddraw();
4082 hr
= set_display_mode(ddraw1
, 800, 600);
4083 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4084 w
= GetSystemMetrics(SM_CXSCREEN
);
4085 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4086 h
= GetSystemMetrics(SM_CYSCREEN
);
4087 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4089 ddraw2
= create_ddraw();
4090 hr
= set_display_mode(ddraw2
, 640, 480);
4091 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4092 w
= GetSystemMetrics(SM_CXSCREEN
);
4093 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4094 h
= GetSystemMetrics(SM_CYSCREEN
);
4095 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4097 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4098 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4100 ref
= IDirectDraw2_Release(ddraw1
);
4101 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4102 w
= GetSystemMetrics(SM_CXSCREEN
);
4103 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4104 h
= GetSystemMetrics(SM_CYSCREEN
);
4105 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4107 ref
= IDirectDraw2_Release(ddraw2
);
4108 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4109 w
= GetSystemMetrics(SM_CXSCREEN
);
4110 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4111 h
= GetSystemMetrics(SM_CYSCREEN
);
4112 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4114 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
4115 ddraw1
= create_ddraw();
4116 hr
= set_display_mode(ddraw1
, 800, 600);
4117 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4118 w
= GetSystemMetrics(SM_CXSCREEN
);
4119 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4120 h
= GetSystemMetrics(SM_CYSCREEN
);
4121 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4123 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4124 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4126 ddraw2
= create_ddraw();
4127 hr
= set_display_mode(ddraw2
, 640, 480);
4128 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
4130 ref
= IDirectDraw2_Release(ddraw1
);
4131 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4132 w
= GetSystemMetrics(SM_CXSCREEN
);
4133 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4134 h
= GetSystemMetrics(SM_CYSCREEN
);
4135 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4137 ref
= IDirectDraw2_Release(ddraw2
);
4138 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4139 w
= GetSystemMetrics(SM_CXSCREEN
);
4140 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4141 h
= GetSystemMetrics(SM_CYSCREEN
);
4142 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4144 if (display_count
< 2)
4146 skip("Following tests require two monitors.\n");
4150 ret
= restore_display_modes(original_modes
, display_count
);
4151 ok(ret
, "Failed to restore display modes.\n");
4153 second_monitor_name
[0] = '\0';
4154 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
4156 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
4158 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
4162 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
4163 memset(&old_devmode
, 0, sizeof(old_devmode
));
4164 old_devmode
.dmSize
= sizeof(old_devmode
);
4165 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
4166 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4168 devmode
= old_devmode
;
4169 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
4171 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4172 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
4175 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4176 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
4177 "Failed to find a different mode for the second monitor.\n");
4179 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
4180 ddraw1
= create_ddraw();
4181 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4182 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4183 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4185 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4186 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4188 memset(&devmode2
, 0, sizeof(devmode2
));
4189 devmode2
.dmSize
= sizeof(devmode2
);
4190 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4191 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4192 if (compare_mode_rect(&devmode2
, &old_devmode
))
4194 skip("Failed to change display settings of the second monitor.\n");
4195 ref
= IDirectDraw2_Release(ddraw1
);
4196 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4200 hr
= IDirectDraw2_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
4201 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4202 ref
= IDirectDraw2_Release(ddraw1
);
4203 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4205 memset(&devmode3
, 0, sizeof(devmode3
));
4206 devmode3
.dmSize
= sizeof(devmode3
);
4207 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
4208 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4209 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
4210 ret
= restore_display_modes(original_modes
, display_count
);
4211 ok(ret
, "Failed to restore display modes.\n");
4213 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
4214 * SetDisplayMode() was called */
4215 ddraw1
= create_ddraw();
4216 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4217 hr
= set_display_mode(ddraw1
, 800, 600);
4218 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4220 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4221 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4223 ref
= IDirectDraw2_Release(ddraw1
);
4224 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4226 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4227 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4228 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4229 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4230 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4231 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4232 ret
= restore_display_modes(original_modes
, display_count
);
4233 ok(ret
, "Failed to restore display modes.\n");
4235 /* Test that mode restorations happen for non-primary monitors as well */
4236 ddraw1
= create_ddraw();
4237 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4238 hr
= set_display_mode(ddraw1
, 800, 600);
4239 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4241 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4242 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4244 hr
= IDirectDraw2_RestoreDisplayMode(ddraw1
);
4245 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4247 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4248 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4249 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4250 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4251 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4252 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4254 ref
= IDirectDraw2_Release(ddraw1
);
4255 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4256 ret
= restore_display_modes(original_modes
, display_count
);
4257 ok(ret
, "Failed to restore display modes.\n");
4259 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4260 ddraw1
= create_ddraw();
4261 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4262 hr
= set_display_mode(ddraw1
, 800, 600);
4263 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4265 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4266 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4267 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4269 ref
= IDirectDraw2_Release(ddraw1
);
4270 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4272 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4273 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4274 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4275 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4276 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4277 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4278 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4279 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4280 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4281 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4282 ret
= restore_display_modes(original_modes
, display_count
);
4283 ok(ret
, "Failed to restore display modes.\n");
4285 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4286 * objects and one of them restores display mode */
4287 ddraw1
= create_ddraw();
4288 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4289 ddraw2
= create_ddraw();
4290 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4291 hr
= set_display_mode(ddraw1
, 800, 600);
4292 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4293 hr
= set_display_mode(ddraw2
, 640, 480);
4294 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4296 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4297 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4299 hr
= IDirectDraw2_RestoreDisplayMode(ddraw2
);
4300 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4302 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4303 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4304 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4305 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4306 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4307 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4309 ref
= IDirectDraw2_Release(ddraw2
);
4310 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4311 ref
= IDirectDraw2_Release(ddraw1
);
4312 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4313 ret
= restore_display_modes(original_modes
, display_count
);
4314 ok(ret
, "Failed to restore display modes.\n");
4316 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4317 * objects and one of them got released */
4318 ddraw1
= create_ddraw();
4319 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4320 ddraw2
= create_ddraw();
4321 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4322 hr
= set_display_mode(ddraw1
, 800, 600);
4323 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4324 hr
= set_display_mode(ddraw2
, 640, 480);
4325 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4327 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4328 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4330 ref
= IDirectDraw2_Release(ddraw2
);
4331 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4333 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4334 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4335 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4336 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4337 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4338 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4340 ref
= IDirectDraw2_Release(ddraw1
);
4341 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4344 DestroyWindow(window
);
4345 ret
= restore_display_modes(original_modes
, display_count
);
4346 ok(ret
, "Failed to restore display modes.\n");
4347 free(original_modes
);
4350 static void test_initialize(void)
4352 IDirectDraw2
*ddraw
;
4355 ddraw
= create_ddraw();
4356 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4358 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4359 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx.\n", hr
);
4360 IDirectDraw2_Release(ddraw
);
4363 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw2
, (void **)&ddraw
);
4364 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw2 instance, hr %#lx.\n", hr
);
4365 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4366 ok(hr
== DD_OK
, "Initialize returned hr %#lx, expected DD_OK.\n", hr
);
4367 hr
= IDirectDraw2_Initialize(ddraw
, NULL
);
4368 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4369 IDirectDraw2_Release(ddraw
);
4373 static void test_coop_level_surf_create(void)
4375 IDirectDrawSurface
*surface
;
4376 IDirectDraw2
*ddraw
;
4380 ddraw
= create_ddraw();
4381 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4383 memset(&ddsd
, 0, sizeof(ddsd
));
4384 ddsd
.dwSize
= sizeof(ddsd
);
4385 ddsd
.dwFlags
= DDSD_CAPS
;
4386 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4387 surface
= (void *)0xdeadbeef;
4388 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4389 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4390 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4392 surface
= (void *)0xdeadbeef;
4393 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4394 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4395 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4397 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4398 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4400 surface
= (void *)0xdeadbeef;
4401 hr
= IDirectDraw2_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4402 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#lx.\n", hr
);
4403 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4405 IDirectDraw2_Release(ddraw
);
4408 static void test_coop_level_multi_window(void)
4410 HWND window1
, window2
;
4411 IDirectDraw2
*ddraw
;
4414 window1
= create_window();
4415 window2
= create_window();
4416 ddraw
= create_ddraw();
4417 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4419 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4420 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4421 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4422 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4423 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4424 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4426 IDirectDraw2_Release(ddraw
);
4427 DestroyWindow(window2
);
4428 DestroyWindow(window1
);
4431 static void test_clear_rect_count(void)
4433 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4434 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
4435 IDirect3DViewport2
*viewport
;
4436 IDirect3DDevice2
*device
;
4437 IDirectDrawSurface
*rt
;
4438 IDirectDraw2
*ddraw
;
4443 window
= create_window();
4444 ddraw
= create_ddraw();
4445 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4446 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4448 skip("Failed to create a 3D device, skipping test.\n");
4449 IDirectDraw2_Release(ddraw
);
4450 DestroyWindow(window
);
4454 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4455 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4457 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
4458 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
4459 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
4460 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
4462 viewport
= create_viewport(device
, 0, 0, 640, 480);
4463 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4464 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
4466 viewport_set_background(device
, viewport
, white
);
4467 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4468 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4469 viewport_set_background(device
, viewport
, red
);
4470 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4471 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4472 viewport_set_background(device
, viewport
, green
);
4473 hr
= IDirect3DViewport2_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
4474 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4475 viewport_set_background(device
, viewport
, blue
);
4476 hr
= IDirect3DViewport2_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4477 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4479 color
= get_surface_color(rt
, 320, 240);
4480 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4481 "Got unexpected color 0x%08x.\n", color
);
4483 IDirectDrawSurface_Release(rt
);
4484 destroy_viewport(device
, viewport
);
4485 destroy_material(white
);
4486 destroy_material(red
);
4487 destroy_material(green
);
4488 destroy_material(blue
);
4489 IDirect3DDevice2_Release(device
);
4490 IDirectDraw2_Release(ddraw
);
4491 DestroyWindow(window
);
4494 static BOOL
test_mode_restored(IDirectDraw2
*ddraw
, HWND window
)
4496 DDSURFACEDESC ddsd1
, ddsd2
;
4499 memset(&ddsd1
, 0, sizeof(ddsd1
));
4500 ddsd1
.dwSize
= sizeof(ddsd1
);
4501 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd1
);
4502 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
4504 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4505 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4506 hr
= set_display_mode(ddraw
, 640, 480);
4507 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4508 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4509 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4511 memset(&ddsd2
, 0, sizeof(ddsd2
));
4512 ddsd2
.dwSize
= sizeof(ddsd2
);
4513 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &ddsd2
);
4514 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
4515 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
4516 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4518 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4521 static void test_coop_level_versions(void)
4527 IDirectDrawSurface
*surface
;
4528 IDirectDraw2
*ddraw2
;
4531 window
= create_window();
4532 ddraw2
= create_ddraw();
4533 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4534 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4535 restored
= test_mode_restored(ddraw2
, window
);
4536 ok(restored
, "Display mode not restored in new ddraw object\n");
4538 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4539 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4540 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4542 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4543 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
4544 restored
= test_mode_restored(ddraw2
, window
);
4545 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4547 /* A successful one does */
4548 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4549 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4550 restored
= test_mode_restored(ddraw2
, window
);
4551 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4553 IDirectDraw_Release(ddraw
);
4554 IDirectDraw2_Release(ddraw2
);
4556 ddraw2
= create_ddraw();
4557 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4558 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4559 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4561 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4562 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4563 restored
= test_mode_restored(ddraw2
, window
);
4564 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4566 IDirectDraw_Release(ddraw
);
4567 IDirectDraw2_Release(ddraw2
);
4569 /* A failing call does not restore the ddraw2+ behavior */
4570 ddraw2
= create_ddraw();
4571 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4572 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4573 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4575 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4576 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4577 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4578 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
4579 restored
= test_mode_restored(ddraw2
, window
);
4580 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4582 IDirectDraw_Release(ddraw
);
4583 IDirectDraw2_Release(ddraw2
);
4585 /* Neither does a sequence of successful calls with the new interface */
4586 ddraw2
= create_ddraw();
4587 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4588 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4589 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4591 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4592 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4593 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4594 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4595 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4596 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4598 restored
= test_mode_restored(ddraw2
, window
);
4599 ok(!restored
, "Display mode restored after ddraw1-ddraw2 SetCooperativeLevel() call sequence\n");
4600 IDirectDraw_Release(ddraw
);
4601 IDirectDraw2_Release(ddraw2
);
4603 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4604 ddraw2
= create_ddraw();
4605 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4606 hr
= IDirectDraw2_QueryInterface(ddraw2
, &IID_IDirectDraw
, (void **)&ddraw
);
4607 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
4609 hr
= IDirectDraw2_SetCooperativeLevel(ddraw2
, window
, DDSCL_NORMAL
);
4610 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4612 memset(&ddsd
, 0, sizeof(ddsd
));
4613 ddsd
.dwSize
= sizeof(ddsd
);
4614 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4615 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4616 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4617 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4618 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#lx.\n", hr
);
4619 IDirectDrawSurface_Release(surface
);
4620 restored
= test_mode_restored(ddraw2
, window
);
4621 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4623 IDirectDraw_Release(ddraw
);
4624 IDirectDraw2_Release(ddraw2
);
4625 DestroyWindow(window
);
4628 static void test_lighting_interface_versions(void)
4630 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4631 IDirect3DMaterial2
*emissive
, *background
;
4632 IDirect3DViewport2
*viewport
;
4633 IDirect3DDevice2
*device
;
4634 IDirectDrawSurface
*rt
;
4635 unsigned int color
, i
;
4636 IDirectDraw2
*ddraw
;
4639 D3DMATERIALHANDLE mat_handle
;
4642 static D3DVERTEX quad
[] =
4644 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4645 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4646 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4647 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4649 static D3DLVERTEX lquad
[] =
4651 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4652 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4653 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4654 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4656 static D3DTLVERTEX tlquad
[] =
4658 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4659 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4660 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4661 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4665 D3DVERTEXTYPE vertextype
;
4667 DWORD d3drs_lighting
, d3drs_specular
;
4673 /* Lighting is enabled when D3DVT_VERTEX is used and D3DDP_DONOTLIGHT is not
4674 * set. D3DVT_VERTEX has diffuse = 0xffffffff and specular = 0x00000000, as
4675 * in later d3d versions */
4676 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
4677 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
4678 { D3DVT_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4679 { D3DVT_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4680 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
4681 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
4682 { D3DVT_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4683 { D3DVT_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4685 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
4686 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
4687 { D3DVT_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4688 { D3DVT_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4689 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
4690 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
4691 { D3DVT_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4692 { D3DVT_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4694 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
4695 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
4696 { D3DVT_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4697 { D3DVT_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4698 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
4699 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
4700 { D3DVT_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4701 { D3DVT_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4704 window
= create_window();
4705 ddraw
= create_ddraw();
4706 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4707 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4709 skip("Failed to create a 3D device, skipping test.\n");
4710 IDirectDraw2_Release(ddraw
);
4711 DestroyWindow(window
);
4715 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
4716 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4718 viewport
= create_viewport(device
, 0, 0, 640, 480);
4719 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
4720 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
4722 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4723 hr
= IDirect3DMaterial2_GetHandle(emissive
, device
, &mat_handle
);
4724 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
4725 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4726 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
4727 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
4728 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#lx.\n", hr
);
4730 background
= create_diffuse_material(device
, 0.1f
, 0.1f
, 0.1f
, 0.1f
);
4731 viewport_set_background(device
, viewport
, background
);
4733 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
4734 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#lx.\n", hr
);
4735 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#lx, expected TRUE.\n", rs
);
4737 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4739 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4740 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4742 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
4743 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#lx.\n", hr
);
4744 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4745 tests
[i
].d3drs_specular
);
4746 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#lx.\n", hr
);
4748 hr
= IDirect3DDevice2_BeginScene(device
);
4749 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
4750 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4751 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4752 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
4753 hr
= IDirect3DDevice2_EndScene(device
);
4754 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
4756 color
= get_surface_color(rt
, 320, 240);
4757 ok(compare_color(color
, tests
[i
].color
, 1),
4758 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4759 color
, tests
[i
].color
, i
);
4762 destroy_material(background
);
4763 destroy_material(emissive
);
4764 destroy_viewport(device
, viewport
);
4765 IDirectDrawSurface_Release(rt
);
4766 IDirect3DDevice2_Release(device
);
4767 ref
= IDirectDraw2_Release(ddraw
);
4768 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4769 DestroyWindow(window
);
4775 IDirectDraw2
*ddraw
;
4778 } activateapp_testdata
;
4780 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4782 if (message
== WM_ACTIVATEAPP
)
4784 if (activateapp_testdata
.ddraw
)
4787 activateapp_testdata
.received
= FALSE
;
4788 hr
= IDirectDraw2_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4789 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4790 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#lx.\n", hr
);
4791 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4793 activateapp_testdata
.received
= TRUE
;
4796 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4799 static void test_coop_level_activateapp(void)
4801 IDirectDraw2
*ddraw
;
4806 IDirectDrawSurface
*surface
;
4808 ddraw
= create_ddraw();
4809 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4811 wc
.lpfnWndProc
= activateapp_test_proc
;
4812 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4813 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4815 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4816 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4818 /* Exclusive with window already active. */
4819 SetForegroundWindow(window
);
4820 activateapp_testdata
.received
= FALSE
;
4821 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4822 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4823 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4824 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4825 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4827 /* Exclusive with window not active. */
4828 SetForegroundWindow(GetDesktopWindow());
4829 activateapp_testdata
.received
= FALSE
;
4830 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4831 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4832 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4833 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4834 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4836 /* Normal with window not active, then exclusive with the same window. */
4837 SetForegroundWindow(GetDesktopWindow());
4838 activateapp_testdata
.received
= FALSE
;
4839 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4840 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4841 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4842 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4843 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4844 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4845 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4846 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4848 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4849 SetForegroundWindow(GetDesktopWindow());
4850 activateapp_testdata
.received
= FALSE
;
4851 activateapp_testdata
.ddraw
= ddraw
;
4852 activateapp_testdata
.window
= window
;
4853 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4854 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4855 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4856 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4857 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4858 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4860 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4861 * succeeding. Another switch to exclusive and back to normal is needed to release the
4862 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4863 * WM_ACTIVATEAPP messages. */
4864 activateapp_testdata
.ddraw
= NULL
;
4865 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4866 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4867 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4868 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4870 /* Setting DDSCL_NORMAL with recursive invocation. */
4871 SetForegroundWindow(GetDesktopWindow());
4872 activateapp_testdata
.received
= FALSE
;
4873 activateapp_testdata
.ddraw
= ddraw
;
4874 activateapp_testdata
.window
= window
;
4875 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4876 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4877 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4878 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4880 /* DDraw is in exclusive mode now. */
4881 memset(&ddsd
, 0, sizeof(ddsd
));
4882 ddsd
.dwSize
= sizeof(ddsd
);
4883 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4884 ddsd
.dwBackBufferCount
= 1;
4885 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4886 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4887 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
4888 IDirectDrawSurface_Release(surface
);
4890 /* Recover again, just to be sure. */
4891 activateapp_testdata
.ddraw
= NULL
;
4892 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4893 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4894 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4895 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4897 DestroyWindow(window
);
4898 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4899 IDirectDraw2_Release(ddraw
);
4902 struct format_support_check
4904 const DDPIXELFORMAT
*format
;
4908 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4910 struct format_support_check
*format
= ctx
;
4912 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4914 format
->supported
= TRUE
;
4915 return DDENUMRET_CANCEL
;
4918 return DDENUMRET_OK
;
4921 static void test_unsupported_formats(void)
4924 BOOL expect_success
;
4926 IDirectDraw2
*ddraw
;
4927 IDirect3DDevice2
*device
;
4928 IDirectDrawSurface
*surface
;
4931 DWORD expected_caps
;
4942 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4943 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4949 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4950 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4954 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4956 window
= create_window();
4957 ddraw
= create_ddraw();
4958 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4959 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4961 skip("Failed to create a 3D device, skipping test.\n");
4962 IDirectDraw2_Release(ddraw
);
4963 DestroyWindow(window
);
4967 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4969 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4970 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4971 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
4973 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4975 memset(&ddsd
, 0, sizeof(ddsd
));
4976 ddsd
.dwSize
= sizeof(ddsd
);
4977 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4978 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4981 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4983 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4984 expect_success
= FALSE
;
4986 expect_success
= TRUE
;
4988 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4989 ok(SUCCEEDED(hr
) == expect_success
,
4990 "Got unexpected hr %#lx for format %s, caps %#lx, expected %s.\n",
4991 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4995 memset(&ddsd
, 0, sizeof(ddsd
));
4996 ddsd
.dwSize
= sizeof(ddsd
);
4997 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4998 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5000 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
5001 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5002 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
5003 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5004 else if (check
.supported
)
5005 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5007 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5009 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
5010 "Expected caps %#lx, format %s, input caps %#lx.\n",
5011 expected_caps
, formats
[i
].name
, caps
[j
]);
5013 IDirectDrawSurface_Release(surface
);
5017 IDirect3DDevice2_Release(device
);
5018 IDirectDraw2_Release(ddraw
);
5019 DestroyWindow(window
);
5022 static void test_rt_caps(const GUID
*device_guid
)
5024 DWORD fourcc_codes
[64], fourcc_code_count
;
5025 PALETTEENTRY palette_entries
[256];
5026 IDirectDrawPalette
*palette
;
5027 IDirect3DDevice2
*device
;
5028 BOOL software_device
;
5029 IDirectDraw2
*ddraw
;
5038 static const DDPIXELFORMAT p8_fmt
=
5040 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5041 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
5043 static const DDPIXELFORMAT fourcc_fmt
=
5045 .dwSize
= sizeof(DDPIXELFORMAT
),
5046 .dwFlags
= DDPF_FOURCC
,
5047 .dwFourCC
= MAKEFOURCC('Y','U','Y','2'),
5052 const DDPIXELFORMAT
*pf
;
5054 HRESULT create_device_hr
;
5056 HRESULT alternative_set_rt_hr
;
5057 BOOL create_may_fail
;
5063 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5071 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5079 DDSCAPS_OFFSCREENPLAIN
,
5087 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5088 D3DERR_SURFACENOTINVIDMEM
,
5095 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5103 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5127 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5128 D3DERR_SURFACENOTINVIDMEM
,
5135 DDSCAPS_SYSTEMMEMORY
,
5151 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5152 DDERR_NOPALETTEATTACHED
,
5159 DDSCAPS_OFFSCREENPLAIN
,
5167 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5168 DDERR_NOPALETTEATTACHED
,
5175 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5183 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
5185 DDERR_INVALIDPIXELFORMAT
,
5187 TRUE
/* AMD Evergreen */,
5191 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5193 DDERR_INVALIDPIXELFORMAT
,
5207 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5209 DDERR_INVALIDPIXELFORMAT
,
5210 DDERR_INVALIDPIXELFORMAT
,
5211 TRUE
/* Nvidia Kepler */,
5215 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5219 TRUE
/* Nvidia Kepler */,
5223 DDSCAPS_FLIP
| DDSCAPS_COMPLEX
| DDSCAPS_OFFSCREENPLAIN
,
5230 software_device
= is_software_device_type(device_guid
);
5232 window
= create_window();
5233 ddraw
= create_ddraw();
5234 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5235 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
, NULL
)))
5237 skip("Failed to create a 3D device, skipping test.\n");
5238 IDirectDraw2_Release(ddraw
);
5239 DestroyWindow(window
);
5242 z_depth
= get_device_z_depth(device
);
5243 ok(!!z_depth
, "Failed to get device z depth.\n");
5244 IDirect3DDevice2_Release(device
);
5246 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
5248 skip("D3D interface is not available, skipping test.\n");
5252 memset(palette_entries
, 0, sizeof(palette_entries
));
5253 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
5254 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5256 memset(&hal_caps
, 0, sizeof(hal_caps
));
5257 hal_caps
.dwSize
= sizeof(hal_caps
);
5258 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
5259 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5261 fourcc_code_count
= ARRAY_SIZE(fourcc_codes
);
5262 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &fourcc_code_count
, fourcc_codes
);
5263 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5265 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5267 IDirectDrawSurface
*surface
, *rt
, *expected_rt
, *tmp
;
5268 DWORD caps_in
, expected_caps
;
5269 DDSURFACEDESC surface_desc
;
5270 IDirect3DDevice2
*device
;
5271 HRESULT expected_hr
;
5273 caps_in
= test_data
[i
].caps_in
;
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
= caps_in
;
5279 if (test_data
[i
].pf
)
5281 if (test_data
[i
].pf
->dwFlags
& DDPF_FOURCC
)
5285 for (j
= 0; j
< fourcc_code_count
; ++j
)
5287 if (test_data
[i
].pf
->dwFourCC
== fourcc_codes
[j
])
5290 if (j
== fourcc_code_count
)
5292 skip("Fourcc format %#lx is not supported, skipping test.\n", test_data
[i
].pf
->dwFourCC
);
5296 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5297 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5299 if (caps_in
& DDSCAPS_ZBUFFER
)
5301 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5302 surface_desc
.dwZBufferBitDepth
= z_depth
;
5304 if (caps_in
& DDSCAPS_FLIP
)
5306 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5307 surface_desc
.dwBackBufferCount
= 1;
5309 surface_desc
.dwWidth
= 640;
5310 surface_desc
.dwHeight
= 480;
5311 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5312 expected_hr
= DDERR_NODIRECTDRAWHW
;
5314 expected_hr
= DD_OK
;
5315 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5316 ok(hr
== expected_hr
|| broken(test_data
[i
].create_may_fail
5317 || (software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
)),
5318 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5322 memset(&surface_desc
, 0, sizeof(surface_desc
));
5323 surface_desc
.dwSize
= sizeof(surface_desc
);
5324 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5326 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
5327 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
5329 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
5331 if (caps_in
& DDSCAPS_FLIP
)
5332 expected_caps
|= DDSCAPS_FRONTBUFFER
;
5334 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
5335 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
5336 || (software_device
&& caps_in
& DDSCAPS_ZBUFFER
5337 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
5338 "Got unexpected caps %#lx, expected %#lx, test %u, software_device %u.\n",
5339 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
5341 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5343 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
5344 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
5345 ? DD_OK
: test_data
[i
].create_device_hr
))),
5346 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5350 if (hr
== DDERR_NOPALETTEATTACHED
)
5352 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
5353 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5354 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5355 if (software_device
)
5357 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5358 hr
, i
, software_device
);
5359 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
5360 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5361 hr
, i
, software_device
);
5363 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
5364 hr
, i
, software_device
);
5368 refcount
= IDirect3DDevice2_Release(device
);
5369 ok(!refcount
, "Test %u: The device was not properly freed, refcount %lu.\n", i
, refcount
);
5372 IDirectDrawSurface_Release(surface
);
5374 memset(&surface_desc
, 0, sizeof(surface_desc
));
5375 surface_desc
.dwSize
= sizeof(surface_desc
);
5376 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5377 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5378 surface_desc
.dwWidth
= 640;
5379 surface_desc
.dwHeight
= 480;
5380 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5381 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5383 hr
= IDirect3D2_CreateDevice(d3d
, device_guid
, surface
, &device
);
5384 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5387 memset(&surface_desc
, 0, sizeof(surface_desc
));
5388 surface_desc
.dwSize
= sizeof(surface_desc
);
5389 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5390 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5391 if (test_data
[i
].pf
)
5393 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5394 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
5396 if (test_data
[i
].caps_in
& DDSCAPS_ZBUFFER
)
5398 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5399 surface_desc
.dwZBufferBitDepth
= z_depth
;
5401 if (caps_in
& DDSCAPS_FLIP
)
5403 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5404 surface_desc
.dwBackBufferCount
= 1;
5406 surface_desc
.dwWidth
= 640;
5407 surface_desc
.dwHeight
= 480;
5408 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
5409 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5411 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
5412 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
5413 || broken(hr
== test_data
[i
].alternative_set_rt_hr
),
5414 "Got unexpected hr %#lx, test %u, software_device %u.\n",
5415 hr
, i
, software_device
);
5417 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
5420 expected_rt
= surface
;
5422 /* It appears the surface is set as render target in this case, but no
5423 * reference is taken. */
5424 if (hr
== DDERR_INVALIDPIXELFORMAT
)
5426 refcount
= IDirectDrawSurface_AddRef(rt
);
5427 ok(refcount
== 2, "Test %u: Got unexpected refcount %lu.\n", i
, refcount
);
5430 hr
= IDirect3DDevice2_GetRenderTarget(device
, &tmp
);
5431 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
5432 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
5434 IDirectDrawSurface_Release(tmp
);
5435 IDirectDrawSurface_Release(rt
);
5436 refcount
= IDirect3DDevice2_Release(device
);
5437 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5438 refcount
= IDirectDrawSurface_Release(surface
);
5439 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5442 IDirectDrawPalette_Release(palette
);
5443 IDirect3D2_Release(d3d
);
5446 refcount
= IDirectDraw2_Release(ddraw
);
5447 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5448 DestroyWindow(window
);
5451 static void test_primary_caps(void)
5453 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5454 IDirectDrawSurface
*surface
;
5455 DDSURFACEDESC surface_desc
;
5456 IDirectDraw2
*ddraw
;
5466 DWORD back_buffer_count
;
5474 DDSCAPS_PRIMARYSURFACE
,
5477 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
5481 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
5488 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
5495 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
5502 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
5509 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
5516 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5523 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5530 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5532 DDERR_NOEXCLUSIVEMODE
,
5536 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5537 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5543 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5544 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5547 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
5550 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5551 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
5557 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5558 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
5565 window
= create_window();
5566 ddraw
= create_ddraw();
5567 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5569 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5571 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
5572 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5574 memset(&surface_desc
, 0, sizeof(surface_desc
));
5575 surface_desc
.dwSize
= sizeof(surface_desc
);
5576 surface_desc
.dwFlags
= DDSD_CAPS
;
5577 if (test_data
[i
].back_buffer_count
!= ~0u)
5578 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5579 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5580 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5581 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5582 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
5586 memset(&surface_desc
, 0, sizeof(surface_desc
));
5587 surface_desc
.dwSize
= sizeof(surface_desc
);
5588 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5589 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
5590 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5591 "Test %u: Got unexpected caps %#lx, expected %#lx.\n",
5592 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5594 IDirectDrawSurface_Release(surface
);
5597 refcount
= IDirectDraw2_Release(ddraw
);
5598 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5599 DestroyWindow(window
);
5602 static void test_surface_lock(void)
5604 IDirectDraw2
*ddraw
;
5605 IDirectDrawSurface
*surface
;
5606 IDirect3DDevice2
*device
;
5621 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5622 "videomemory offscreenplain"
5625 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5626 "systemmemory offscreenplain"
5629 DDSCAPS_PRIMARYSURFACE
,
5633 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5634 "videomemory texture"
5637 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5638 "systemmemory texture"
5641 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5650 window
= create_window();
5651 ddraw
= create_ddraw();
5652 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5653 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5655 skip("Failed to create a 3D device, skipping test.\n");
5656 IDirectDraw2_Release(ddraw
);
5657 DestroyWindow(window
);
5660 z_depth
= get_device_z_depth(device
);
5661 ok(!!z_depth
, "Failed to get device z depth.\n");
5662 IDirect3DDevice2_Release(device
);
5664 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5666 memset(&ddsd
, 0, sizeof(ddsd
));
5667 ddsd
.dwSize
= sizeof(ddsd
);
5668 ddsd
.dwFlags
= DDSD_CAPS
;
5669 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5671 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5675 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
5677 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5678 ddsd
.dwZBufferBitDepth
= z_depth
;
5680 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5682 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5683 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5685 memset(&ddsd
, 0, sizeof(ddsd
));
5686 ddsd
.dwSize
= sizeof(ddsd
);
5687 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5688 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5691 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5692 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5695 memset(&ddsd
, 0, sizeof(ddsd
));
5696 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5697 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, tests
[i
].name
);
5699 IDirectDrawSurface_Release(surface
);
5702 refcount
= IDirectDraw2_Release(ddraw
);
5703 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5704 DestroyWindow(window
);
5707 static void test_surface_discard(void)
5709 IDirectDraw2
*ddraw
;
5710 IDirect3DDevice2
*device
;
5714 IDirectDrawSurface
*surface
, *target
;
5723 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5724 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5725 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5726 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5730 window
= create_window();
5732 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5736 /* Sigh. Anything other than the first run of the loop randomly fails with
5737 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
5738 * the blit fails, but with sleeps added between surface creation and lock
5739 * the lock can fail too. Interestingly ddraw claims the render target has
5740 * been lost, not the test surface.
5742 * Recreating ddraw every iteration seems to fix this. */
5743 ddraw
= create_ddraw();
5744 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5745 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5747 skip("Failed to create a 3D device, skipping test.\n");
5748 DestroyWindow(window
);
5749 IDirectDraw2_Release(ddraw
);
5753 hr
= IDirect3DDevice2_GetRenderTarget(device
, &target
);
5754 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5756 memset(&ddsd
, 0, sizeof(ddsd
));
5757 ddsd
.dwSize
= sizeof(ddsd
);
5758 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5759 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5762 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5765 skip("Failed to create surface, skipping.\n");
5769 memset(&ddsd
, 0, sizeof(ddsd
));
5770 ddsd
.dwSize
= sizeof(ddsd
);
5771 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5772 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5773 addr
= ddsd
.lpSurface
;
5774 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5775 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5777 memset(&ddsd
, 0, sizeof(ddsd
));
5778 ddsd
.dwSize
= sizeof(ddsd
);
5779 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5780 ok(SUCCEEDED(hr
) , "Failed to lock surface, hr %#lx.\n", hr
);
5781 discarded
= ddsd
.lpSurface
!= addr
;
5782 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5783 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5785 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
5786 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
5788 memset(&ddsd
, 0, sizeof(ddsd
));
5789 ddsd
.dwSize
= sizeof(ddsd
);
5790 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5791 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5792 discarded
|= ddsd
.lpSurface
!= addr
;
5793 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5794 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5796 IDirectDrawSurface_Release(surface
);
5798 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
5799 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
5800 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
5802 IDirectDrawSurface_Release(target
);
5803 IDirect3DDevice2_Release(device
);
5804 IDirectDraw2_Release(ddraw
);
5807 DestroyWindow(window
);
5810 static void test_flip(void)
5812 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5813 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5814 DDSCAPS caps
= {DDSCAPS_FLIP
};
5815 DDSURFACEDESC surface_desc
;
5816 unsigned int color
, i
;
5817 BOOL sysmem_primary
;
5818 IDirectDraw2
*ddraw
;
5819 DWORD expected_caps
;
5831 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5832 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5833 {"TEXTURE", DDSCAPS_TEXTURE
},
5836 window
= create_window();
5837 ddraw
= create_ddraw();
5838 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5840 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5841 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5843 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5845 /* Creating a flippable texture induces a BSoD on some versions of the
5846 * Intel graphics driver. At least Intel GMA 950 with driver version
5847 * 6.14.10.4926 on Windows XP SP3 is affected. */
5848 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5850 win_skip("Skipping flippable texture test.\n");
5854 memset(&surface_desc
, 0, sizeof(surface_desc
));
5855 surface_desc
.dwSize
= sizeof(surface_desc
);
5856 surface_desc
.dwFlags
= DDSD_CAPS
;
5857 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5858 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5859 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5860 surface_desc
.dwWidth
= 512;
5861 surface_desc
.dwHeight
= 512;
5862 surface_desc
.dwBackBufferCount
= 3;
5863 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5864 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5866 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5867 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5868 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5869 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5871 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5872 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5873 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5874 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5876 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5877 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5878 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5879 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5883 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5884 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5885 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5886 ok(hr
== DD_OK
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5887 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5888 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5889 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5891 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5892 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5893 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5894 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5895 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5896 hr
= restore_surfaces(ddraw
);
5897 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#lx.\n", test_data
[i
].name
, hr
);
5899 memset(&surface_desc
, 0, sizeof(surface_desc
));
5900 surface_desc
.dwSize
= sizeof(surface_desc
);
5901 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5902 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5903 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5904 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5905 expected_caps
|= DDSCAPS_VISIBLE
;
5906 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5907 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5908 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5910 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5911 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5912 memset(&surface_desc
, 0, sizeof(surface_desc
));
5913 surface_desc
.dwSize
= sizeof(surface_desc
);
5914 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5915 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5916 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5917 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5918 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5919 expected_caps
|= DDSCAPS_BACKBUFFER
;
5920 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5921 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5923 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5924 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5925 memset(&surface_desc
, 0, sizeof(surface_desc
));
5926 surface_desc
.dwSize
= sizeof(surface_desc
);
5927 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5928 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5929 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5930 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5931 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5932 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5933 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5935 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5936 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5937 memset(&surface_desc
, 0, sizeof(surface_desc
));
5938 surface_desc
.dwSize
= sizeof(surface_desc
);
5939 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5940 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5941 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5942 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5943 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5944 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5946 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5947 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5948 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5949 test_data
[i
].name
, surface
, frontbuffer
);
5950 IDirectDrawSurface_Release(surface
);
5952 memset(&surface_desc
, 0, sizeof(surface_desc
));
5953 surface_desc
.dwSize
= sizeof(surface_desc
);
5954 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5955 surface_desc
.ddsCaps
.dwCaps
= 0;
5956 surface_desc
.dwWidth
= 640;
5957 surface_desc
.dwHeight
= 480;
5958 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5959 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5960 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5961 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5962 IDirectDrawSurface_Release(surface
);
5964 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5965 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5966 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5967 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5968 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5969 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5970 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5971 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5973 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5974 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5975 * as a workaround. */
5976 fill_surface(backbuffer1
, 0xffff0000);
5977 fill_surface(backbuffer2
, 0xff00ff00);
5978 fill_surface(backbuffer3
, 0xff0000ff);
5980 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5981 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5982 color
= get_surface_color(backbuffer1
, 320, 240);
5983 /* The testbot seems to just copy the contents of one surface to all the
5984 * others, instead of properly flipping. */
5985 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5986 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5987 color
= get_surface_color(backbuffer2
, 320, 240);
5988 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5989 fill_surface(backbuffer3
, 0xffff0000);
5991 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5992 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5993 color
= get_surface_color(backbuffer1
, 320, 240);
5994 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5995 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5996 color
= get_surface_color(backbuffer2
, 320, 240);
5997 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5998 fill_surface(backbuffer3
, 0xff00ff00);
6000 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6001 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
6002 color
= get_surface_color(backbuffer1
, 320, 240);
6003 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6004 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6005 color
= get_surface_color(backbuffer2
, 320, 240);
6006 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6007 fill_surface(backbuffer3
, 0xff0000ff);
6009 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
6010 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
6011 color
= get_surface_color(backbuffer2
, 320, 240);
6012 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6013 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6014 color
= get_surface_color(backbuffer3
, 320, 240);
6015 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6016 fill_surface(backbuffer1
, 0xffff0000);
6018 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
6019 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
6020 color
= get_surface_color(backbuffer1
, 320, 240);
6021 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6022 color
= get_surface_color(backbuffer3
, 320, 240);
6023 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6024 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6025 fill_surface(backbuffer2
, 0xff00ff00);
6027 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
6028 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
6029 color
= get_surface_color(backbuffer1
, 320, 240);
6030 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6031 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6032 color
= get_surface_color(backbuffer2
, 320, 240);
6033 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6035 IDirectDrawSurface_Release(backbuffer3
);
6036 IDirectDrawSurface_Release(backbuffer2
);
6037 IDirectDrawSurface_Release(backbuffer1
);
6038 IDirectDrawSurface_Release(frontbuffer
);
6041 refcount
= IDirectDraw2_Release(ddraw
);
6042 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
6043 DestroyWindow(window
);
6046 static void reset_ddsd(DDSURFACEDESC
*ddsd
)
6048 memset(ddsd
, 0, sizeof(*ddsd
));
6049 ddsd
->dwSize
= sizeof(*ddsd
);
6052 static void test_set_surface_desc(void)
6054 IDirectDraw2
*ddraw
;
6058 IDirectDrawSurface
*surface
;
6059 IDirectDrawSurface3
*surface3
;
6069 invalid_caps_tests
[] =
6071 {DDSCAPS_VIDEOMEMORY
, FALSE
, "videomemory plain"},
6072 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, TRUE
, "systemmemory texture"},
6073 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, FALSE
, "systemmemory primary"},
6076 window
= create_window();
6077 ddraw
= create_ddraw();
6078 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6079 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6080 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6083 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6086 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6087 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6088 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6089 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6090 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6091 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6092 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6094 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6095 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6097 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6098 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#lx.\n", hr
);
6099 IDirectDrawSurface_Release(surface
);
6102 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6103 ddsd
.lpSurface
= data
;
6104 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6105 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6107 /* Redundantly setting the same lpSurface is not an error. */
6108 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6109 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6110 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6111 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6112 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6113 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
6115 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &ddsd
, 0, NULL
);
6116 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
6117 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6118 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
6119 hr
= IDirectDrawSurface3_Unlock(surface3
, NULL
);
6120 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6123 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6124 ddsd
.lpSurface
= data
;
6125 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 1);
6126 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6128 ddsd
.lpSurface
= NULL
;
6129 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6130 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6132 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, NULL
, 0);
6133 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6135 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6136 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6137 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6138 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
6140 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
6141 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6142 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6144 ddsd
.dwFlags
= DDSD_CAPS
;
6145 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6146 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6148 /* dwCaps = 0 is allowed, but ignored. */
6149 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
6150 ddsd
.lpSurface
= data
;
6151 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6152 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
6153 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6154 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6155 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
6156 ddsd
.ddsCaps
.dwCaps
= 0;
6157 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6158 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6160 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6161 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6162 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6163 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
6165 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
6167 ddsd
.dwFlags
= DDSD_HEIGHT
;
6169 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6170 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6172 ddsd
.lpSurface
= data
;
6173 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
6174 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6175 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6178 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6179 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6182 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6183 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#lx.\n", hr
);
6184 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
6185 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
6187 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
6189 ddsd
.dwFlags
= DDSD_PITCH
;
6190 ddsd
.lPitch
= 8 * 4;
6191 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6192 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6194 ddsd
.dwFlags
= DDSD_WIDTH
;
6196 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6197 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6199 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
6200 ddsd
.lpSurface
= data
;
6201 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6202 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6204 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
6205 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6206 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6208 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6209 ddsd
.lPitch
= 16 * 4;
6211 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6212 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6215 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &ddsd
);
6216 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6217 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
6218 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
6219 ok(ddsd
.lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %lu.\n", ddsd
.lPitch
);
6221 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
6223 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
6224 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6225 ddsd
.lPitch
= 4 * 4;
6226 ddsd
.lpSurface
= data
;
6227 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6228 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
6231 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6232 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
6234 ddsd
.lPitch
= 16 * 4 + 1;
6235 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6236 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6238 ddsd
.lPitch
= 16 * 4 + 3;
6239 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6240 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6243 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6244 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6246 ddsd
.lPitch
= 16 * 4;
6247 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6248 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6251 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6254 ddsd
.lpSurface
= data
;
6255 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6256 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6258 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6259 ddsd
.lPitch
= 16 * 4;
6261 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6262 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6264 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
6265 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
6266 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6267 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6268 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6269 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6270 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6271 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6272 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6273 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6275 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6276 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6277 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6279 /* Can't set color keys. */
6281 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
6282 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
6283 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
6284 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6285 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6287 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
6288 ddsd
.lpSurface
= data
;
6289 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6290 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
6292 /* Check that other surface properties are retained. */
6294 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
6295 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x0000ff00;
6296 hr
= IDirectDrawSurface3_SetColorKey(surface3
, DDCKEY_SRCBLT
, &ddsd
.ddckCKSrcBlt
);
6297 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6300 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6302 ddsd
.lPitch
= 8 * 2;
6304 ddsd
.lpSurface
= data
;
6305 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6306 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
6307 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 16;
6308 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
6309 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
6310 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
6311 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6312 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6314 memset(&ddsd
.ddckCKSrcBlt
, 0xcc, sizeof(ddsd
.ddckCKSrcBlt
));
6315 hr
= IDirectDrawSurface3_GetColorKey(surface3
, DDCKEY_SRCBLT
, &ddsd
.ddckCKSrcBlt
);
6316 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6317 ok(ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x00ff00ff,
6318 "Got low color key value %#lx.\n", ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
);
6320 IDirectDrawSurface3_Release(surface3
);
6322 /* Test mipmap texture. */
6324 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6327 ddsd
.dwMipMapCount
= 3;
6328 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6329 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6330 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
6334 skip("Mipmaps are not supported.\n");
6338 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6339 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6340 IDirectDrawSurface_Release(surface
);
6342 /* Changing surface desc for mipmap fails even without changing any
6344 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6345 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
6348 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6349 ddsd
.lpSurface
= data
;
6350 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6351 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
6352 IDirectDrawSurface3_Release(surface3
);
6356 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
6359 ddsd
.dwMipMapCount
= 3;
6360 ddsd
.lpSurface
= data
;
6361 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6363 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6364 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
6368 static DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6369 IDirectDrawSurface3
*surface2
;
6371 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6372 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6373 IDirectDrawSurface_Release(surface
);
6375 hr
= IDirectDrawSurface3_GetAttachedSurface(surface3
, &caps
, &surface2
);
6376 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6378 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface2
, &ddsd
);
6379 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6380 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %lu.\n", ddsd
.dwWidth
);
6383 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6386 ddsd
.lPitch
= 16 * 4;
6387 ddsd
.lpSurface
= data
;
6388 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6389 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6392 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6395 ddsd
.lPitch
= 8 * 4;
6396 ddsd
.lpSurface
= data
;
6397 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6398 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6401 /* _Lock causes access violation on Windows. */
6403 hr
= IDirectDrawSurface3_Lock(surface2
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6404 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6405 IDirectDrawSurface3_Unlock(surface2
, NULL
);
6410 /* Causes access violation on Windows. */
6412 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
6415 ddsd
.lPitch
= 4 * 4;
6416 ddsd
.lpSurface
= data
;
6417 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface2
, &ddsd
, 0);
6418 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6420 IDirectDrawSurface3_Release(surface2
);
6421 IDirectDrawSurface3_Release(surface3
);
6424 /* Test surface created with DDSD_LPSURFACE. */
6426 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
6429 ddsd
.lpSurface
= data
;
6430 ddsd
.lPitch
= 8 * 4;
6431 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6432 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6433 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
6435 /* SetSurfaceDesc needs systemmemory surfaces.
6437 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
6438 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
6441 ddsd
.dwFlags
= DDSD_CAPS
;
6442 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
6443 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6445 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6448 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6449 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6450 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6451 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6452 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6453 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6456 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6457 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#lx.\n", hr
);
6460 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
6461 invalid_caps_tests
[i
].name
);
6464 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6465 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6466 IDirectDrawSurface_Release(surface
);
6469 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6470 ddsd
.lpSurface
= data
;
6471 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6472 if (invalid_caps_tests
[i
].supported
)
6474 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6478 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
6479 invalid_caps_tests
[i
].name
, hr
);
6481 /* Check priority of error conditions. */
6482 ddsd
.dwFlags
= DDSD_WIDTH
;
6483 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6484 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
6485 invalid_caps_tests
[i
].name
, hr
);
6488 IDirectDrawSurface3_Release(surface3
);
6492 ref
= IDirectDraw2_Release(ddraw
);
6493 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6494 DestroyWindow(window
);
6497 static void test_user_memory_getdc(void)
6499 unsigned int data
[16][16], x
, y
;
6500 IDirectDraw2
*ddraw
;
6504 IDirectDrawSurface
*surface
;
6505 IDirectDrawSurface3
*surface3
;
6512 window
= create_window();
6513 ddraw
= create_ddraw();
6514 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6516 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6517 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6520 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6523 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6524 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6525 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6526 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6527 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6528 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6529 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6530 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6531 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6533 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
6534 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface3 interface, hr %#lx.\n", hr
);
6535 IDirectDrawSurface_Release(surface
);
6537 memset(data
, 0xaa, sizeof(data
));
6539 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6540 ddsd
.lpSurface
= data
;
6541 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6542 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6544 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6545 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
6546 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
6547 ok(!!bitmap
, "Failed to get bitmap.\n");
6548 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
6549 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
6550 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
6551 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
6552 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
6553 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6554 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
6556 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
6557 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
6559 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
6560 ddsd
.lpSurface
= data
;
6563 ddsd
.lPitch
= sizeof(*data
);
6564 hr
= IDirectDrawSurface3_SetSurfaceDesc(surface3
, &ddsd
, 0);
6565 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
6567 memset(data
, 0xaa, sizeof(data
));
6568 hr
= IDirectDrawSurface3_GetDC(surface3
, &dc
);
6569 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
6570 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
6571 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
6572 hr
= IDirectDrawSurface3_ReleaseDC(surface3
, dc
);
6573 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
6575 for (y
= 0; y
< 4; y
++)
6577 for (x
= 0; x
< 4; x
++)
6579 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
6580 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
6583 ok(data
[y
][x
] == 0x00000000, "Expected color 0xaaaaaaaa on position %ux%u, got %#x.\n",
6587 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
6589 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
6591 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
6593 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
6596 IDirectDrawSurface3_Release(surface3
);
6597 ref
= IDirectDraw2_Release(ddraw
);
6598 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6599 DestroyWindow(window
);
6602 static void test_sysmem_overlay(void)
6604 IDirectDraw2
*ddraw
;
6608 IDirectDrawSurface
*surface
;
6611 window
= create_window();
6612 ddraw
= create_ddraw();
6613 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6615 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6616 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6619 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6622 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
6623 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
6624 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6625 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6626 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6627 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6628 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6629 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6630 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#lx.\n", hr
);
6632 ref
= IDirectDraw2_Release(ddraw
);
6633 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
6634 DestroyWindow(window
);
6637 static void test_primary_palette(void)
6639 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
6640 IDirectDrawSurface
*primary
, *backbuffer
;
6641 PALETTEENTRY palette_entries
[256];
6642 IDirectDrawPalette
*palette
, *tmp
;
6643 DDSURFACEDESC surface_desc
;
6644 IDirectDraw2
*ddraw
;
6650 window
= create_window();
6651 ddraw
= create_ddraw();
6652 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6653 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6655 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6656 IDirectDraw2_Release(ddraw
);
6657 DestroyWindow(window
);
6660 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6661 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6663 memset(&surface_desc
, 0, sizeof(surface_desc
));
6664 surface_desc
.dwSize
= sizeof(surface_desc
);
6665 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6666 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6667 surface_desc
.dwBackBufferCount
= 1;
6668 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6669 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6670 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
6671 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
6673 memset(palette_entries
, 0, sizeof(palette_entries
));
6674 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
6675 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6676 refcount
= get_refcount((IUnknown
*)palette
);
6677 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6679 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6680 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6681 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
6683 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6684 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6686 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
6687 * and is generally somewhat broken with respect to 8 bpp / palette
6689 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
6691 win_skip("Broken palette handling detected, skipping tests.\n");
6692 IDirectDrawPalette_Release(tmp
);
6693 IDirectDrawPalette_Release(palette
);
6694 /* The Windows 8 testbot keeps extra references to the primary and
6695 * backbuffer while in 8 bpp mode. */
6696 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
6697 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
6701 refcount
= get_refcount((IUnknown
*)palette
);
6702 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6704 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6705 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6706 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
6707 "Got unexpected palette caps %#lx.\n", palette_caps
);
6709 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
6710 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6711 refcount
= get_refcount((IUnknown
*)palette
);
6712 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6714 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6715 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
6716 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
6718 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
6719 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6720 refcount
= get_refcount((IUnknown
*)palette
);
6721 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
6723 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6724 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
6725 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
6726 IDirectDrawPalette_Release(tmp
);
6727 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
6728 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6730 refcount
= IDirectDrawPalette_Release(palette
);
6731 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6732 refcount
= IDirectDrawPalette_Release(palette
);
6733 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6735 /* Note that this only seems to work when the palette is attached to the
6736 * primary surface. When attached to a regular surface, attempting to get
6737 * the palette here will cause an access violation. */
6738 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
6739 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6741 hr
= IDirectDrawSurface_IsLost(primary
);
6742 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6744 memset(&surface_desc
, 0, sizeof(surface_desc
));
6745 surface_desc
.dwSize
= sizeof(surface_desc
);
6746 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6747 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6748 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6749 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6750 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 8, "Got unexpected bit count %lu.\n",
6751 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
6753 hr
= set_display_mode(ddraw
, 640, 480);
6754 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
6756 memset(&surface_desc
, 0, sizeof(surface_desc
));
6757 surface_desc
.dwSize
= sizeof(surface_desc
);
6758 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6759 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6760 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6761 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6762 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 32
6763 || surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 24,
6764 "Got unexpected bit count %lu.\n", surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
6766 hr
= IDirectDrawSurface_IsLost(primary
);
6767 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
6768 hr
= IDirectDrawSurface_Restore(primary
);
6769 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
6770 hr
= IDirectDrawSurface_IsLost(primary
);
6771 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
6773 memset(&surface_desc
, 0, sizeof(surface_desc
));
6774 surface_desc
.dwSize
= sizeof(surface_desc
);
6775 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
6776 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6777 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
6778 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
6779 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 32
6780 || surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 24,
6781 "Got unexpected bit count %lu.\n", surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
6784 refcount
= IDirectDrawSurface_Release(backbuffer
);
6785 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
6786 refcount
= IDirectDrawSurface_Release(primary
);
6787 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6788 refcount
= IDirectDraw2_Release(ddraw
);
6789 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6790 DestroyWindow(window
);
6793 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
6795 UINT
*surface_count
= context
;
6798 IDirectDrawSurface_Release(surface
);
6800 return DDENUMRET_OK
;
6803 static void test_surface_attachment(void)
6805 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
6806 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
6807 DDSURFACEDESC surface_desc
;
6808 IDirectDraw2
*ddraw
;
6814 window
= create_window();
6815 ddraw
= create_ddraw();
6816 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6817 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6818 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6820 memset(&surface_desc
, 0, sizeof(surface_desc
));
6821 surface_desc
.dwSize
= sizeof(surface_desc
);
6822 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
6823 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6824 surface_desc
.dwMipMapCount
= 3;
6825 surface_desc
.dwWidth
= 128;
6826 surface_desc
.dwHeight
= 128;
6827 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6828 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6830 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
6831 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
6832 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
6833 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
6834 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
6835 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6838 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
6839 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6841 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
6842 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
6844 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
6845 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
6847 memset(&surface_desc
, 0, sizeof(surface_desc
));
6848 surface_desc
.dwSize
= sizeof(surface_desc
);
6849 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6850 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6851 surface_desc
.dwWidth
= 16;
6852 surface_desc
.dwHeight
= 16;
6853 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6854 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6856 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6857 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6858 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6859 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6860 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6861 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6862 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6863 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6864 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6865 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6866 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6867 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6869 IDirectDrawSurface_Release(surface4
);
6871 memset(&surface_desc
, 0, sizeof(surface_desc
));
6872 surface_desc
.dwSize
= sizeof(surface_desc
);
6873 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6874 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6875 surface_desc
.dwWidth
= 16;
6876 surface_desc
.dwHeight
= 16;
6877 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6878 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6880 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
6882 skip("Running on refrast, skipping some tests.\n");
6883 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
6884 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6888 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6889 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6890 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6891 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
6892 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6893 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
6894 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6895 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
6896 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6897 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
6898 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6901 IDirectDrawSurface_Release(surface4
);
6902 IDirectDrawSurface_Release(surface3
);
6903 IDirectDrawSurface_Release(surface2
);
6904 IDirectDrawSurface_Release(surface1
);
6906 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6907 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6909 /* Try a single primary and two offscreen plain surfaces. */
6910 memset(&surface_desc
, 0, sizeof(surface_desc
));
6911 surface_desc
.dwSize
= sizeof(surface_desc
);
6912 surface_desc
.dwFlags
= DDSD_CAPS
;
6913 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6914 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6915 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6917 memset(&surface_desc
, 0, sizeof(surface_desc
));
6918 surface_desc
.dwSize
= sizeof(surface_desc
);
6919 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6920 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6921 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6922 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6923 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6924 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6926 memset(&surface_desc
, 0, sizeof(surface_desc
));
6927 surface_desc
.dwSize
= sizeof(surface_desc
);
6928 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6929 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6930 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
6931 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
6932 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
6933 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6935 /* This one has a different size. */
6936 memset(&surface_desc
, 0, sizeof(surface_desc
));
6937 surface_desc
.dwSize
= sizeof(surface_desc
);
6938 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6939 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6940 surface_desc
.dwWidth
= 128;
6941 surface_desc
.dwHeight
= 128;
6942 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
6943 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6945 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
6946 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6947 /* Try the reverse without detaching first. */
6948 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6949 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6950 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6951 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6953 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
6954 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6955 /* Try to detach reversed. */
6956 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
6957 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6958 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
6959 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6961 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
6962 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
6963 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
6964 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
6966 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
6967 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6968 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
6969 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
6971 IDirectDrawSurface_Release(surface4
);
6972 IDirectDrawSurface_Release(surface3
);
6973 IDirectDrawSurface_Release(surface2
);
6974 IDirectDrawSurface_Release(surface1
);
6976 /* Test depth surfaces of different sizes. */
6977 memset(&surface_desc
, 0, sizeof(surface_desc
));
6978 surface_desc
.dwSize
= sizeof(surface_desc
);
6979 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6980 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6981 surface_desc
.dwWidth
= 64;
6982 surface_desc
.dwHeight
= 64;
6983 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
6984 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6986 memset(&surface_desc
, 0, sizeof(surface_desc
));
6987 surface_desc
.dwSize
= sizeof(surface_desc
);
6988 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6989 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
6990 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6991 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
6992 surface_desc
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
6993 surface_desc
.ddpfPixelFormat
.dwZBitMask
= 0x0000ffff;
6994 surface_desc
.dwWidth
= 32;
6995 surface_desc
.dwHeight
= 32;
6996 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
6997 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
6998 surface_desc
.dwWidth
= 64;
6999 surface_desc
.dwHeight
= 64;
7000 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7001 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
7002 surface_desc
.dwWidth
= 128;
7003 surface_desc
.dwHeight
= 128;
7004 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7005 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
7007 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
7008 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
7010 IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface2
);
7011 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
7012 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#lx.\n", hr
);
7013 hr
= IDirectDrawSurface2_DeleteAttachedSurface(surface1
, 0, surface3
);
7014 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#lx.\n", hr
);
7015 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
7016 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
7018 IDirectDrawSurface2_Release(surface4
);
7019 IDirectDrawSurface2_Release(surface3
);
7020 IDirectDrawSurface2_Release(surface2
);
7021 IDirectDrawSurface2_Release(surface1
);
7023 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
7024 memset(&surface_desc
, 0, sizeof(surface_desc
));
7025 surface_desc
.dwSize
= sizeof(surface_desc
);
7026 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7027 surface_desc
.dwWidth
= 64;
7028 surface_desc
.dwHeight
= 64;
7029 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
7030 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7031 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
7032 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
7033 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
7034 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
7035 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
7036 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7037 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7038 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7039 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7041 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7042 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
7043 surface_desc
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
7044 surface_desc
.ddpfPixelFormat
.dwZBitMask
= 0x0000ffff;
7045 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7046 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7048 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
7049 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
7050 refcount
= get_refcount((IUnknown
*)surface2
);
7051 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
7052 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
7053 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
7055 /* Attaching while already attached to other surface. */
7056 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
7057 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
7058 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
7059 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
7060 IDirectDrawSurface_Release(surface3
);
7062 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
7063 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
7064 refcount
= get_refcount((IUnknown
*)surface2
);
7065 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
7067 /* Automatic detachment on release. */
7068 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
7069 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
7070 refcount
= get_refcount((IUnknown
*)surface2
);
7071 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
7072 refcount
= IDirectDrawSurface_Release(surface1
);
7073 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7074 refcount
= IDirectDrawSurface_Release(surface2
);
7075 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7076 refcount
= IDirectDraw2_Release(ddraw
);
7077 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7078 DestroyWindow(window
);
7081 static void test_pixel_format(void)
7083 HWND window
, window2
, window3
;
7085 int format
, test_format
;
7086 PIXELFORMATDESCRIPTOR pfd
;
7087 IDirectDraw2
*ddraw
= NULL
;
7088 IDirectDrawClipper
*clipper
= NULL
;
7089 HDC hdc
, hdc2
, hdc3
;
7091 IDirectDrawSurface
*primary
= NULL
, *offscreen
;
7097 window
= create_window();
7098 ok(!!window
, "Failed to create window.\n");
7099 window2
= create_window();
7100 ok(!!window2
, "Failed to create window.\n");
7102 hdc
= GetDC(window
);
7103 ok(!!hdc
, "Failed to get DC.\n");
7104 hdc2
= GetDC(window2
);
7105 ok(!!hdc2
, "Failed to get DC.\n");
7107 gl
= LoadLibraryA("opengl32.dll");
7108 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
7110 format
= GetPixelFormat(hdc
);
7111 ok(format
== 0, "new window has pixel format %d\n", format
);
7113 ZeroMemory(&pfd
, sizeof(pfd
));
7114 pfd
.nSize
= sizeof(pfd
);
7116 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
7117 pfd
.iPixelType
= PFD_TYPE_RGBA
;
7118 pfd
.iLayerType
= PFD_MAIN_PLANE
;
7119 format
= ChoosePixelFormat(hdc
, &pfd
);
7122 skip("no pixel format available\n");
7126 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7128 skip("failed to set pixel format\n");
7132 if (!SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7134 skip("failed to set pixel format on second window\n");
7138 ddraw
= create_ddraw();
7139 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7141 test_format
= GetPixelFormat(hdc
);
7142 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7144 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7145 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7147 test_format
= GetPixelFormat(hdc
);
7148 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7150 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
7151 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
7152 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
7153 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
7155 test_format
= GetPixelFormat(hdc
);
7156 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7157 test_format
= GetPixelFormat(hdc2
);
7158 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7160 memset(&ddsd
, 0, sizeof(ddsd
));
7161 ddsd
.dwSize
= sizeof(ddsd
);
7162 ddsd
.dwFlags
= DDSD_CAPS
;
7163 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7165 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7166 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
7168 test_format
= GetPixelFormat(hdc
);
7169 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7170 test_format
= GetPixelFormat(hdc2
);
7171 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7173 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
7174 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
7176 test_format
= GetPixelFormat(hdc
);
7177 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7178 test_format
= GetPixelFormat(hdc2
);
7179 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7181 memset(&ddsd
, 0, sizeof(ddsd
));
7182 ddsd
.dwSize
= sizeof(ddsd
);
7183 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7184 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7185 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
7186 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
7187 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
7189 memset(&fx
, 0, sizeof(fx
));
7190 fx
.dwSize
= sizeof(fx
);
7191 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7192 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
7194 test_format
= GetPixelFormat(hdc
);
7195 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7197 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
7198 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
7200 test_format
= GetPixelFormat(hdc
);
7201 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7202 test_format
= GetPixelFormat(hdc2
);
7203 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7205 IDirectDrawSurface_Release(offscreen
);
7206 IDirectDrawSurface_Release(primary
);
7207 refcount
= IDirectDrawClipper_Release(clipper
);
7208 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7209 refcount
= IDirectDraw2_Release(ddraw
);
7210 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7212 /* Test that creating a device doesn't set a pixel format on a window which
7215 window3
= create_window();
7216 hdc3
= GetDC(window3
);
7218 test_format
= GetPixelFormat(hdc3
);
7219 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7221 ddraw
= create_ddraw();
7222 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7223 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window3
, DDSCL_NORMAL
);
7224 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7226 test_format
= GetPixelFormat(hdc3
);
7227 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7229 memset(&ddsd
, 0, sizeof(ddsd
));
7230 ddsd
.dwSize
= sizeof(ddsd
);
7231 ddsd
.dwFlags
= DDSD_CAPS
;
7232 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7233 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7234 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7236 memset(&ddsd
, 0, sizeof(ddsd
));
7237 ddsd
.dwSize
= sizeof(ddsd
);
7238 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7239 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7240 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
7241 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
7242 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
7244 memset(&fx
, 0, sizeof(fx
));
7245 fx
.dwSize
= sizeof(fx
);
7246 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7247 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
7249 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
7250 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
7252 test_format
= GetPixelFormat(hdc3
);
7253 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7255 IDirectDrawSurface_Release(offscreen
);
7256 IDirectDrawSurface_Release(primary
);
7257 refcount
= IDirectDraw2_Release(ddraw
);
7258 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7260 test_format
= GetPixelFormat(hdc3
);
7261 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7263 ret
= SetPixelFormat(hdc3
, format
, &pfd
);
7264 ok(ret
, "Failed to set pixel format %d.\n", format
);
7266 test_format
= GetPixelFormat(hdc3
);
7267 ok(test_format
== format
, "Expected pixel format %d, got %d.\n", format
, test_format
);
7269 ReleaseDC(window3
, hdc3
);
7270 DestroyWindow(window3
);
7274 ReleaseDC(window2
, hdc2
);
7275 ReleaseDC(window
, hdc
);
7276 DestroyWindow(window2
);
7277 DestroyWindow(window
);
7280 static void test_create_surface_pitch(void)
7282 DWORD vidmem_total
= 0, vidmem_free
= 0, vidmem_free2
= 0;
7283 DDSCAPS vidmem_caps
= {DDSCAPS_TEXTURE
};
7284 IDirectDrawSurface
* surface
, *primary
;
7285 DDSURFACEDESC surface_desc
;
7286 IDirectDraw2
*ddraw
;
7306 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7308 DDSD_PITCH
, 0x100, 0x100},
7309 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7310 DDSD_PITCH
, 0x104, DD_OK
,
7311 DDSD_PITCH
, 0x100, 0x100},
7312 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7313 DDSD_PITCH
, 0x0f8, DD_OK
,
7314 DDSD_PITCH
, 0x100, 0x100},
7315 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7316 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7318 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7320 DDSD_PITCH
, 0x100, 0x0fc},
7322 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7323 DDSD_PITCH
, 0x104, DD_OK
,
7324 DDSD_PITCH
, 0x100, 0x0fc},
7325 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7326 DDSD_PITCH
, 0x0f8, DD_OK
,
7327 DDSD_PITCH
, 0x100, 0x0fc},
7328 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7329 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
7330 DDSD_PITCH
, 0x100, 0x0fc},
7331 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7332 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
7334 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7335 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7338 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7339 0, 0, DDERR_INVALIDCAPS
,
7341 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7343 DDSD_PITCH
, 0x100, 0 },
7344 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
,
7346 DDSD_PITCH
, 0x100, 0 },
7347 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7348 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7350 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7351 0, 0, DDERR_INVALIDCAPS
,
7354 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7356 DDSD_PITCH
, 0x100, 0 },
7357 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7358 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
7360 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
7362 DDSD_PITCH
, 0x100, 0x0fc},
7363 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
7365 DDSD_PITCH
, 0x100, 0x100},
7367 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
7369 window
= create_window();
7370 ddraw
= create_ddraw();
7371 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7372 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7373 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7375 mem
= calloc((63 * 4) + 8, 63);
7377 /* We need a primary surface and exclusive mode for video memory accounting to work
7378 * right on Windows. Otherwise it gives us junk data, like creating a video memory
7379 * surface freeing up memory. */
7380 memset(&surface_desc
, 0, sizeof(surface_desc
));
7381 surface_desc
.dwSize
= sizeof(surface_desc
);
7382 surface_desc
.dwFlags
= DDSD_CAPS
;
7383 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7384 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7385 ok(SUCCEEDED(hr
), "Failed to create a primary surface, hr %#lx.\n", hr
);
7387 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free
);
7388 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7389 "Failed to get available video memory, hr %#lx.\n", hr
);
7391 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7393 memset(&surface_desc
, 0, sizeof(surface_desc
));
7394 surface_desc
.dwSize
= sizeof(surface_desc
);
7395 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
7396 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7397 surface_desc
.dwWidth
= 63;
7398 surface_desc
.dwHeight
= 63;
7399 surface_desc
.lPitch
= test_data
[i
].pitch_in
;
7400 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7401 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7402 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
7403 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
7404 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
7405 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
7406 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7407 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
7409 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
7410 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, expected_hr
);
7411 surface_desc
.lpSurface
= mem
;
7412 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7414 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
7416 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
7420 memset(&surface_desc
, 0, sizeof(surface_desc
));
7421 surface_desc
.dwSize
= sizeof(surface_desc
);
7422 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
7423 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
7424 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
7425 "Test %u: Got unexpected flags %#lx, expected %#lx.\n",
7426 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
7427 /* The pitch for textures seems to be implementation specific. */
7428 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
7430 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
7431 todo_wine
ok(surface_desc
.lPitch
== test_data
[i
].pitch_out64
,
7432 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
7433 i
, surface_desc
.lPitch
, test_data
[i
].pitch_out64
);
7435 ok(surface_desc
.lPitch
== test_data
[i
].pitch_out32
,
7436 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
7437 i
, surface_desc
.lPitch
, test_data
[i
].pitch_out32
);
7439 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
7441 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
7442 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7443 "Failed to get available video memory, hr %#lx.\n", hr
);
7444 if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
7446 /* Star Trek Starfleet Academy cares about this bit here: That creating a system memory
7447 * resource does not influence available video memory. */
7448 ok(vidmem_free2
== vidmem_free
, "Free video memory changed from %#lx to %#lx, test %u.\n",
7449 vidmem_free
, vidmem_free2
, i
);
7451 else if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
7453 /* DDSCAPS_ALLOCONLOAD does not seem to delay video memory allocation, at least not on
7456 * The amount of video memory consumed is different from what dwHeight * lPitch would
7457 * suggest, although not by much. */
7458 ok(vidmem_free2
< vidmem_free
,
7459 "Expected free video memory to change, but it did not, test %u.\n", i
);
7462 IDirectDrawSurface_Release(surface
);
7464 hr
= IDirectDraw2_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
7465 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
7466 "Failed to get available video memory, hr %#lx.\n", hr
);
7467 ok(hr
== DDERR_NODIRECTDRAWHW
|| vidmem_free2
== vidmem_free
,
7468 "Free video memory changed from %#lx to %#lx, test %u.\n",
7469 vidmem_free
, vidmem_free2
, i
);
7472 IDirectDrawSurface_Release(primary
);
7474 refcount
= IDirectDraw2_Release(ddraw
);
7475 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7476 DestroyWindow(window
);
7479 static void test_mipmap(void)
7481 IDirectDrawSurface
*surface1
;
7482 IDirectDrawSurface2
*surface
, *surface_base
, *surface_mip
;
7483 unsigned int i
, mipmap_count
;
7484 DDSURFACEDESC surface_desc
;
7485 IDirectDraw2
*ddraw
;
7489 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7498 DWORD mipmap_count_in
;
7500 DWORD mipmap_count_out
;
7504 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
},
7505 {0, DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
7506 {0, DDSCAPS_MIPMAP
| DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
7507 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
7508 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
7509 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
7510 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
7512 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 1, DDERR_INVALIDCAPS
},
7513 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 3, DDERR_INVALIDCAPS
},
7514 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
7515 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
},
7518 window
= create_window();
7519 ddraw
= create_ddraw();
7520 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7521 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7522 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7524 memset(&hal_caps
, 0, sizeof(hal_caps
));
7525 hal_caps
.dwSize
= sizeof(hal_caps
);
7526 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7527 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7528 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7530 skip("Mipmapped textures not supported, skipping tests.\n");
7531 IDirectDraw2_Release(ddraw
);
7532 DestroyWindow(window
);
7536 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7538 memset(&surface_desc
, 0, sizeof(surface_desc
));
7539 surface_desc
.dwSize
= sizeof(surface_desc
);
7540 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
7541 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7542 surface_desc
.dwWidth
= tests
[i
].width
;
7543 surface_desc
.dwHeight
= tests
[i
].height
;
7544 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
7545 surface_desc
.dwMipMapCount
= tests
[i
].mipmap_count_in
;
7546 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7547 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
7551 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7552 ok(SUCCEEDED(hr
), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", i
, hr
);
7553 IDirectDrawSurface_Release(surface1
);
7555 memset(&surface_desc
, 0, sizeof(surface_desc
));
7556 surface_desc
.dwSize
= sizeof(surface_desc
);
7557 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
7558 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
7559 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7560 "Test %u: Got unexpected flags %#lx.\n", i
, surface_desc
.dwFlags
);
7561 ok(surface_desc
.dwMipMapCount
== tests
[i
].mipmap_count_out
,
7562 "Test %u: Got unexpected mipmap count %lu.\n", i
, surface_desc
.dwMipMapCount
);
7564 surface_base
= surface
;
7565 IDirectDrawSurface2_AddRef(surface_base
);
7566 mipmap_count
= surface_desc
.dwMipMapCount
;
7567 while (mipmap_count
> 1)
7569 hr
= IDirectDrawSurface2_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
7570 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7572 memset(&surface_desc
, 0, sizeof(surface_desc
));
7573 surface_desc
.dwSize
= sizeof(surface_desc
);
7574 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface_base
, &surface_desc
);
7575 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#lx.\n", i
, mipmap_count
, hr
);
7576 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7577 "Test %u, %u: Got unexpected flags %#lx.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
7578 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
7579 "Test %u, %u: Got unexpected mipmap count %lu.\n",
7580 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7582 memset(&surface_desc
, 0, sizeof(surface_desc
));
7583 surface_desc
.dwSize
= sizeof(surface_desc
);
7584 hr
= IDirectDrawSurface2_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
7585 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7586 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
7587 "Test %u, %u: unexpected change of mipmap count %lu.\n",
7588 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7589 memset(&surface_desc
, 0, sizeof(surface_desc
));
7590 surface_desc
.dwSize
= sizeof(surface_desc
);
7591 hr
= IDirectDrawSurface2_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
7592 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
7593 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
7594 "Test %u, %u: Got unexpected child mipmap count %lu.\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
7595 IDirectDrawSurface2_Unlock(surface_mip
, NULL
);
7596 IDirectDrawSurface2_Unlock(surface_base
, NULL
);
7598 IDirectDrawSurface2_Release(surface_base
);
7599 surface_base
= surface_mip
;
7602 IDirectDrawSurface2_Release(surface_base
);
7604 IDirectDrawSurface2_Release(surface
);
7607 refcount
= IDirectDraw2_Release(ddraw
);
7608 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7609 DestroyWindow(window
);
7612 static void test_palette_complex(void)
7614 IDirectDrawSurface
*surface1
;
7615 IDirectDrawSurface2
*surface
, *mipmap
, *tmp
;
7616 DDSURFACEDESC surface_desc
;
7617 IDirectDraw2
*ddraw
;
7618 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
7622 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
7624 PALETTEENTRY palette_entries
[256];
7630 window
= create_window();
7631 ddraw
= create_ddraw();
7632 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7633 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7634 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7636 memset(&hal_caps
, 0, sizeof(hal_caps
));
7637 hal_caps
.dwSize
= sizeof(hal_caps
);
7638 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
7639 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7640 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7642 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
7643 IDirectDraw2_Release(ddraw
);
7644 DestroyWindow(window
);
7648 memset(&surface_desc
, 0, sizeof(surface_desc
));
7649 surface_desc
.dwSize
= sizeof(surface_desc
);
7650 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7651 surface_desc
.dwWidth
= 128;
7652 surface_desc
.dwHeight
= 128;
7653 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7654 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7655 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7656 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
7657 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7658 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7659 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
7660 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
7661 IDirectDrawSurface_Release(surface1
);
7663 memset(palette_entries
, 0, sizeof(palette_entries
));
7664 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7665 palette_entries
, &palette
, NULL
);
7666 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7668 memset(palette_entries
, 0, sizeof(palette_entries
));
7669 palette_entries
[1].peRed
= 0xff;
7670 palette_entries
[1].peGreen
= 0x80;
7671 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7672 palette_entries
, &palette_mipmap
, NULL
);
7673 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7675 palette2
= (void *)0xdeadbeef;
7676 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7677 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
7678 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
7679 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
7680 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7681 hr
= IDirectDrawSurface2_GetPalette(surface
, &palette2
);
7682 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
7683 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
7684 IDirectDrawPalette_Release(palette2
);
7687 IDirectDrawSurface2_AddRef(mipmap
);
7688 for (i
= 0; i
< 7; ++i
)
7690 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7691 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
7692 palette2
= (void *)0xdeadbeef;
7693 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7694 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
7695 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
7697 hr
= IDirectDrawSurface2_SetPalette(tmp
, palette_mipmap
);
7698 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#lx.\n", i
, hr
);
7700 hr
= IDirectDrawSurface2_GetPalette(tmp
, &palette2
);
7701 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#lx.\n", i
, hr
);
7702 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
7703 IDirectDrawPalette_Release(palette2
);
7705 hr
= IDirectDrawSurface2_GetDC(tmp
, &dc
);
7706 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#lx.\n", i
, hr
);
7707 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7708 ok(count
== 1, "Expected count 1, got %u.\n", count
);
7709 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
7710 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
7711 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
7712 hr
= IDirectDrawSurface2_ReleaseDC(tmp
, dc
);
7713 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#lx.\n", i
, hr
);
7715 IDirectDrawSurface2_Release(mipmap
);
7719 hr
= IDirectDrawSurface2_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7720 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
7721 IDirectDrawSurface2_Release(mipmap
);
7722 refcount
= IDirectDrawSurface2_Release(surface
);
7723 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7724 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
7725 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7726 refcount
= IDirectDrawPalette_Release(palette
);
7727 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7729 refcount
= IDirectDraw2_Release(ddraw
);
7730 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7731 DestroyWindow(window
);
7734 static void test_p8_blit(void)
7736 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
7737 DDSURFACEDESC surface_desc
;
7738 unsigned int color
, x
;
7739 IDirectDraw2
*ddraw
;
7740 IDirectDrawPalette
*palette
, *palette2
;
7744 PALETTEENTRY palette_entries
[256];
7747 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
7748 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
7749 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
7750 static const unsigned int expected
[] =
7752 0x00101010, 0x00010101, 0x00020202, 0x00030303,
7753 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
7756 window
= create_window();
7757 ddraw
= create_ddraw();
7758 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7759 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7760 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7761 is_warp
= ddraw_is_warp(ddraw
);
7763 memset(palette_entries
, 0, sizeof(palette_entries
));
7764 palette_entries
[1].peGreen
= 0xff;
7765 palette_entries
[2].peBlue
= 0xff;
7766 palette_entries
[3].peFlags
= 0xff;
7767 palette_entries
[4].peRed
= 0xff;
7768 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7769 palette_entries
, &palette
, NULL
);
7770 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7771 palette_entries
[1].peBlue
= 0xff;
7772 palette_entries
[2].peGreen
= 0xff;
7773 palette_entries
[3].peRed
= 0xff;
7774 palette_entries
[4].peFlags
= 0x0;
7775 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7776 palette_entries
, &palette2
, NULL
);
7777 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7779 memset(&surface_desc
, 0, sizeof(surface_desc
));
7780 surface_desc
.dwSize
= sizeof(surface_desc
);
7781 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7782 surface_desc
.dwWidth
= 8;
7783 surface_desc
.dwHeight
= 1;
7784 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7785 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7786 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7787 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
7788 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
7789 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7790 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
7791 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7792 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
7793 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7795 memset(&surface_desc
, 0, sizeof(surface_desc
));
7796 surface_desc
.dwSize
= sizeof(surface_desc
);
7797 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7798 surface_desc
.dwWidth
= 8;
7799 surface_desc
.dwHeight
= 1;
7800 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7801 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7802 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7803 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
7804 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
7805 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
7806 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
7807 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
7808 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
7809 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7811 memset(&surface_desc
, 0, sizeof(surface_desc
));
7812 surface_desc
.dwSize
= sizeof(surface_desc
);
7813 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7814 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
7815 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
7816 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
7817 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
7819 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
7820 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
7821 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
7822 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7823 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
7825 fx
.dwSize
= sizeof(fx
);
7826 fx
.dwFillColor
= 0xdeadbeef;
7827 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
7828 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7830 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
7831 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7832 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
7833 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
7834 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
7835 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
7836 "Failed to blit, hr %#lx.\n", hr
);
7840 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
7842 color
= get_surface_color(dst
, x
, 0);
7843 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
7844 * blits see below. */
7845 todo_wine
ok(compare_color(color
, expected
[x
], 0)
7846 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
7847 "Pixel %u: Got color %#x, expected %#x.\n",
7848 x
, color
, expected
[x
]);
7852 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
7853 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
7854 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
7855 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
7857 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
7858 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
7859 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
7860 * surface untouched. Error checking (DDBLT_KEYSRC without a key
7861 * for example) also works as expected.
7863 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
7864 * the display mode set to P8 doesn't help either. */
7865 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
7866 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
7867 "Got unexpected P8 color key blit result.\n");
7868 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
7869 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
7871 IDirectDrawSurface_Release(src
);
7872 IDirectDrawSurface_Release(dst
);
7873 IDirectDrawSurface_Release(dst_p8
);
7874 IDirectDrawPalette_Release(palette
);
7875 IDirectDrawPalette_Release(palette2
);
7877 refcount
= IDirectDraw2_Release(ddraw
);
7878 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7879 DestroyWindow(window
);
7882 static void test_material(void)
7884 IDirect3DMaterial2
*background
, *material
;
7885 D3DMATERIALHANDLE mat_handle
, tmp
;
7886 IDirect3DViewport2
*viewport
;
7887 IDirect3DDevice2
*device
;
7888 IDirectDrawSurface
*rt
;
7889 unsigned int color
, i
;
7890 IDirectDraw2
*ddraw
;
7896 static D3DVERTEX quad
[] =
7898 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7899 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7900 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7901 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
7906 D3DCOLOR expected_color
;
7911 {FALSE
, 0x00ffffff},
7913 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7915 window
= create_window();
7916 ddraw
= create_ddraw();
7917 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7918 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7920 skip("Failed to create a 3D device, skipping test.\n");
7921 DestroyWindow(window
);
7925 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
7926 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
7928 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
7929 viewport
= create_viewport(device
, 0, 0, 640, 480);
7930 viewport_set_background(device
, viewport
, background
);
7931 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
7932 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
7934 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
7935 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7936 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
7938 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7939 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7940 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
7941 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7942 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7943 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7944 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7945 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7946 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
7947 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7948 hr
= IDirect3DDevice2_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
7949 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
7950 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
7952 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7954 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
7955 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7957 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
7958 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
7960 hr
= IDirect3DDevice2_BeginScene(device
);
7961 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
7962 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_VERTEX
, quad
, 4, 0);
7963 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
7964 hr
= IDirect3DDevice2_EndScene(device
);
7965 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
7966 color
= get_surface_color(rt
, 320, 240);
7967 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
7968 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
7971 destroy_material(material
);
7972 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7973 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
7974 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
7976 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
7977 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
7978 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7979 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
7980 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7981 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7982 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7983 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7984 color
= get_surface_color(rt
, 320, 240);
7985 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7987 hr
= IDirect3DViewport2_SetBackground(viewport
, 0);
7988 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
7989 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
7990 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
7991 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
7992 ok(valid
, "Got unexpected valid %#x.\n", valid
);
7993 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7994 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
7995 color
= get_surface_color(rt
, 320, 240);
7996 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
7998 destroy_viewport(device
, viewport
);
7999 viewport
= create_viewport(device
, 0, 0, 640, 480);
8001 hr
= IDirect3DViewport2_GetBackground(viewport
, &tmp
, &valid
);
8002 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
8003 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
8004 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
8005 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8006 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8007 color
= get_surface_color(rt
, 320, 240);
8008 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
8010 destroy_viewport(device
, viewport
);
8011 destroy_material(background
);
8012 destroy_material(material
);
8013 IDirectDrawSurface_Release(rt
);
8014 refcount
= IDirect3DDevice2_Release(device
);
8015 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8016 refcount
= IDirectDraw2_Release(ddraw
);
8017 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
8018 DestroyWindow(window
);
8021 static void test_lighting(void)
8023 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8024 static D3DMATRIX mat
=
8026 1.0f
, 0.0f
, 0.0f
, 0.0f
,
8027 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8028 0.0f
, 0.0f
, 1.0f
, 0.0f
,
8029 0.0f
, 0.0f
, 0.0f
, 1.0f
,
8033 1.0f
, 0.0f
, 1.0f
, 0.0f
,
8034 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8035 1.0f
, 0.0f
, 1.0f
, 0.0f
,
8036 0.0f
, 0.0f
, 0.5f
, 1.0f
,
8040 0.0f
, 0.0f
, 1.0f
, 0.0f
,
8041 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8042 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
8043 10.f
, 10.0f
, 10.0f
, 1.0f
,
8047 1.0f
, 0.0f
, 0.0f
, 0.0f
,
8048 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8049 0.0f
, 0.0f
, 1.0f
, -1.0f
,
8050 10.f
, 10.0f
, 10.0f
, 0.0f
,
8052 static D3DLVERTEX unlitquad
[] =
8054 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
8055 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
8056 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
8057 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
8061 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
8062 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
8063 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
8064 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
8066 static D3DVERTEX unlitnquad
[] =
8068 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8069 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8070 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8071 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8075 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8076 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8077 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8078 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
8082 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8083 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8084 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8085 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8089 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
8090 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
8091 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
8092 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
8096 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8097 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8098 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8099 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
8101 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
8104 D3DMATRIX
*world_matrix
;
8107 const char *message
;
8111 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
8112 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
8113 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
8114 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
8117 IDirect3DViewport2
*viewport
, *viewport2
;
8118 D3DMATERIALHANDLE mat_handle
;
8119 IDirect3DMaterial2
*material
;
8120 IDirect3DDevice2
*device
;
8121 IDirectDrawSurface
*rt
;
8122 IDirect3DLight
*light
;
8123 unsigned int color
, i
;
8124 D3DLIGHT2 light_desc
;
8125 IDirectDraw2
*ddraw
;
8131 window
= create_window();
8132 ddraw
= create_ddraw();
8133 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8134 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8136 skip("Failed to create a 3D device, skipping test.\n");
8137 DestroyWindow(window
);
8141 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
8142 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8144 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8145 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8147 viewport
= create_viewport(device
, 0, 0, 640, 480);
8148 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8149 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8151 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
8152 viewport_set_background(device
, viewport
, material
);
8154 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8155 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8157 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
8158 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
8159 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
8160 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
8161 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
8162 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
8163 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
8164 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#lx.\n", hr
);
8165 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
8166 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
8167 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8168 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
8170 hr
= IDirect3DDevice2_BeginScene(device
);
8171 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8173 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
8174 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
8175 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8176 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, unlitquad
,
8178 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8180 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
8181 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#lx.\n", hr
);
8182 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_LVERTEX
, litquad
,
8184 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8186 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
8187 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8188 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, unlitnquad
,
8190 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8192 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
8193 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#lx.\n", hr
);
8194 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, litnquad
,
8196 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8198 hr
= IDirect3DDevice2_EndScene(device
);
8199 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8201 color
= get_surface_color(rt
, 160, 360);
8202 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
8203 color
= get_surface_color(rt
, 160, 120);
8204 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
8205 color
= get_surface_color(rt
, 480, 360);
8206 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
8207 color
= get_surface_color(rt
, 480, 120);
8208 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
8210 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
8211 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8212 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8213 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8214 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
8215 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8217 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
8218 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8219 memset(&light_desc
, 0, sizeof(light_desc
));
8220 light_desc
.dwSize
= sizeof(light_desc
);
8221 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
8222 light_desc
.dcvColor
.r
= 0.0f
;
8223 light_desc
.dcvColor
.g
= 0.25f
;
8224 light_desc
.dcvColor
.b
= 1.0f
;
8225 light_desc
.dcvColor
.a
= 1.0f
;
8226 light_desc
.dvDirection
.z
= 1.0f
;
8227 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
8228 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8229 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8230 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8231 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8232 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
8234 viewport2
= create_viewport(device
, 0, 0, 640, 480);
8235 hr
= IDirect3DViewport2_AddLight(viewport2
, light
);
8236 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
8237 destroy_viewport(device
, viewport2
);
8239 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8240 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8242 hr
= IDirect3DDevice2_BeginScene(device
);
8243 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8245 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
, nquad
,
8247 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8249 hr
= IDirect3DDevice2_EndScene(device
);
8250 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8252 color
= get_surface_color(rt
, 320, 240);
8253 ok(color
== 0x00002000, "Lit quad with no light has color 0x%08x.\n", color
);
8255 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
8256 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
8257 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8258 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8259 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8260 light_desc
.dwFlags
= 0;
8261 hr
= IDirect3DLight_GetLight(light
, (D3DLIGHT
*)&light_desc
);
8262 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8263 ok(light_desc
.dwFlags
== D3DLIGHT_ACTIVE
, "Got unexpected flags %#lx.\n", light_desc
.dwFlags
);
8265 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8266 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8267 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8269 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
8270 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
8272 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8273 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8275 hr
= IDirect3DDevice2_BeginScene(device
);
8276 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8278 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
8279 tests
[i
].quad
, 4, indices
, 6, 0);
8280 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8282 hr
= IDirect3DDevice2_EndScene(device
);
8283 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8285 color
= get_surface_color(rt
, 320, 240);
8286 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
8289 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8290 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#lx.\n", hr
);
8291 IDirect3DLight_Release(light
);
8292 destroy_material(material
);
8293 destroy_viewport(device
, viewport
);
8294 IDirectDrawSurface2_Release(rt
);
8295 refcount
= IDirect3DDevice2_Release(device
);
8296 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8297 IDirect3D2_Release(d3d
);
8298 refcount
= IDirectDraw2_Release(ddraw
);
8299 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
8300 DestroyWindow(window
);
8303 static void test_specular_lighting(void)
8305 static const unsigned int vertices_side
= 5;
8306 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
8307 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8308 static D3DMATRIX mat
=
8310 1.0f
, 0.0f
, 0.0f
, 0.0f
,
8311 0.0f
, 1.0f
, 0.0f
, 0.0f
,
8312 0.0f
, 0.0f
, 1.0f
, 0.0f
,
8313 0.0f
, 0.0f
, 0.0f
, 1.0f
,
8315 static D3DLIGHT2 directional
=
8318 D3DLIGHT_DIRECTIONAL
,
8319 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8320 {{0.0f
}, {0.0f
}, {0.0f
}},
8321 {{0.0f
}, {0.0f
}, {1.0f
}},
8327 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8328 {{0.0f
}, {0.0f
}, {0.0f
}},
8329 {{0.0f
}, {0.0f
}, {0.0f
}},
8338 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8339 {{0.0f
}, {0.0f
}, {0.0f
}},
8340 {{0.0f
}, {0.0f
}, {1.0f
}},
8344 M_PI
/ 12.0f
, M_PI
/ 3.0f
8349 D3DLIGHT_PARALLELPOINT
,
8350 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8351 {{0.5f
}, {0.0f
}, {-1.0f
}},
8352 {{0.0f
}, {0.0f
}, {0.0f
}},
8358 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8359 {{-1.1f
}, {0.0f
}, {1.1f
}},
8360 {{0.0f
}, {0.0f
}, {0.0f
}},
8369 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
8370 {{0.0f
}, {0.0f
}, {0.1f
}},
8371 {{0.0f
}, {0.0f
}, {0.0f
}},
8376 static const struct expected_color
8378 unsigned int x
, y
, color
;
8380 expected_directional_local
[] =
8382 {160, 120, 0x003c3c3c},
8383 {320, 120, 0x00717171},
8384 {480, 120, 0x003c3c3c},
8385 {160, 240, 0x00717171},
8386 {320, 240, 0x00ffffff},
8387 {480, 240, 0x00717171},
8388 {160, 360, 0x003c3c3c},
8389 {320, 360, 0x00717171},
8390 {480, 360, 0x003c3c3c},
8392 expected_point_local
[] =
8394 {160, 120, 0x00000000},
8395 {320, 120, 0x00090909},
8396 {480, 120, 0x00000000},
8397 {160, 240, 0x00090909},
8398 {320, 240, 0x00fafafa},
8399 {480, 240, 0x00090909},
8400 {160, 360, 0x00000000},
8401 {320, 360, 0x00090909},
8402 {480, 360, 0x00000000},
8404 expected_spot_local
[] =
8406 {160, 120, 0x00000000},
8407 {320, 120, 0x00020202},
8408 {480, 120, 0x00000000},
8409 {160, 240, 0x00020202},
8410 {320, 240, 0x00fafafa},
8411 {480, 240, 0x00020202},
8412 {160, 360, 0x00000000},
8413 {320, 360, 0x00020202},
8414 {480, 360, 0x00000000},
8416 expected_parallelpoint
[] =
8418 {160, 120, 0x00050505},
8419 {320, 120, 0x002c2c2c},
8420 {480, 120, 0x006e6e6e},
8421 {160, 240, 0x00090909},
8422 {320, 240, 0x00717171},
8423 {480, 240, 0x00ffffff},
8424 {160, 360, 0x00050505},
8425 {320, 360, 0x002c2c2c},
8426 {480, 360, 0x006e6e6e},
8428 expected_point_far
[] =
8430 {160, 120, 0x00000000},
8431 {320, 120, 0x00000000},
8432 {480, 120, 0x00000000},
8433 {160, 240, 0x00000000},
8434 {320, 240, 0x00ffffff},
8435 {480, 240, 0x00000000},
8436 {160, 360, 0x00000000},
8437 {320, 360, 0x00000000},
8438 {480, 360, 0x00000000},
8442 {160, 120, 0x00000000},
8443 {320, 120, 0x00000000},
8444 {480, 120, 0x00000000},
8445 {160, 240, 0x00000000},
8446 {320, 240, 0x00000000},
8447 {480, 240, 0x00000000},
8448 {160, 360, 0x00000000},
8449 {320, 360, 0x00000000},
8450 {480, 360, 0x00000000},
8455 float specular_power
;
8456 const struct expected_color
*expected
;
8457 unsigned int expected_count
;
8461 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
8462 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
8463 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
8464 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
8465 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8466 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
8467 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8468 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8469 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8470 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8471 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
8474 IDirect3DDevice2
*device
;
8475 IDirectDraw2
*ddraw
;
8476 IDirectDrawSurface
*rt
;
8477 IDirect3DViewport2
*viewport
;
8478 IDirect3DMaterial2
*material
, *background_material
;
8479 unsigned int color
, i
, j
, x
, y
;
8480 IDirect3DLight
*light
;
8481 D3DMATERIALHANDLE mat_handle
;
8488 window
= create_window();
8489 ddraw
= create_ddraw();
8490 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8491 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8493 skip("Failed to create a 3D device, skipping test.\n");
8494 DestroyWindow(window
);
8498 quad
= malloc(vertices_side
* vertices_side
* sizeof(*quad
));
8499 indices
= malloc(indices_count
* sizeof(*indices
));
8500 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
8502 for (x
= 0; x
< vertices_side
; ++x
)
8504 quad
[i
].x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8505 quad
[i
].y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
8511 quad
[i
++].tv
= 0.0f
;
8514 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
8516 for (x
= 0; x
< (vertices_side
- 1); ++x
)
8518 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8519 indices
[i
++] = y
* vertices_side
+ x
;
8520 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8521 indices
[i
++] = y
* vertices_side
+ x
+ 1;
8522 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
8523 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
8527 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
8528 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
8530 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
8531 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8533 viewport
= create_viewport(device
, 0, 0, 640, 480);
8534 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
8535 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
8537 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
8538 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
8539 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
8540 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
8541 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
8542 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
8543 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
8544 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
8545 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
8546 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
8548 background_material
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
8549 viewport_set_background(device
, viewport
, background_material
);
8551 hr
= IDirect3D2_CreateLight(d3d
, &light
, NULL
);
8552 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#lx.\n", hr
);
8553 hr
= IDirect3DViewport2_AddLight(viewport
, light
);
8554 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#lx.\n", hr
);
8556 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
8557 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#lx.\n", hr
);
8559 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8561 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
8562 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
8563 ok(SUCCEEDED(hr
), "Failed to set light, hr %#lx.\n", hr
);
8565 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
8566 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
8567 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
8568 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8569 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
8571 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8572 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8574 hr
= IDirect3DDevice2_BeginScene(device
);
8575 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8577 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, D3DVT_VERTEX
,
8578 quad
, vertices_side
* vertices_side
, indices
, indices_count
, 0);
8579 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8581 hr
= IDirect3DDevice2_EndScene(device
);
8582 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8584 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
8586 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
8587 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
8588 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
8589 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
8590 tests
[i
].expected
[j
].y
, color
, i
);
8593 destroy_material(material
);
8596 hr
= IDirect3DViewport2_DeleteLight(viewport
, light
);
8597 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#lx.\n", hr
);
8598 IDirect3DLight_Release(light
);
8599 destroy_material(background_material
);
8600 destroy_viewport(device
, viewport
);
8601 IDirectDrawSurface2_Release(rt
);
8602 refcount
= IDirect3DDevice2_Release(device
);
8603 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8604 IDirect3D2_Release(d3d
);
8605 refcount
= IDirectDraw2_Release(ddraw
);
8606 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
8607 DestroyWindow(window
);
8612 static void test_palette_gdi(void)
8614 IDirectDrawSurface
*surface
, *primary
;
8615 DDSURFACEDESC surface_desc
;
8616 unsigned int color
, i
;
8617 IDirectDraw2
*ddraw
;
8618 IDirectDrawPalette
*palette
, *palette2
;
8622 PALETTEENTRY palette_entries
[256];
8627 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8628 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8629 * not the point of this test. */
8630 static const RGBQUAD expected1
[] =
8632 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8633 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8635 static const RGBQUAD expected2
[] =
8637 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8638 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8640 static const RGBQUAD expected3
[] =
8642 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8643 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8645 HPALETTE ddraw_palette_handle
;
8646 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8647 RGBQUAD rgbquad
[255];
8648 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8650 window
= create_window();
8651 ddraw
= create_ddraw();
8652 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8653 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8654 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8656 memset(&surface_desc
, 0, sizeof(surface_desc
));
8657 surface_desc
.dwSize
= sizeof(surface_desc
);
8658 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8659 surface_desc
.dwWidth
= 16;
8660 surface_desc
.dwHeight
= 16;
8661 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8662 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8663 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8664 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
8665 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8666 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8668 /* Avoid colors from the Windows default palette. */
8669 memset(palette_entries
, 0, sizeof(palette_entries
));
8670 palette_entries
[1].peRed
= 0x01;
8671 palette_entries
[2].peGreen
= 0x02;
8672 palette_entries
[3].peBlue
= 0x03;
8673 palette_entries
[4].peRed
= 0x13;
8674 palette_entries
[4].peGreen
= 0x14;
8675 palette_entries
[4].peBlue
= 0x15;
8676 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8677 palette_entries
, &palette
, NULL
);
8678 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8680 /* If there is no palette assigned and the display mode is not 8 bpp, some
8681 * drivers refuse to create a DC while others allow it. If a DC is created,
8682 * the DIB color table is uninitialized and contains random colors. No error
8683 * is generated when trying to read pixels and random garbage is returned.
8685 * The most likely explanation is that if the driver creates a DC, it (or
8686 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8687 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8688 * contains uninitialized garbage. See comments below for the P8 case. */
8690 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8691 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8692 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8693 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8694 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8695 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8696 "Got unexpected palette %p, expected %p.\n",
8697 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8699 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8700 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8701 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8703 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8704 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8705 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8706 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8708 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8710 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8711 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8712 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8715 /* Update the palette while the DC is in use. This does not modify the DC. */
8716 palette_entries
[4].peRed
= 0x23;
8717 palette_entries
[4].peGreen
= 0x24;
8718 palette_entries
[4].peBlue
= 0x25;
8719 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8720 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
8722 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8723 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8724 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8725 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8726 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8727 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8729 /* Neither does re-setting the palette. */
8730 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
8731 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8732 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8733 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8735 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8736 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8737 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8738 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8739 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8740 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8742 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8743 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8745 /* Refresh the DC. This updates the palette. */
8746 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8747 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8748 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8749 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8750 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8752 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8753 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8754 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8755 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8757 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8759 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8760 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8761 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8763 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8764 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8766 refcount
= IDirectDrawSurface_Release(surface
);
8767 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8769 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8770 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8771 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8773 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8774 IDirectDrawPalette_Release(palette
);
8775 IDirectDraw2_Release(ddraw
);
8776 DestroyWindow(window
);
8779 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
8781 memset(&surface_desc
, 0, sizeof(surface_desc
));
8782 surface_desc
.dwSize
= sizeof(surface_desc
);
8783 surface_desc
.dwFlags
= DDSD_CAPS
;
8784 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8785 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8786 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8788 memset(&fx
, 0, sizeof(fx
));
8789 fx
.dwSize
= sizeof(fx
);
8791 SetRect(&r
, 0, 0, 319, 479);
8792 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8793 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
8794 SetRect(&r
, 320, 0, 639, 479);
8796 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8797 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
8799 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
8800 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8801 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
8802 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8804 color
= GetPixel(dc
, 160, 240);
8805 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8806 color
= GetPixel(dc
, 480, 240);
8807 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8809 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8810 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8811 "Got unexpected palette %p, expected %p.\n",
8812 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8813 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8815 /* The primary uses the system palette. In exclusive mode, the system palette matches
8816 * the ddraw palette attached to the primary, so the result is what you would expect
8817 * from a regular surface. Tests for the interaction between the ddraw palette and
8818 * the system palette are not included pending an application that depends on this.
8819 * The relation between those causes problems on Windows Vista and newer for games
8820 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8821 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8822 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8823 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8825 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8826 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8827 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8828 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8830 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8832 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8833 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8834 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8836 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
8837 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8839 memset(&surface_desc
, 0, sizeof(surface_desc
));
8840 surface_desc
.dwSize
= sizeof(surface_desc
);
8841 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8842 surface_desc
.dwWidth
= 16;
8843 surface_desc
.dwHeight
= 16;
8844 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8845 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8846 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8848 /* Here the offscreen surface appears to use the primary's palette,
8849 * but in all likelihood it is actually the system palette. */
8850 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8851 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8852 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8853 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8854 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8856 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8857 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8858 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8859 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8861 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8863 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8864 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8865 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8867 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8868 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8870 /* On real hardware a change to the primary surface's palette applies immediately,
8871 * even on device contexts from offscreen surfaces that do not have their own
8872 * palette. On the testbot VMs this is not the case. Don't test this until we
8873 * know of an application that depends on this. */
8875 memset(palette_entries
, 0, sizeof(palette_entries
));
8876 palette_entries
[1].peBlue
= 0x40;
8877 palette_entries
[2].peRed
= 0x40;
8878 palette_entries
[3].peGreen
= 0x40;
8879 palette_entries
[4].peRed
= 0x12;
8880 palette_entries
[4].peGreen
= 0x34;
8881 palette_entries
[4].peBlue
= 0x56;
8882 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8883 palette_entries
, &palette2
, NULL
);
8884 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8885 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
8886 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8888 /* A palette assigned to the offscreen surface overrides the primary / system
8890 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8891 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8892 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8893 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8894 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
8896 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
8897 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8898 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8899 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
8901 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8903 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8904 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8905 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8907 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8908 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8910 refcount
= IDirectDrawSurface_Release(surface
);
8911 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8913 /* The Windows 8 testbot keeps extra references to the primary and
8914 * backbuffer while in 8 bpp mode. */
8915 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
8916 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
8918 refcount
= IDirectDrawSurface_Release(primary
);
8919 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8920 refcount
= IDirectDrawPalette_Release(palette2
);
8921 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8922 refcount
= IDirectDrawPalette_Release(palette
);
8923 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8924 refcount
= IDirectDraw2_Release(ddraw
);
8925 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8926 DestroyWindow(window
);
8929 static void test_palette_alpha(void)
8931 IDirectDrawSurface
*surface1
;
8932 IDirectDrawSurface2
*surface
;
8933 DDSURFACEDESC surface_desc
;
8934 IDirectDraw2
*ddraw
;
8935 IDirectDrawPalette
*palette
;
8939 PALETTEENTRY palette_entries
[256];
8944 BOOL attach_allowed
;
8949 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
8950 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
8951 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
8954 window
= create_window();
8955 ddraw
= create_ddraw();
8956 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8957 if (FAILED(IDirectDraw2_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8959 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8960 IDirectDraw2_Release(ddraw
);
8961 DestroyWindow(window
);
8964 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8965 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8967 memset(palette_entries
, 0, sizeof(palette_entries
));
8968 palette_entries
[1].peFlags
= 0x42;
8969 palette_entries
[2].peFlags
= 0xff;
8970 palette_entries
[3].peFlags
= 0x80;
8971 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
8972 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8974 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8975 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8976 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
8977 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8978 palette_entries
[0].peFlags
);
8979 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8980 palette_entries
[1].peFlags
);
8981 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8982 palette_entries
[2].peFlags
);
8983 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8984 palette_entries
[3].peFlags
);
8986 IDirectDrawPalette_Release(palette
);
8988 memset(palette_entries
, 0, sizeof(palette_entries
));
8989 palette_entries
[1].peFlags
= 0x42;
8990 palette_entries
[1].peRed
= 0xff;
8991 palette_entries
[2].peFlags
= 0xff;
8992 palette_entries
[3].peFlags
= 0x80;
8993 hr
= IDirectDraw2_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
8994 palette_entries
, &palette
, NULL
);
8995 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8997 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8998 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8999 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
9000 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9001 palette_entries
[0].peFlags
);
9002 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9003 palette_entries
[1].peFlags
);
9004 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9005 palette_entries
[2].peFlags
);
9006 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9007 palette_entries
[3].peFlags
);
9009 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
9011 memset(&surface_desc
, 0, sizeof(surface_desc
));
9012 surface_desc
.dwSize
= sizeof(surface_desc
);
9013 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
9014 surface_desc
.dwWidth
= 128;
9015 surface_desc
.dwHeight
= 128;
9016 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
9017 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
9018 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
9019 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
9020 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
9021 IDirectDrawSurface_Release(surface1
);
9023 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
9024 if (test_data
[i
].attach_allowed
)
9025 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
9027 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
9035 hr
= IDirectDrawSurface2_GetDC(surface
, &dc
);
9036 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
9037 "Failed to get DC, hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
9040 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
9041 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
9042 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
9043 rgbquad
.rgbRed
, test_data
[i
].name
);
9044 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
9045 rgbquad
.rgbGreen
, test_data
[i
].name
);
9046 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
9047 rgbquad
.rgbBlue
, test_data
[i
].name
);
9048 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
9049 rgbquad
.rgbReserved
, test_data
[i
].name
);
9050 hr
= IDirectDrawSurface2_ReleaseDC(surface
, dc
);
9051 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
9054 IDirectDrawSurface2_Release(surface
);
9057 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
9058 memset(&surface_desc
, 0, sizeof(surface_desc
));
9059 surface_desc
.dwSize
= sizeof(surface_desc
);
9060 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9061 surface_desc
.dwWidth
= 128;
9062 surface_desc
.dwHeight
= 128;
9063 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9064 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9065 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9066 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9067 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9068 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9069 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9070 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
9071 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9072 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
9073 ok(SUCCEEDED(hr
), "Failed to get IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
9074 IDirectDrawSurface_Release(surface1
);
9076 hr
= IDirectDrawSurface2_SetPalette(surface
, palette
);
9077 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
9078 IDirectDrawSurface2_Release(surface
);
9080 /* The Windows 8 testbot keeps extra references to the primary
9081 * while in 8 bpp mode. */
9082 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
9083 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
9085 refcount
= IDirectDrawPalette_Release(palette
);
9086 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9087 refcount
= IDirectDraw2_Release(ddraw
);
9088 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9089 DestroyWindow(window
);
9092 static void test_lost_device(void)
9094 IDirectDrawSurface
*surface
, *back_buffer
, *back_buffer2
, *ds
;
9095 IDirectDrawSurface
*sysmem_surface
, *vidmem_surface
;
9096 DDSURFACEDESC surface_desc
;
9097 HWND window1
, window2
;
9098 IDirectDraw2
*ddraw
;
9104 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9105 0, 0, 640, 480, 0, 0, 0, 0);
9106 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9107 0, 0, 640, 480, 0, 0, 0, 0);
9108 ddraw
= create_ddraw();
9109 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9110 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9111 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9113 memset(&surface_desc
, 0, sizeof(surface_desc
));
9114 surface_desc
.dwSize
= sizeof(surface_desc
);
9115 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9116 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9117 surface_desc
.dwBackBufferCount
= 1;
9118 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9119 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9121 memset(&surface_desc
, 0, sizeof(surface_desc
));
9122 surface_desc
.dwSize
= sizeof(surface_desc
);
9123 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9124 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9125 surface_desc
.dwWidth
= 100;
9126 surface_desc
.dwHeight
= 100;
9127 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
9128 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9130 memset(&surface_desc
, 0, sizeof(surface_desc
));
9131 surface_desc
.dwSize
= sizeof(surface_desc
);
9132 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9133 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
9134 surface_desc
.dwWidth
= 64;
9135 surface_desc
.dwHeight
= 64;
9136 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9137 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9138 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9139 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9140 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9141 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9142 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
9144 skip("Failed to create video memory surface, skipping related tests.\n");
9145 vidmem_surface
= NULL
;
9148 hr
= IDirectDrawSurface_IsLost(surface
);
9149 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9150 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9151 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9152 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9153 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9156 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9157 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9160 ret
= SetForegroundWindow(GetDesktopWindow());
9161 ok(ret
, "Failed to set foreground window.\n");
9162 hr
= IDirectDrawSurface_IsLost(surface
);
9163 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9164 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9165 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9166 hr
= IDirectDrawSurface_Restore(surface
);
9167 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
9168 hr
= IDirectDrawSurface_IsLost(surface
);
9169 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9170 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9171 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9172 hr
= IDirectDrawSurface_Restore(sysmem_surface
);
9173 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9174 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9175 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9178 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9179 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9180 hr
= IDirectDrawSurface_Restore(vidmem_surface
);
9181 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
9182 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9183 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9186 ret
= SetForegroundWindow(window1
);
9187 ok(ret
, "Failed to set foreground window.\n");
9188 hr
= IDirectDrawSurface_IsLost(surface
);
9189 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9190 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9191 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9192 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9193 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9196 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9197 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9200 hr
= restore_surfaces(ddraw
);
9201 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9202 hr
= IDirectDrawSurface_IsLost(surface
);
9203 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9204 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9205 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9206 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9207 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9210 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9211 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9214 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9215 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9216 hr
= IDirectDrawSurface_IsLost(surface
);
9217 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9218 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9219 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9220 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9221 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9224 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9225 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9228 /* Trying to restore the primary will crash, probably because flippable
9229 * surfaces can't exist in DDSCL_NORMAL. */
9230 IDirectDrawSurface_Release(surface
);
9231 memset(&surface_desc
, 0, sizeof(surface_desc
));
9232 surface_desc
.dwSize
= sizeof(surface_desc
);
9233 surface_desc
.dwFlags
= DDSD_CAPS
;
9234 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9235 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9236 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9237 hr
= restore_surfaces(ddraw
);
9238 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9240 hr
= IDirectDrawSurface_IsLost(surface
);
9241 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9243 ret
= SetForegroundWindow(GetDesktopWindow());
9244 ok(ret
, "Failed to set foreground window.\n");
9245 hr
= IDirectDrawSurface_IsLost(surface
);
9246 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9247 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9248 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9251 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9252 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9255 ret
= SetForegroundWindow(window1
);
9256 ok(ret
, "Failed to set foreground window.\n");
9257 hr
= IDirectDrawSurface_IsLost(surface
);
9258 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9259 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9260 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9263 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9264 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9267 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9268 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9269 hr
= IDirectDrawSurface_IsLost(surface
);
9270 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9271 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9272 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9275 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9276 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9279 hr
= restore_surfaces(ddraw
);
9280 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9281 hr
= IDirectDrawSurface_IsLost(surface
);
9282 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9283 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9284 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9287 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9288 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9291 IDirectDrawSurface_Release(surface
);
9292 memset(&surface_desc
, 0, sizeof(surface_desc
));
9293 surface_desc
.dwSize
= sizeof(surface_desc
);
9294 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9295 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9296 surface_desc
.dwBackBufferCount
= 2;
9297 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9298 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9301 memset(&surface_desc
, 0, sizeof(surface_desc
));
9302 surface_desc
.dwSize
= sizeof(surface_desc
);
9303 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface
, &surface_desc
);
9304 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9306 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
9307 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9308 surface_desc
.dwZBufferBitDepth
= 16;
9309 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
9312 skip("Could not create Z buffer, skipping Z buffer restore test.\n");
9316 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
9317 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9320 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9321 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9322 hr
= IDirectDrawSurface_IsLost(surface
);
9323 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9324 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9325 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9326 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9327 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9330 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9331 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9334 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9335 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9336 hr
= IDirectDrawSurface_IsLost(surface
);
9337 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9338 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9339 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9340 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9341 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9344 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9345 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9348 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9349 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9350 hr
= IDirectDrawSurface_IsLost(surface
);
9351 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9352 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9353 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9354 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9355 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9358 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9359 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9362 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
9363 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9364 hr
= IDirectDrawSurface_IsLost(surface
);
9365 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9366 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9367 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9368 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9369 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9372 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9373 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9376 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9377 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9378 hr
= IDirectDrawSurface_IsLost(surface
);
9379 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9380 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9381 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
9382 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9383 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9386 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9387 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9390 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9391 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9392 hr
= IDirectDrawSurface_IsLost(surface
);
9393 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9394 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
9395 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9396 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
9397 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9400 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
9401 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9404 memset(&caps
, 0, sizeof(caps
));
9405 caps
.dwCaps
= DDSCAPS_FLIP
;
9407 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9408 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9409 ok(back_buffer
!= surface
, "Got the same surface.\n");
9410 hr
= IDirectDrawSurface_Restore(surface
);
9411 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9412 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
9413 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9414 hr
= IDirectDrawSurface_IsLost(back_buffer
);
9415 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9416 IDirectDrawSurface_Release(back_buffer
);
9418 hr
= IDirectDrawSurface_GetAttachedSurface(back_buffer
, &caps
, &back_buffer2
);
9419 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9420 ok(back_buffer2
!= back_buffer
, "Got the same surface.\n");
9421 ok(back_buffer2
!= surface
, "Got the same surface.\n");
9422 hr
= IDirectDrawSurface_IsLost(back_buffer2
);
9423 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9424 IDirectDrawSurface_Release(back_buffer2
);
9428 hr
= IDirectDrawSurface_IsLost(ds
);
9429 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
9430 hr
= IDirectDrawSurface_Restore(ds
);
9431 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9432 hr
= IDirectDrawSurface_IsLost(ds
);
9433 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
9434 IDirectDrawSurface_Release(ds
);
9438 IDirectDrawSurface_Release(vidmem_surface
);
9439 IDirectDrawSurface_Release(sysmem_surface
);
9440 IDirectDrawSurface_Release(surface
);
9441 refcount
= IDirectDraw2_Release(ddraw
);
9442 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9443 DestroyWindow(window2
);
9444 DestroyWindow(window1
);
9447 static void test_surface_desc_lock(void)
9449 IDirectDrawSurface
*surface
;
9450 DDSURFACEDESC surface_desc
;
9451 IDirectDraw2
*ddraw
;
9456 window
= create_window();
9457 ddraw
= create_ddraw();
9458 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9459 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9460 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9462 memset(&surface_desc
, 0, sizeof(surface_desc
));
9463 surface_desc
.dwSize
= sizeof(surface_desc
);
9464 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9465 surface_desc
.dwWidth
= 16;
9466 surface_desc
.dwHeight
= 16;
9467 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9468 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9469 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9471 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9472 surface_desc
.dwSize
= sizeof(surface_desc
);
9473 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9474 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9475 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9477 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9478 surface_desc
.dwSize
= sizeof(surface_desc
);
9479 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9480 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9481 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9482 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9483 surface_desc
.dwSize
= sizeof(surface_desc
);
9484 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9485 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9486 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9487 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9488 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9490 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9491 surface_desc
.dwSize
= sizeof(surface_desc
);
9492 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
9493 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
9494 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9496 IDirectDrawSurface_Release(surface
);
9497 refcount
= IDirectDraw2_Release(ddraw
);
9498 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9499 DestroyWindow(window
);
9502 static void test_texturemapblend(void)
9507 static RECT rect
= {0, 0, 64, 128};
9508 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9510 IDirectDrawSurface
*surface
, *rt
;
9511 IDirect3DTexture2
*texture
;
9512 D3DTEXTUREHANDLE texture_handle
;
9515 IDirectDraw2
*ddraw
;
9516 IDirect3DDevice2
*device
;
9517 IDirect3DMaterial2
*material
;
9518 IDirect3DViewport2
*viewport
;
9521 static D3DTLVERTEX test1_quads
[] =
9523 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
9524 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
9525 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
9526 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
9527 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
9528 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
9529 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
9530 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
9534 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
9535 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
9536 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
9537 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
9538 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
9539 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
9540 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
9541 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
9544 window
= create_window();
9545 ddraw
= create_ddraw();
9546 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9547 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9549 skip("Failed to create a 3D device, skipping test.\n");
9550 DestroyWindow(window
);
9551 IDirectDraw2_Release(ddraw
);
9555 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9556 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9558 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
9559 viewport
= create_viewport(device
, 0, 0, 640, 480);
9560 viewport_set_background(device
, viewport
, material
);
9561 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
9562 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
9564 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
9566 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
9567 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
9568 memset(&ddsd
, 0, sizeof(ddsd
));
9569 ddsd
.dwSize
= sizeof(ddsd
);
9570 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9571 ddsd
.dwHeight
= 128;
9573 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9574 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9575 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9576 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9577 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9578 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9579 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9580 ddsd
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
9581 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9582 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9584 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9585 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9586 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9587 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9588 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9589 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9591 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9592 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9594 memset(&fx
, 0, sizeof(fx
));
9595 fx
.dwSize
= sizeof(fx
);
9596 fx
.dwFillColor
= 0xff0000ff;
9597 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9598 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9599 fx
.dwFillColor
= 0x800000ff;
9600 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9601 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9603 /* Note that the ddraw1 version of this test runs tests 1-3 with D3DRENDERSTATE_COLORKEYENABLE
9604 * enabled, whereas this version only runs test 4 with color keying on. Because no color key
9605 * is set on the texture this should not result in different behavior. */
9606 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9607 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9608 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9609 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9610 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9611 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9612 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9613 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9614 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9615 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9616 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9617 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9619 hr
= IDirect3DDevice2_BeginScene(device
);
9620 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9621 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9622 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9623 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9624 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9625 hr
= IDirect3DDevice2_EndScene(device
);
9626 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9628 color
= get_surface_color(rt
, 5, 5);
9629 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9630 color
= get_surface_color(rt
, 400, 5);
9631 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9632 color
= get_surface_color(rt
, 5, 245);
9633 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9634 color
= get_surface_color(rt
, 400, 245);
9635 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9637 IDirect3DTexture2_Release(texture
);
9638 ref
= IDirectDrawSurface_Release(surface
);
9639 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9641 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
9642 memset(&ddsd
, 0, sizeof(ddsd
));
9643 ddsd
.dwSize
= sizeof(ddsd
);
9644 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9645 ddsd
.dwHeight
= 128;
9647 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9648 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9649 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9650 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9651 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9652 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9653 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9655 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9656 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9658 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9659 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9660 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9661 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9662 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9663 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9665 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9666 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9668 fx
.dwFillColor
= 0xff0000ff;
9669 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9670 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9671 fx
.dwFillColor
= 0x800000ff;
9672 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9673 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9675 hr
= IDirect3DDevice2_BeginScene(device
);
9676 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9677 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9678 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9679 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9680 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9681 hr
= IDirect3DDevice2_EndScene(device
);
9682 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9684 color
= get_surface_color(rt
, 5, 5);
9685 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9686 color
= get_surface_color(rt
, 400, 5);
9687 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9688 color
= get_surface_color(rt
, 5, 245);
9689 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9690 color
= get_surface_color(rt
, 400, 245);
9691 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9693 IDirect3DTexture2_Release(texture
);
9694 ref
= IDirectDrawSurface_Release(surface
);
9695 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9697 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
9698 memset(&ddsd
, 0, sizeof(ddsd
));
9699 ddsd
.dwSize
= sizeof(ddsd
);
9700 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9701 ddsd
.dwHeight
= 128;
9703 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9704 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9705 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9706 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9707 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9708 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9709 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9710 ddsd
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
9711 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9712 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9714 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9715 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9716 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9717 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9718 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9719 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9721 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9722 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9724 fx
.dwFillColor
= 0x00ffffff;
9725 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9726 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9727 fx
.dwFillColor
= 0x00ffff80;
9728 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9729 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9731 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9732 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9734 hr
= IDirect3DDevice2_BeginScene(device
);
9735 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9736 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[0], 4, 0);
9737 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9738 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test2_quads
[4], 4, 0);
9739 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9740 hr
= IDirect3DDevice2_EndScene(device
);
9741 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9743 color
= get_surface_color(rt
, 5, 5);
9744 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9745 color
= get_surface_color(rt
, 400, 5);
9746 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9747 color
= get_surface_color(rt
, 5, 245);
9748 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9749 color
= get_surface_color(rt
, 400, 245);
9750 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9752 IDirect3DTexture2_Release(texture
);
9753 ref
= IDirectDrawSurface_Release(surface
);
9754 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9756 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
9757 memset(&ddsd
, 0, sizeof(ddsd
));
9758 ddsd
.dwSize
= sizeof(ddsd
);
9759 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9760 ddsd
.dwHeight
= 128;
9762 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9763 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
9764 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9765 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 16;
9766 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
9767 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
9768 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
9770 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
9771 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9773 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9774 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9775 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
9776 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9777 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
9778 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9780 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9781 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
9783 fx
.dwFillColor
= 0xf800;
9784 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9785 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9786 fx
.dwFillColor
= 0x001f;
9787 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9788 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
9790 ckey
.dwColorSpaceLowValue
= 0x001f;
9791 ckey
.dwColorSpaceHighValue
= 0x001f;
9792 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9793 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9795 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9796 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9797 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9798 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9800 hr
= IDirect3DDevice2_BeginScene(device
);
9801 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9802 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[0], 4, 0);
9803 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9804 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_TLVERTEX
, &test1_quads
[4], 4, 0);
9805 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9806 hr
= IDirect3DDevice2_EndScene(device
);
9807 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9809 color
= get_surface_color(rt
, 5, 5);
9810 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9811 color
= get_surface_color(rt
, 400, 5);
9812 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9813 color
= get_surface_color(rt
, 5, 245);
9814 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9815 color
= get_surface_color(rt
, 400, 245);
9816 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9818 IDirect3DTexture2_Release(texture
);
9819 ref
= IDirectDrawSurface_Release(surface
);
9820 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9822 destroy_viewport(device
, viewport
);
9823 ref
= IDirect3DMaterial2_Release(material
);
9824 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9825 IDirectDrawSurface_Release(rt
);
9826 IDirect3DDevice2_Release(device
);
9827 ref
= IDirectDraw2_Release(ddraw
);
9828 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9829 DestroyWindow(window
);
9832 static void test_viewport_clear_rect(void)
9835 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9836 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
9837 IDirectDrawSurface
*rt
;
9840 IDirectDraw2
*ddraw
;
9841 IDirect3DDevice2
*device
;
9842 IDirect3DMaterial2
*red
, *green
;
9843 IDirect3DViewport2
*viewport
, *viewport2
;
9846 window
= create_window();
9847 ddraw
= create_ddraw();
9848 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9849 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9851 skip("Failed to create a 3D device, skipping test.\n");
9852 DestroyWindow(window
);
9853 IDirectDraw2_Release(ddraw
);
9857 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
9858 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9860 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
9861 viewport
= create_viewport(device
, 0, 0, 640, 480);
9862 viewport_set_background(device
, viewport
, red
);
9863 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9864 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9866 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
9867 viewport2
= create_viewport(device
, 100, 100, 20, 20);
9868 viewport_set_background(device
, viewport2
, green
);
9869 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
9870 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9872 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
9873 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9874 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
9875 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
9876 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
9877 "Got unexpected color 0x%08x.\n", color
);
9878 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
9879 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
9880 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
9881 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9882 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
9883 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9885 destroy_viewport(device
, viewport2
);
9886 destroy_material(green
);
9887 destroy_viewport(device
, viewport
);
9888 destroy_material(red
);
9889 IDirectDrawSurface_Release(rt
);
9890 IDirect3DDevice2_Release(device
);
9891 ref
= IDirectDraw2_Release(ddraw
);
9892 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
9893 DestroyWindow(window
);
9896 static void test_color_fill(void)
9899 IDirect3DDevice2
*device
;
9900 IDirectDraw2
*ddraw
;
9901 IDirectDrawSurface
*surface
, *surface2
;
9902 DDSURFACEDESC surface_desc
;
9903 unsigned int i
, *color
;
9908 RECT rect
= {5, 5, 7, 7};
9909 DWORD num_fourcc_codes
, *fourcc_codes
;
9911 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
9915 HRESULT colorfill_hr
, depthfill_hr
;
9918 unsigned int result
;
9920 DDPIXELFORMAT format
;
9925 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9926 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9928 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9929 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9933 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9934 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9936 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9937 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9941 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9942 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9944 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9945 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9949 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9950 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9952 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9953 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9957 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
9958 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9959 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9962 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9963 * different afterwards. DX9+ GPUs set one of the two luminance values
9964 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9965 * value they set. r200 (dx8) just sets the entire block to the clear
9967 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9968 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9970 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9971 {0}, {0}, {0}, {0}, {0}
9975 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9976 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9978 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9979 {0}, {0}, {0}, {0}, {0}
9983 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9984 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9986 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9987 {0}, {0}, {0}, {0}, {0}
9991 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9992 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9994 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9995 {0}, {0}, {0}, {0}, {0}
9999 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
10000 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
10002 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
10003 {0}, {0}, {0}, {0}, {0}
10007 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
10008 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
10010 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
10011 {0}, {0}, {0}, {0}, {0}
10015 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
10016 * surface works, presumably because it is handled by the runtime instead of
10018 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
10019 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
10021 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
10022 {8}, {0}, {0}, {0}, {0}
10026 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
10027 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
10029 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
10030 {8}, {0}, {0}, {0}, {0}
10034 static const struct
10042 {SRCCOPY
, "SRCCOPY", DD_OK
},
10043 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
10044 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
10045 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
10046 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
10047 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
10048 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
10049 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
10050 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
10051 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
10052 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
10053 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
10054 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
10055 {BLACKNESS
, "BLACKNESS", DD_OK
},
10056 {WHITENESS
, "WHITENESS", DD_OK
},
10057 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
10060 window
= create_window();
10061 ddraw
= create_ddraw();
10062 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10063 is_warp
= ddraw_is_warp(ddraw
);
10064 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10066 skip("Failed to create a 3D device, skipping test.\n");
10067 DestroyWindow(window
);
10068 IDirectDraw2_Release(ddraw
);
10072 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
10073 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
10074 fourcc_codes
= calloc(num_fourcc_codes
, sizeof(*fourcc_codes
));
10077 hr
= IDirectDraw2_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
10078 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
10079 for (i
= 0; i
< num_fourcc_codes
; i
++)
10081 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
10082 support_yuy2
= TRUE
;
10083 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
10084 support_uyvy
= TRUE
;
10086 free(fourcc_codes
);
10088 memset(&hal_caps
, 0, sizeof(hal_caps
));
10089 hal_caps
.dwSize
= sizeof(hal_caps
);
10090 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
10091 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
10093 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
10094 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
10096 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
10098 DWORD expected_broken
= tests
[i
].result
;
10099 unsigned int mask
= 0xffffffffu
;
10101 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
10102 memset(&fx
, 0, sizeof(fx
));
10103 fx
.dwSize
= sizeof(fx
);
10104 fx
.dwFillColor
= 0xdeadbeef;
10106 memset(&surface_desc
, 0, sizeof(surface_desc
));
10107 surface_desc
.dwSize
= sizeof(surface_desc
);
10108 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10109 surface_desc
.dwWidth
= 64;
10110 surface_desc
.dwHeight
= 64;
10111 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
10112 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
10114 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
10116 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
10117 hr
= IDirect3DDevice2_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
10118 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
10119 if (!check
.supported
)
10123 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
10125 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
10127 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
10130 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
10132 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
10133 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
10134 surface_desc
.dwZBufferBitDepth
= get_device_z_depth(device
);
10135 mask
>>= (32 - surface_desc
.dwZBufferBitDepth
);
10136 /* Some drivers seem to convert depth values incorrectly or not at
10137 * all. Affects at least AMD PALM, 8.17.10.1247. */
10138 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
10143 expected
= tests
[i
].result
& mask
;
10144 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
10145 g
= (f
+ 1.0f
) / 2.0f
;
10147 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
10148 expected_broken
*= 0x01010101;
10152 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10153 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10155 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10156 todo_wine_if (tests
[i
].format
.dwFourCC
)
10157 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10158 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
10160 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10161 todo_wine_if (tests
[i
].format
.dwFourCC
)
10162 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10163 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
10165 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10167 memset(&surface_desc
, 0, sizeof(surface_desc
));
10168 surface_desc
.dwSize
= sizeof(surface_desc
);
10169 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10170 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10171 color
= surface_desc
.lpSurface
;
10172 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10173 *color
, tests
[i
].result
, tests
[i
].name
);
10174 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10175 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10178 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10179 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10180 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10181 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10182 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
10183 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10185 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10187 memset(&surface_desc
, 0, sizeof(surface_desc
));
10188 surface_desc
.dwSize
= sizeof(surface_desc
);
10189 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10190 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10191 color
= surface_desc
.lpSurface
;
10192 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& surface_desc
.dwZBufferBitDepth
!= 16)
10193 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
10194 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
10195 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10196 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
10197 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10198 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10201 fx
.dwFillColor
= 0xdeadbeef;
10202 fx
.dwROP
= BLACKNESS
;
10203 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10204 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
10205 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10206 ok(fx
.dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
10207 fx
.dwFillColor
, tests
[i
].name
);
10209 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10211 memset(&surface_desc
, 0, sizeof(surface_desc
));
10212 surface_desc
.dwSize
= sizeof(surface_desc
);
10213 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10214 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10215 color
= surface_desc
.lpSurface
;
10216 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
10217 *color
, tests
[i
].name
);
10218 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10219 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10222 fx
.dwROP
= WHITENESS
;
10223 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10224 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
10225 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10226 ok(fx
.dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
10227 fx
.dwFillColor
, tests
[i
].name
);
10229 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10231 memset(&surface_desc
, 0, sizeof(surface_desc
));
10232 surface_desc
.dwSize
= sizeof(surface_desc
);
10233 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10234 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10235 color
= surface_desc
.lpSurface
;
10236 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
10237 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
10238 *color
, tests
[i
].name
);
10239 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10240 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
10243 IDirectDrawSurface_Release(surface
);
10246 memset(&fx
, 0, sizeof(fx
));
10247 fx
.dwSize
= sizeof(fx
);
10248 fx
.dwFillColor
= 0xdeadbeef;
10249 fx
.dwROP
= WHITENESS
;
10251 memset(&surface_desc
, 0, sizeof(surface_desc
));
10252 surface_desc
.dwSize
= sizeof(surface_desc
);
10253 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10254 surface_desc
.dwWidth
= 64;
10255 surface_desc
.dwHeight
= 64;
10256 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10257 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10258 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
10259 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
10260 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
10261 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
10262 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10263 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10264 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10265 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10266 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10269 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
10270 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10271 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
10272 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10274 /* Unused source rectangle. */
10275 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10276 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10277 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10278 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10280 /* Unused source surface. */
10281 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10282 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10283 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10284 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10285 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10286 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10287 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10288 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10290 /* Inverted destination or source rectangle. */
10291 SetRect(&rect
, 5, 7, 7, 5);
10292 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10293 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10294 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10295 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10296 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10297 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10298 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10299 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10300 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10301 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10303 /* Negative rectangle. */
10304 SetRect(&rect
, -1, -1, 5, 5);
10305 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10306 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10307 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10308 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10309 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10310 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10311 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10312 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10313 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10314 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10316 /* Out of bounds rectangle. */
10317 SetRect(&rect
, 0, 0, 65, 65);
10318 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10319 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10320 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10321 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10323 /* Combine multiple flags. */
10324 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10325 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10326 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10327 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10328 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10329 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10331 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
10333 fx
.dwROP
= rops
[i
].rop
;
10334 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10335 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#lx for rop %s.\n", hr
, rops
[i
].name
);
10338 IDirectDrawSurface_Release(surface2
);
10339 IDirectDrawSurface_Release(surface
);
10341 memset(&surface_desc
, 0, sizeof(surface_desc
));
10342 surface_desc
.dwSize
= sizeof(surface_desc
);
10343 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
10344 surface_desc
.dwWidth
= 64;
10345 surface_desc
.dwHeight
= 64;
10346 surface_desc
.dwZBufferBitDepth
= get_device_z_depth(device
);
10347 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10348 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10349 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10350 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10351 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10354 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
10355 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10357 /* Unused source rectangle. */
10358 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10359 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10361 /* Unused source surface. */
10362 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10363 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10364 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10365 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10367 /* Inverted destination or source rectangle. */
10368 SetRect(&rect
, 5, 7, 7, 5);
10369 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10370 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10371 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10372 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10373 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10374 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10375 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10376 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10378 /* Negative rectangle. */
10379 SetRect(&rect
, -1, -1, 5, 5);
10380 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10381 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10382 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10383 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10384 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10385 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10386 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10387 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10389 /* Out of bounds rectangle. */
10390 SetRect(&rect
, 0, 0, 65, 65);
10391 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10392 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
10394 /* Combine multiple flags. */
10395 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10396 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10398 IDirectDrawSurface_Release(surface2
);
10399 IDirectDrawSurface_Release(surface
);
10402 IDirect3DDevice2_Release(device
);
10403 refcount
= IDirectDraw2_Release(ddraw
);
10404 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
10405 DestroyWindow(window
);
10408 static void test_colorkey_precision(void)
10410 static D3DLVERTEX quad
[] =
10412 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {0.0f
}},
10413 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {0.0f
}, {1.0f
}},
10414 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {0.0f
}},
10415 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff000000}, {0}, {1.0f
}, {1.0f
}},
10417 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10418 unsigned int data
[4] = {0}, color_mask
, color
, t
, c
;
10419 IDirect3DDevice2
*device
;
10420 IDirectDraw2
*ddraw
;
10421 IDirectDrawSurface
*rt
;
10422 IDirect3DViewport2
*viewport
;
10425 IDirectDrawSurface
*src
, *dst
, *texture
;
10426 D3DTEXTUREHANDLE handle
;
10427 IDirect3DTexture2
*d3d_texture
;
10428 IDirect3DMaterial2
*green
;
10429 DDSURFACEDESC surface_desc
, lock_desc
;
10433 BOOL is_nvidia
, is_warp
;
10434 static const struct
10436 unsigned int max
, shift
, bpp
, clear
;
10444 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10446 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10447 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10452 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10454 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10455 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10460 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10462 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10463 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10468 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10470 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10471 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10476 window
= create_window();
10477 ddraw
= create_ddraw();
10478 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10479 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10481 skip("Failed to create a 3D device, skipping test.\n");
10482 DestroyWindow(window
);
10483 IDirectDraw2_Release(ddraw
);
10486 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10487 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10489 is_nvidia
= ddraw_is_nvidia(ddraw
);
10490 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10491 * (color key doesn't match although the values are equal), and a false
10492 * positive when the color key is 0 and the texture contains the value 1.
10493 * I don't want to mark this broken unconditionally since this would
10494 * essentially disable the test on Windows. Also on random occasions
10495 * 254 == 255 and 255 != 255.*/
10496 is_warp
= ddraw_is_warp(ddraw
);
10498 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
10499 viewport
= create_viewport(device
, 0, 0, 640, 480);
10500 viewport_set_background(device
, viewport
, green
);
10501 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10502 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
10504 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10505 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
10506 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
10507 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
10508 /* There's no way to ignore the texture color in d3d2, so multiply the texture color
10509 * with a black vertex color. */
10510 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
10511 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
10513 memset(&fx
, 0, sizeof(fx
));
10514 fx
.dwSize
= sizeof(fx
);
10515 memset(&lock_desc
, 0, sizeof(lock_desc
));
10516 lock_desc
.dwSize
= sizeof(lock_desc
);
10518 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
10520 if (is_nvidia
&& tests
[t
].skip_nv
)
10522 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
10526 memset(&surface_desc
, 0, sizeof(surface_desc
));
10527 surface_desc
.dwSize
= sizeof(surface_desc
);
10528 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10529 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10530 surface_desc
.dwWidth
= 4;
10531 surface_desc
.dwHeight
= 1;
10532 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
10533 /* Windows XP (at least with the r200 driver, other drivers untested) produces
10534 * garbage when doing color keyed texture->texture blits. */
10535 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
10536 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10537 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
10538 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10540 fx
.dwFillColor
= tests
[t
].clear
;
10541 /* On the w8 testbot (WARP driver) the blit result has different values in the
10543 color_mask
= tests
[t
].fmt
.dwRBitMask
10544 | tests
[t
].fmt
.dwGBitMask
10545 | tests
[t
].fmt
.dwBBitMask
;
10547 for (c
= 0; c
<= tests
[t
].max
; ++c
)
10549 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
10550 * texture after it has been set once... */
10551 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
10552 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10553 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10554 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10555 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
10556 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10558 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
10559 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
10560 hr
= IDirect3DTexture2_GetHandle(d3d_texture
, device
, &handle
);
10561 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
10562 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
10563 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
10564 IDirect3DTexture2_Release(d3d_texture
);
10566 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10567 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
10569 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10570 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10571 switch (tests
[t
].bpp
)
10574 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10575 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10576 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10577 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
10581 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10582 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10583 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10584 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
10587 hr
= IDirectDrawSurface_Unlock(src
, 0);
10588 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10589 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
10590 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10592 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10593 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10594 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
10595 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10597 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
10598 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10600 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
10601 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10602 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10603 switch (tests
[t
].bpp
)
10606 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10607 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10608 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10609 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10613 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10614 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10615 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10616 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10619 hr
= IDirectDrawSurface_Unlock(dst
, 0);
10620 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10624 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10625 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
10627 if (data
[3] == tests
[t
].clear
)
10629 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
10630 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
10631 * even when a different surface is used. The blit itself doesn't draw anything,
10632 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
10633 * never be masked out by the key.
10635 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
10636 * test is disabled entirely.
10638 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
10639 * terrible on WARP. */
10640 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
10641 IDirectDrawSurface_Release(texture
);
10642 IDirectDrawSurface_Release(src
);
10643 IDirectDrawSurface_Release(dst
);
10648 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10649 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
10651 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10652 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
10654 if (c
== tests
[t
].max
)
10655 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10656 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
10658 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10659 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
10661 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10662 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
10664 hr
= IDirect3DDevice2_BeginScene(device
);
10665 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
10666 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
10667 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
10668 hr
= IDirect3DDevice2_EndScene(device
);
10669 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10671 color
= get_surface_color(rt
, 80, 240);
10673 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10674 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10675 color
, tests
[t
].name
, c
);
10677 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10678 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10679 color
, tests
[t
].name
, c
);
10681 color
= get_surface_color(rt
, 240, 240);
10682 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10683 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10684 color
, tests
[t
].name
, c
);
10686 color
= get_surface_color(rt
, 400, 240);
10687 if (c
== tests
[t
].max
)
10688 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10689 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10690 color
, tests
[t
].name
, c
);
10692 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10693 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10694 color
, tests
[t
].name
, c
);
10696 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
10697 ok(SUCCEEDED(hr
), "Failed to set texture handle, hr %#lx.\n", hr
);
10698 IDirectDrawSurface_Release(texture
);
10700 IDirectDrawSurface_Release(src
);
10701 IDirectDrawSurface_Release(dst
);
10705 destroy_viewport(device
, viewport
);
10706 destroy_material(green
);
10707 IDirectDrawSurface_Release(rt
);
10708 IDirect3DDevice2_Release(device
);
10709 refcount
= IDirectDraw2_Release(ddraw
);
10710 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
10711 DestroyWindow(window
);
10714 static void test_range_colorkey(void)
10716 IDirectDraw2
*ddraw
;
10719 IDirectDrawSurface
*surface
;
10720 DDSURFACEDESC surface_desc
;
10724 window
= create_window();
10725 ddraw
= create_ddraw();
10726 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10727 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10728 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10730 memset(&surface_desc
, 0, sizeof(surface_desc
));
10731 surface_desc
.dwSize
= sizeof(surface_desc
);
10732 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
10733 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10734 surface_desc
.dwWidth
= 1;
10735 surface_desc
.dwHeight
= 1;
10736 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10737 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
10738 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
10739 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
10740 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
10741 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0x00000000;
10743 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
10744 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10745 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10746 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10747 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10749 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10750 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10751 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10752 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10754 /* Same for DDSCAPS_OFFSCREENPLAIN. */
10755 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10756 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10757 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10758 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10759 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10761 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10762 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10763 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10764 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10766 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10767 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10768 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10769 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10771 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
10772 ckey
.dwColorSpaceLowValue
= 0x00000000;
10773 ckey
.dwColorSpaceHighValue
= 0x00000001;
10774 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10775 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10777 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10778 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10779 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10780 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10782 ckey
.dwColorSpaceLowValue
= 0x00000001;
10783 ckey
.dwColorSpaceHighValue
= 0x00000000;
10784 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10785 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10787 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10788 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10789 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10790 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10792 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
10793 ckey
.dwColorSpaceLowValue
= 0x00000000;
10794 ckey
.dwColorSpaceHighValue
= 0x00000000;
10795 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10796 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
10798 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
10799 ckey
.dwColorSpaceLowValue
= 0x00000001;
10800 ckey
.dwColorSpaceHighValue
= 0x00000000;
10801 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10802 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10803 ckey
.dwColorSpaceLowValue
= 0x00000000;
10804 ckey
.dwColorSpaceHighValue
= 0x00000001;
10805 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10806 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10807 /* Range destination keys don't work either. */
10808 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
10809 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10811 /* Just to show it's not because of A, R, and G having equal values. */
10812 ckey
.dwColorSpaceLowValue
= 0x00000000;
10813 ckey
.dwColorSpaceHighValue
= 0x01010101;
10814 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10815 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
10817 /* None of these operations modified the key. */
10818 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10819 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
10820 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
10821 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
10823 IDirectDrawSurface_Release(surface
);
10824 refcount
= IDirectDraw2_Release(ddraw
);
10825 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10826 DestroyWindow(window
);
10829 static void test_shademode(void)
10831 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10832 unsigned int color0
, color1
, i
, count
;
10833 IDirect3DMaterial2
*background
;
10834 IDirect3DViewport2
*viewport
;
10835 IDirect3DDevice2
*device
;
10836 IDirectDrawSurface
*rt
;
10837 IDirectDraw2
*ddraw
;
10842 static D3DLVERTEX quad_strip
[] =
10844 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10845 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10846 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10847 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10851 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
10852 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10853 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10855 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
10856 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
10857 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
10859 static const struct
10863 unsigned int color0
, color1
;
10867 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
10868 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10869 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10870 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10871 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
10872 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10875 window
= create_window();
10876 ddraw
= create_ddraw();
10877 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10878 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10880 skip("Failed to create a 3D device, skipping test.\n");
10881 IDirectDraw2_Release(ddraw
);
10882 DestroyWindow(window
);
10886 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
10887 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10889 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
10890 viewport
= create_viewport(device
, 0, 0, 640, 480);
10891 viewport_set_background(device
, viewport
, background
);
10892 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
10893 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
10895 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10896 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
10898 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10899 * the color fixups we have to do for FLAT shading will be dependent on that. */
10901 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10903 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10904 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
10906 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10907 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#lx.\n", hr
);
10909 hr
= IDirect3DDevice2_BeginScene(device
);
10910 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
10911 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
10912 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
10913 hr
= IDirect3DDevice2_DrawPrimitive(device
, tests
[i
].primtype
, D3DVT_LVERTEX
, quad
, count
, 0);
10914 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
10915 hr
= IDirect3DDevice2_EndScene(device
);
10916 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10918 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10919 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10921 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10922 * each triangle. This requires EXT_provoking_vertex or similar
10923 * functionality being available. */
10924 /* PHONG should be the same as GOURAUD, since no hardware implements
10926 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10927 i
, color0
, tests
[i
].color0
);
10928 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10929 i
, color1
, tests
[i
].color1
);
10932 destroy_viewport(device
, viewport
);
10933 destroy_material(background
);
10934 IDirectDrawSurface_Release(rt
);
10935 refcount
= IDirect3DDevice2_Release(device
);
10936 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10937 IDirectDraw2_Release(ddraw
);
10938 DestroyWindow(window
);
10941 static void test_lockrect_invalid(void)
10944 IDirectDraw2
*ddraw
;
10945 IDirectDrawSurface
*surface1
;
10946 IDirectDrawSurface2
*surface
;
10949 DDSURFACEDESC surface_desc
;
10951 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10952 static RECT valid
[] =
10957 {120, 60, 128, 68},
10958 {60, 120, 68, 128},
10960 static RECT invalid
[] =
10962 {68, 60, 60, 68}, /* left > right */
10963 {60, 68, 68, 60}, /* top > bottom */
10964 {-8, 60, 0, 68}, /* left < surface */
10965 {60, -8, 68, 0}, /* top < surface */
10966 {-16, 60, -8, 68}, /* right < surface */
10967 {60, -16, 68, -8}, /* bottom < surface */
10968 {60, 60, 136, 68}, /* right > surface */
10969 {60, 60, 68, 136}, /* bottom > surface */
10970 {136, 60, 144, 68}, /* left > surface */
10971 {60, 136, 68, 144}, /* top > surface */
10973 static const struct
10981 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10982 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10983 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
10984 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
10987 window
= create_window();
10988 ddraw
= create_ddraw();
10989 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10990 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10991 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10993 memset(&hal_caps
, 0, sizeof(hal_caps
));
10994 hal_caps
.dwSize
= sizeof(hal_caps
);
10995 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, NULL
);
10996 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
10997 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
10999 skip("Required surface types not supported, skipping test.\n");
11003 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
11005 memset(&surface_desc
, 0, sizeof(surface_desc
));
11006 surface_desc
.dwSize
= sizeof(surface_desc
);
11007 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11008 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
11009 surface_desc
.dwWidth
= 128;
11010 surface_desc
.dwHeight
= 128;
11011 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11012 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11013 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
11014 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xff0000;
11015 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x00ff00;
11016 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x0000ff;
11018 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
11019 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11020 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface
);
11021 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface2 interface, hr %#lx.\n", hr
);
11022 IDirectDrawSurface_Release(surface1
);
11024 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
11025 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11027 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
11029 RECT
*rect
= &valid
[i
];
11031 memset(&surface_desc
, 0, sizeof(surface_desc
));
11032 surface_desc
.dwSize
= sizeof(surface_desc
);
11034 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11035 ok(SUCCEEDED(hr
), "Lock failed (%#lx) for rect %s, type %s.\n",
11036 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11038 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
11039 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11042 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
11044 RECT
*rect
= &invalid
[i
];
11046 memset(&surface_desc
, 1, sizeof(surface_desc
));
11047 surface_desc
.dwSize
= sizeof(surface_desc
);
11049 hr
= IDirectDrawSurface2_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11050 ok(hr
== resources
[r
].hr
, "Lock returned %#lx for rect %s, type %s.\n",
11051 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11054 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
11055 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11058 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
11061 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11062 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#lx, type %s.\n",
11063 hr
, resources
[r
].name
);
11064 hr
= IDirectDrawSurface2_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11065 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#lx, type %s.\n",
11066 hr
, resources
[r
].name
);
11067 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
11068 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11070 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11071 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#lx).\n", wine_dbgstr_rect(&valid
[0]), hr
);
11072 hr
= IDirectDrawSurface2_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11073 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#lx).\n",
11074 wine_dbgstr_rect(&valid
[0]), hr
);
11076 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
11077 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
11079 hr
= IDirectDrawSurface2_Unlock(surface
, NULL
);
11080 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
11082 IDirectDrawSurface2_Release(surface
);
11086 IDirectDraw2_Release(ddraw
);
11087 DestroyWindow(window
);
11090 static void test_yv12_overlay(void)
11092 IDirectDrawSurface
*src_surface
, *dst_surface
;
11093 RECT rect
= {13, 17, 14, 18};
11094 unsigned int offset
, y
;
11095 unsigned char *base
;
11096 IDirectDraw2
*ddraw
;
11097 DDSURFACEDESC desc
;
11101 window
= create_window();
11102 ddraw
= create_ddraw();
11103 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11104 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11105 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11107 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11109 skip("Failed to create a YV12 overlay, skipping test.\n");
11113 memset(&desc
, 0, sizeof(desc
));
11114 desc
.dwSize
= sizeof(desc
);
11115 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11116 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
11118 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
11119 "Got unexpected flags %#lx.\n", desc
.dwFlags
);
11120 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
11121 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
11122 "Got unexpected caps %#lx.\n", desc
.ddsCaps
.dwCaps
);
11123 ok(desc
.dwWidth
== 256, "Got unexpected width %lu.\n", desc
.dwWidth
);
11124 ok(desc
.dwHeight
== 256, "Got unexpected height %lu.\n", desc
.dwHeight
);
11125 /* The overlay pitch seems to have 256 byte alignment. */
11126 ok(!(desc
.lPitch
& 0xff), "Got unexpected pitch %lu.\n", desc
.lPitch
);
11128 /* Fill the surface with some data for the blit test. */
11129 base
= desc
.lpSurface
;
11131 for (y
= 0; y
< desc
.dwHeight
; ++y
)
11133 memset(base
+ desc
.lPitch
* y
, 0x10, desc
.dwWidth
);
11136 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
11138 memset(base
+ desc
.lPitch
* y
, 0x20, desc
.dwWidth
);
11141 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
11143 memset(base
+ desc
.lPitch
* y
, 0x30, desc
.dwWidth
);
11146 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
11147 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
11149 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
11150 * other block-based formats like DXT the entire Y channel is stored in
11151 * one big chunk of memory, followed by the chroma channels. So partial
11152 * locks do not really make sense. Show that they are allowed nevertheless
11153 * and the offset points into the luminance data. */
11154 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
11155 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
11156 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
11157 ok(offset
== rect
.top
* desc
.lPitch
+ rect
.left
, "Got unexpected offset %u, expected %lu.\n",
11158 offset
, rect
.top
* desc
.lPitch
+ rect
.left
);
11159 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
11160 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
11162 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11164 /* Windows XP with a Radeon X1600 GPU refuses to create a second
11165 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
11166 skip("Failed to create a second YV12 surface, skipping blit test.\n");
11167 IDirectDrawSurface_Release(src_surface
);
11171 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
11172 /* VMware rejects YV12 blits. This behavior has not been seen on real
11173 * hardware yet, so mark it broken. */
11174 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#lx.\n", hr
);
11178 memset(&desc
, 0, sizeof(desc
));
11179 desc
.dwSize
= sizeof(desc
);
11180 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11181 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
11183 base
= desc
.lpSurface
;
11184 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
11185 base
+= desc
.dwHeight
* desc
.lPitch
;
11186 ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
11187 base
+= desc
.dwHeight
/ 4 * desc
.lPitch
;
11188 ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
11190 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
11191 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
11194 IDirectDrawSurface_Release(dst_surface
);
11195 IDirectDrawSurface_Release(src_surface
);
11197 IDirectDraw2_Release(ddraw
);
11198 DestroyWindow(window
);
11201 static BOOL
dwm_enabled(void)
11205 if (!strcmp(winetest_platform
, "wine"))
11207 if (!pDwmIsCompositionEnabled
)
11209 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
11214 static void test_offscreen_overlay(void)
11216 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
11217 DDSURFACEDESC surface_desc
;
11218 IDirectDraw2
*ddraw
;
11223 window
= create_window();
11224 ddraw
= create_ddraw();
11225 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11226 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11227 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11229 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11231 skip("Failed to create a UYVY overlay, skipping test.\n");
11235 memset(&surface_desc
, 0, sizeof(surface_desc
));
11236 surface_desc
.dwSize
= sizeof(surface_desc
);
11237 surface_desc
.dwFlags
= DDSD_CAPS
;
11238 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11239 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11240 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11242 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11243 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11244 * surface prevents this by disabling the dwm. */
11245 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
11246 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
11247 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
11248 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
11250 /* Try to overlay a NULL surface. */
11251 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
11252 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11253 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
11254 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11256 /* Try to overlay an offscreen surface. */
11257 memset(&surface_desc
, 0, sizeof(surface_desc
));
11258 surface_desc
.dwSize
= sizeof(surface_desc
);
11259 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11260 surface_desc
.dwWidth
= 64;
11261 surface_desc
.dwHeight
= 64;
11262 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11263 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11264 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11265 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
11266 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
11267 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
11268 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
11269 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
11270 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11271 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11273 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
11274 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
11275 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
11276 "Failed to update overlay, hr %#lx.\n", hr
);
11278 /* Try to overlay the primary with a non-overlay surface. */
11279 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11280 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
11281 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11282 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
11284 IDirectDrawSurface_Release(offscreen
);
11285 IDirectDrawSurface_Release(primary
);
11286 IDirectDrawSurface_Release(overlay
);
11288 IDirectDraw2_Release(ddraw
);
11289 DestroyWindow(window
);
11292 static void test_overlay_rect(void)
11294 IDirectDrawSurface
*overlay
, *primary
= NULL
;
11295 DDSURFACEDESC surface_desc
;
11296 RECT rect
= {0, 0, 64, 64};
11297 IDirectDraw2
*ddraw
;
11303 window
= create_window();
11304 ddraw
= create_ddraw();
11305 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11306 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11307 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11309 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11311 skip("Failed to create a UYVY overlay, skipping test.\n");
11315 memset(&surface_desc
, 0, sizeof(surface_desc
));
11316 surface_desc
.dwSize
= sizeof(surface_desc
);
11317 surface_desc
.dwFlags
= DDSD_CAPS
;
11318 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11319 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11320 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
11322 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11323 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11324 * surface prevents this by disabling the dwm. */
11325 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
11326 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
11327 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
11328 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
11330 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
11333 win_skip("Cannot disable DWM, skipping overlay test.\n");
11337 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
11338 * used. This is not true in Windows Vista and earlier, but changed in
11340 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11341 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11342 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11343 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11344 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11345 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11347 /* Show that the overlay position is the (top, left) coordinate of the
11348 * destination rectangle. */
11349 OffsetRect(&rect
, 32, 16);
11350 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11351 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11352 pos_x
= -1; pos_y
= -1;
11353 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11354 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
11355 ok(pos_x
== rect
.left
, "Got unexpected pos_x %ld, expected %ld.\n", pos_x
, rect
.left
);
11356 ok(pos_y
== rect
.top
, "Got unexpected pos_y %ld, expected %ld.\n", pos_y
, rect
.top
);
11358 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
11359 * seen that the overlay overlays the whole primary(==screen). */
11360 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
11361 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#lx.\n", hr2
);
11362 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11363 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
11364 if (SUCCEEDED(hr2
))
11366 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
11367 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
11371 ok(pos_x
== 32, "Got unexpected pos_x %ld.\n", pos_x
);
11372 ok(pos_y
== 16, "Got unexpected pos_y %ld.\n", pos_y
);
11375 /* The position cannot be retrieved when the overlay is not shown. */
11376 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
11377 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
11378 pos_x
= -1; pos_y
= -1;
11379 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11380 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#lx.\n", hr
);
11381 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
11382 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
11386 IDirectDrawSurface_Release(primary
);
11388 IDirectDrawSurface_Release(overlay
);
11389 IDirectDraw2_Release(ddraw
);
11390 DestroyWindow(window
);
11393 static void test_blt(void)
11395 IDirectDrawSurface
*surface
, *rt
;
11396 DDSURFACEDESC surface_desc
;
11397 IDirect3DDevice2
*device
;
11398 IDirectDraw2
*ddraw
;
11412 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
11413 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
11414 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11415 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11416 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11417 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11418 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11419 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11420 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11421 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11424 window
= create_window();
11425 ddraw
= create_ddraw();
11426 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11427 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11429 skip("Failed to create a 3D device, skipping test.\n");
11430 IDirectDraw2_Release(ddraw
);
11431 DestroyWindow(window
);
11435 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
11436 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11438 memset(&surface_desc
, 0, sizeof(surface_desc
));
11439 surface_desc
.dwSize
= sizeof(surface_desc
);
11440 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11441 surface_desc
.dwWidth
= 640;
11442 surface_desc
.dwHeight
= 480;
11443 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11444 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11445 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11447 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11448 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
11450 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11451 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
11453 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11455 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11456 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11457 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
11459 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11460 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11461 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
11463 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
11464 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11465 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11467 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
11468 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11471 IDirectDrawSurface_Release(surface
);
11472 IDirectDrawSurface_Release(rt
);
11473 refcount
= IDirect3DDevice2_Release(device
);
11474 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11475 IDirectDraw2_Release(ddraw
);
11476 DestroyWindow(window
);
11479 static void test_blt_z_alpha(void)
11481 DWORD blt_flags
[] =
11485 DDBLT_ALPHADESTCONSTOVERRIDE
,
11486 DDBLT_ALPHADESTNEG
,
11487 DDBLT_ALPHADESTSURFACEOVERRIDE
,
11488 DDBLT_ALPHAEDGEBLEND
,
11491 DDBLT_ALPHASRCCONSTOVERRIDE
,
11493 DDBLT_ALPHASRCSURFACEOVERRIDE
,
11496 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
11497 DDBLT_ZBUFFERDESTOVERRIDE
,
11498 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
11499 DDBLT_ZBUFFERSRCOVERRIDE
,
11501 IDirectDrawSurface
*src_surface
, *dst_surface
;
11502 DDSURFACEDESC surface_desc
;
11503 unsigned int color
, i
;
11504 IDirectDraw2
*ddraw
;
11511 window
= create_window();
11512 ddraw
= create_ddraw();
11513 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11514 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11515 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11517 memset(&pf
, 0, sizeof(pf
));
11518 pf
.dwSize
= sizeof(pf
);
11519 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11520 pf
.dwRGBBitCount
= 32;
11521 pf
.dwRBitMask
= 0x00ff0000;
11522 pf
.dwGBitMask
= 0x0000ff00;
11523 pf
.dwBBitMask
= 0x000000ff;
11524 pf
.dwRGBAlphaBitMask
= 0xff000000;
11526 memset(&surface_desc
, 0, sizeof(surface_desc
));
11527 surface_desc
.dwSize
= sizeof(surface_desc
);
11528 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11529 surface_desc
.dwWidth
= 64;
11530 surface_desc
.dwHeight
= 64;
11531 surface_desc
.ddpfPixelFormat
= pf
;
11532 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11534 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11535 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
11536 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11537 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
11539 memset(&fx
, 0, sizeof(fx
));
11540 fx
.dwSize
= sizeof(fx
);
11541 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
11542 fx
.dwZDestConstBitDepth
= 32;
11543 fx
.dwZDestConst
= 0x11111111;
11544 fx
.dwZSrcConstBitDepth
= 32;
11545 fx
.dwZSrcConst
= 0xeeeeeeee;
11546 fx
.dwAlphaEdgeBlendBitDepth
= 8;
11547 fx
.dwAlphaEdgeBlend
= 0x7f;
11548 fx
.dwAlphaDestConstBitDepth
= 8;
11549 fx
.dwAlphaDestConst
= 0xdd;
11550 fx
.dwAlphaSrcConstBitDepth
= 8;
11551 fx
.dwAlphaSrcConst
= 0x22;
11553 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
11555 fx
.dwFillColor
= 0x3300ff00;
11556 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11557 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11559 fx
.dwFillColor
= 0xccff0000;
11560 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11561 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11563 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
11564 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
11566 color
= get_surface_color(dst_surface
, 32, 32);
11567 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
11570 IDirectDrawSurface_Release(dst_surface
);
11571 IDirectDrawSurface_Release(src_surface
);
11572 refcount
= IDirectDraw2_Release(ddraw
);
11573 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
11574 DestroyWindow(window
);
11577 static void test_cross_device_blt(void)
11579 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
11580 IDirect3DDevice2
*device
, *device2
;
11581 IDirectDraw2
*ddraw
, *ddraw2
;
11582 DDSURFACEDESC surface_desc
;
11583 HWND window
, window2
;
11584 unsigned int color
;
11589 window
= create_window();
11590 ddraw
= create_ddraw();
11591 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
11593 skip("Failed to create a 3D device.\n");
11594 IDirectDraw2_Release(ddraw
);
11595 DestroyWindow(window
);
11599 window2
= create_window();
11600 ddraw2
= create_ddraw();
11601 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
11603 skip("Failed to create a 3D device.\n");
11604 IDirectDraw2_Release(ddraw2
);
11605 IDirect3DDevice2_Release(device
);
11606 IDirectDraw2_Release(ddraw
);
11607 DestroyWindow(window
);
11608 DestroyWindow(window2
);
11612 memset(&surface_desc
, 0, sizeof(surface_desc
));
11613 surface_desc
.dwSize
= sizeof(surface_desc
);
11614 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11615 surface_desc
.dwWidth
= 640;
11616 surface_desc
.dwHeight
= 480;
11617 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11618 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
11619 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11621 memset(&surface_desc
, 0, sizeof(surface_desc
));
11622 surface_desc
.dwSize
= sizeof(surface_desc
);
11623 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11624 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
11625 surface_desc
.dwBackBufferCount
= 2;
11626 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11627 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11629 memset(&surface_desc
, 0, sizeof(surface_desc
));
11630 surface_desc
.dwSize
= sizeof(surface_desc
);
11631 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11632 surface_desc
.dwWidth
= 640;
11633 surface_desc
.dwHeight
= 480;
11634 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11635 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11636 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11637 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
11638 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00007c00;
11639 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x000003e0;
11640 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x0000001f;
11641 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11642 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11644 memset(&fx
, 0, sizeof(fx
));
11645 fx
.dwSize
= sizeof(fx
);
11646 fx
.dwFillColor
= 0xff0000ff;
11647 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11648 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
11650 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11651 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11652 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
11653 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
11654 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11655 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11656 color
= get_surface_color(surface
, 320, 240);
11657 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11659 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11660 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11661 color
= get_surface_color(sysmem_surface
, 320, 240);
11662 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11664 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11665 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11666 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
11667 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11669 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11670 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
11671 color
= get_surface_color(sysmem_surface
, 320, 240);
11672 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
11674 IDirectDrawSurface_Release(surface2
);
11675 memset(&surface_desc
, 0, sizeof(surface_desc
));
11676 surface_desc
.dwSize
= sizeof(surface_desc
);
11677 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11678 surface_desc
.dwWidth
= 640;
11679 surface_desc
.dwHeight
= 480;
11680 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11681 hr
= IDirectDraw2_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
11682 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11683 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11684 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
11686 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
11687 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#lx.\n", hr
);
11688 color
= get_surface_color(sysmem_surface
, 320, 240);
11689 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11691 IDirectDrawSurface_Release(surface
);
11692 IDirectDrawSurface_Release(surface2
);
11693 IDirectDrawSurface_Release(sysmem_surface
);
11694 refcount
= IDirect3DDevice2_Release(device
);
11695 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11696 refcount
= IDirect3DDevice2_Release(device2
);
11697 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11698 IDirectDraw2_Release(ddraw
);
11699 IDirectDraw2_Release(ddraw2
);
11700 DestroyWindow(window
);
11701 DestroyWindow(window2
);
11704 static void test_getdc(void)
11706 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
11707 DDSURFACEDESC surface_desc
, map_desc
;
11708 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
11709 IDirectDraw2
*ddraw
;
11710 unsigned int i
, screen_bpp
;
11715 static const struct
11718 DDPIXELFORMAT format
;
11719 BOOL getdc_supported
;
11720 HRESULT alt_result
;
11724 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11725 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
11726 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11727 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
11728 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11729 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11730 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11731 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11732 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11733 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
11734 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11735 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11736 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11737 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11738 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11739 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
11740 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11741 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11742 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11743 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11744 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
11745 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
11746 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
11747 * This is not implemented in wine yet, so disable the test for now.
11748 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
11749 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
11750 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
11752 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
11753 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11754 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
11755 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
11756 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
11757 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11758 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
11759 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11760 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
11761 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11762 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
11763 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11764 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
11765 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11768 window
= create_window();
11769 ddraw
= create_ddraw();
11770 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11771 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11772 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11774 surface_desc
.dwSize
= sizeof(surface_desc
);
11775 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
11776 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11777 screen_bpp
= surface_desc
.ddpfPixelFormat
.dwRGBBitCount
;
11779 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11781 memset(&surface_desc
, 0, sizeof(surface_desc
));
11782 surface_desc
.dwSize
= sizeof(surface_desc
);
11783 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11784 surface_desc
.dwWidth
= 64;
11785 surface_desc
.dwHeight
= 64;
11786 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
11787 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11789 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11791 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11792 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11794 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", test_data
[i
].name
, hr
);
11799 dc
= (void *)0x1234;
11800 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11801 if (test_data
[i
].getdc_supported
)
11802 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
11803 "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11805 ok(FAILED(hr
), "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11809 unsigned int width_bytes
;
11815 type
= GetObjectType(dc
);
11816 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
11817 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
11818 type
= GetObjectType(bitmap
);
11819 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
11821 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
11822 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
11823 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
11824 dib
.dsBm
.bmType
, test_data
[i
].name
);
11825 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11826 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
11827 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11828 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
11829 width_bytes
= ((dib
.dsBm
.bmWidth
* test_data
[i
].format
.dwRGBBitCount
+ 31) >> 3) & ~3;
11830 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
11831 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
11832 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
11833 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
11834 ok(dib
.dsBm
.bmBitsPixel
== test_data
[i
].format
.dwRGBBitCount
,
11835 "Got unexpected bit count %d for format %s.\n",
11836 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
11837 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
11838 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
11839 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
11840 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
11841 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
11843 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %lu for format %s.\n",
11844 dib
.dsBmih
.biSize
, test_data
[i
].name
);
11845 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %ld for format %s.\n",
11846 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11847 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %ld for format %s.\n",
11848 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11849 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
11850 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
11851 ok(dib
.dsBmih
.biBitCount
== test_data
[i
].format
.dwRGBBitCount
,
11852 "Got unexpected bit count %u for format %s.\n",
11853 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
11854 ok(dib
.dsBmih
.biCompression
== (test_data
[i
].format
.dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
11855 || broken(test_data
[i
].format
.dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
11856 "Got unexpected compression %#lx for format %s.\n",
11857 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
11858 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %lu for format %s.\n",
11859 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
11860 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %ld for format %s.\n",
11861 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
11862 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %ld for format %s.\n",
11863 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
11864 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %lu for format %s.\n",
11865 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
11866 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %lu for format %s.\n",
11867 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
11869 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11871 ok((dib
.dsBitfields
[0] == test_data
[i
].format
.dwRBitMask
11872 && dib
.dsBitfields
[1] == test_data
[i
].format
.dwGBitMask
11873 && dib
.dsBitfields
[2] == test_data
[i
].format
.dwBBitMask
)
11874 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11875 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11876 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11880 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11881 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11882 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11884 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11885 ok(!dib
.dsOffset
, "Got unexpected offset %lu for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11887 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11888 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11892 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11895 IDirectDrawSurface_Release(surface
);
11900 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11901 if (FAILED(hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11903 skip("Failed to create mip-mapped texture for format %s (hr %#lx), skipping tests.\n",
11904 test_data
[i
].name
, hr
);
11908 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
11909 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11910 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
11911 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11912 IDirectDrawSurface_Release(tmp
);
11914 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11915 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11916 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11917 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11918 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11919 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11920 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11921 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11923 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11924 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11925 dc2
= (void *)0x1234;
11926 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11927 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11928 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11929 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11930 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11931 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11932 ok(hr
== DDERR_NODC
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11934 map_desc
.dwSize
= sizeof(map_desc
);
11935 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11936 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11937 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11938 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11939 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11940 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11941 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11942 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11944 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11945 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11946 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11947 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11948 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11949 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11951 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11952 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11953 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11954 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11955 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11956 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11957 /* Geforce 9600, Windows 7 returns E_FAIL. The unlock still seems to work as intended, after-
11958 * wards the surface can be locked again. ReleaseDC() does not unlock the surface, trying to
11959 * Lock it after ReleaseDC returns DDERR_SURFACEBUSY. ddraw4 and 7 are unaffected. */
11960 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11961 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11962 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11964 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11965 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11966 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
11967 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11968 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
11969 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11970 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11971 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11973 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11974 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11975 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11976 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11977 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
11978 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11979 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11980 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11982 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11983 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11984 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11985 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11986 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11987 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11988 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11989 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11991 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11992 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11993 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11994 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11995 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11996 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11997 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11998 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11999 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12001 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12002 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12003 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
12004 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12005 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
12006 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12007 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
12008 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12010 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
12011 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12012 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12013 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12014 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
12015 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12016 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
12017 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12019 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
12020 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12021 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12022 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12023 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
12024 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12025 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
12026 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12028 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
12029 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12030 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
12031 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12032 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
12033 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12034 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
12035 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12036 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
12037 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12039 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
12040 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12041 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
12042 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12043 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
12044 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12045 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
12046 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
12047 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
12048 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
12050 IDirectDrawSurface_Release(surface2
);
12051 IDirectDrawSurface_Release(surface
);
12054 IDirectDraw2_Release(ddraw
);
12055 DestroyWindow(window
);
12058 static void test_draw_primitive(void)
12060 static WORD indices
[] = {0, 1, 2, 3};
12061 static D3DVERTEX quad
[] =
12063 {{-1.0f
}, {-1.0f
}, {0.0f
}},
12064 {{-1.0f
}, { 1.0f
}, {0.0f
}},
12065 {{ 1.0f
}, {-1.0f
}, {0.0f
}},
12066 {{ 1.0f
}, { 1.0f
}, {0.0f
}},
12068 IDirect3DViewport2
*viewport
;
12069 IDirect3DDevice2
*device
;
12070 IDirectDraw2
*ddraw
;
12076 window
= create_window();
12077 ddraw
= create_ddraw();
12078 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12079 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12081 skip("Failed to create a 3D device, skipping test.\n");
12082 IDirectDraw2_Release(ddraw
);
12083 DestroyWindow(window
);
12087 viewport
= create_viewport(device
, 0, 0, 640, 480);
12088 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12089 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12091 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
12092 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
12094 IDirect3D2_Release(d3d
);
12096 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
12097 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12098 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
12099 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12101 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
12102 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12104 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
12105 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12106 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
12107 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12108 hr
= IDirect3DDevice2_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
12109 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12111 destroy_viewport(device
, viewport
);
12112 refcount
= IDirect3DDevice2_Release(device
);
12113 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12114 IDirectDraw2_Release(ddraw
);
12115 DestroyWindow(window
);
12118 static void test_edge_antialiasing_blending(void)
12120 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12121 IDirect3DMaterial2
*green_background
;
12122 IDirect3DMaterial2
*red_background
;
12123 IDirectDrawSurface
*offscreen
, *ds
;
12124 D3DDEVICEDESC hal_desc
, hel_desc
;
12125 IDirect3DViewport2
*viewport
;
12126 DDSURFACEDESC surface_desc
;
12127 IDirect3DDevice2
*device
;
12128 IDirectDraw2
*ddraw
;
12129 unsigned int color
;
12134 static D3DMATRIX mat
=
12136 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12137 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12138 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12139 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12141 static D3DLVERTEX green_quad
[] =
12143 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
12144 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
12145 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
12146 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0x7f00ff00}},
12148 static D3DLVERTEX red_quad
[] =
12150 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
12151 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
12152 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xccff0000}},
12153 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xccff0000}},
12156 window
= create_window();
12157 ddraw
= create_ddraw();
12158 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12159 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12161 skip("Failed to create a 3D device.\n");
12162 DestroyWindow(window
);
12166 memset(&hal_desc
, 0, sizeof(hal_desc
));
12167 hal_desc
.dwSize
= sizeof(hal_desc
);
12168 memset(&hel_desc
, 0, sizeof(hel_desc
));
12169 hel_desc
.dwSize
= sizeof(hel_desc
);
12170 hr
= IDirect3DDevice2_GetCaps(device
, &hal_desc
, &hel_desc
);
12171 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
12172 trace("HAL line edge antialiasing support: %#lx.\n",
12173 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12174 trace("HAL triangle edge antialiasing support: %#lx.\n",
12175 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12176 trace("HEL line edge antialiasing support: %#lx.\n",
12177 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12178 trace("HEL triangle edge antialiasing support: %#lx.\n",
12179 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12181 memset(&surface_desc
, 0, sizeof(surface_desc
));
12182 surface_desc
.dwSize
= sizeof(surface_desc
);
12183 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12184 surface_desc
.dwWidth
= 640;
12185 surface_desc
.dwHeight
= 480;
12186 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
12187 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
12188 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12189 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
12190 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
12191 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
12192 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
12193 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
12194 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12195 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#lx.\n", hr
);
12197 ds
= get_depth_stencil(device
);
12198 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
12199 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
12200 IDirectDrawSurface_Release(ds
);
12202 hr
= IDirect3DDevice2_SetRenderTarget(device
, offscreen
, 0);
12203 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
12205 red_background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 0.8f
);
12206 green_background
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.5f
);
12208 viewport
= create_viewport(device
, 0, 0, 640, 480);
12209 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12210 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12212 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12213 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12214 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12215 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
12216 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12217 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
12218 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12219 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#lx.\n", hr
);
12220 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12221 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
12222 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12223 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
12225 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
12226 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#lx.\n", hr
);
12227 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
12228 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#lx.\n", hr
);
12229 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
12230 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#lx.\n", hr
);
12232 viewport_set_background(device
, viewport
, red_background
);
12233 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12234 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12235 hr
= IDirect3DDevice2_BeginScene(device
);
12236 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12237 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12238 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12239 hr
= IDirect3DDevice2_EndScene(device
);
12240 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12241 color
= get_surface_color(offscreen
, 320, 240);
12242 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12244 viewport_set_background(device
, viewport
, green_background
);
12245 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12246 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12247 hr
= IDirect3DDevice2_BeginScene(device
);
12248 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12249 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12250 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12251 hr
= IDirect3DDevice2_EndScene(device
);
12252 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12253 color
= get_surface_color(offscreen
, 320, 240);
12254 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12256 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
12257 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#lx.\n", hr
);
12259 viewport_set_background(device
, viewport
, red_background
);
12260 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12261 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12262 hr
= IDirect3DDevice2_BeginScene(device
);
12263 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12264 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12265 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12266 hr
= IDirect3DDevice2_EndScene(device
);
12267 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12268 color
= get_surface_color(offscreen
, 320, 240);
12269 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12271 viewport_set_background(device
, viewport
, green_background
);
12272 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12273 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12274 hr
= IDirect3DDevice2_BeginScene(device
);
12275 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12276 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12277 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12278 hr
= IDirect3DDevice2_EndScene(device
);
12279 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12280 color
= get_surface_color(offscreen
, 320, 240);
12281 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12283 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
12284 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#lx.\n", hr
);
12286 viewport_set_background(device
, viewport
, red_background
);
12287 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12288 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12289 hr
= IDirect3DDevice2_BeginScene(device
);
12290 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12291 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, green_quad
, 4, 0);
12292 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12293 hr
= IDirect3DDevice2_EndScene(device
);
12294 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12295 color
= get_surface_color(offscreen
, 320, 240);
12296 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12298 viewport_set_background(device
, viewport
, green_background
);
12299 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12300 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
12301 hr
= IDirect3DDevice2_BeginScene(device
);
12302 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12303 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, red_quad
, 4, 0);
12304 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12305 hr
= IDirect3DDevice2_EndScene(device
);
12306 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12307 color
= get_surface_color(offscreen
, 320, 240);
12308 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12310 IDirectDrawSurface_Release(offscreen
);
12311 destroy_viewport(device
, viewport
);
12312 destroy_material(red_background
);
12313 destroy_material(green_background
);
12314 refcount
= IDirect3DDevice2_Release(device
);
12315 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12316 IDirectDraw2_Release(ddraw
);
12317 DestroyWindow(window
);
12320 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
12321 * The stride is honored for navigating to the next vertex. 3 floats input position
12322 * are read, and 16 bytes extra vertex data are copied around. */
12323 struct transform_input
12325 float x
, y
, z
, unused1
; /* Position data, transformed. */
12326 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
12330 struct transform_output
12333 unsigned int v1
, v2
, v3
, v4
;
12334 unsigned int unused3
, unused4
;
12337 static void test_transform_vertices(void)
12339 IDirect3DDevice2
*device
;
12340 IDirectDrawSurface
*rt
;
12341 unsigned int color
, i
;
12342 IDirectDraw2
*ddraw
;
12346 IDirect3DViewport2
*viewport
;
12347 IDirect3DMaterial2
*background
;
12349 static struct transform_input position_tests
[] =
12351 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12352 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
12353 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
12354 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
12355 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
12356 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
12358 static struct transform_input cliptest
[] =
12360 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
12361 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
12362 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12363 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
12365 static struct transform_input offscreentest
[] =
12367 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12369 struct transform_output out
[ARRAY_SIZE(position_tests
)];
12370 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
12371 D3DTRANSFORMDATA transformdata
;
12372 static const D3DVIEWPORT vp_template
=
12374 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
12376 D3DVIEWPORT vp_data
=
12378 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
12380 D3DVIEWPORT2 vp2_data
;
12382 static D3DMATRIX mat_scale
=
12384 2.0f
, 0.0f
, 0.0f
, 0.0f
,
12385 0.0f
, 2.0f
, 0.0f
, 0.0f
,
12386 0.0f
, 0.0f
, 2.0f
, 0.0f
,
12387 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12391 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12392 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12393 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12394 1.0f
, 0.0f
, 0.0f
, 1.0f
,
12398 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12399 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12400 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12401 0.0f
, 1.0f
, 0.0f
, 1.0f
,
12405 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12406 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12407 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12408 0.0f
, 19.2f
, 0.0f
, 2.0f
,
12412 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12413 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12414 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12415 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12417 static D3DLVERTEX quad
[] =
12419 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12420 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12421 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
12422 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
12424 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12427 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
12429 out
[i
].unused3
= 0xdeadbeef;
12430 out
[i
].unused4
= 0xcafecafe;
12433 window
= create_window();
12434 ddraw
= create_ddraw();
12435 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12436 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12438 skip("Failed to create a 3D device, skipping test.\n");
12439 IDirectDraw2_Release(ddraw
);
12440 DestroyWindow(window
);
12443 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
12444 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12446 viewport
= create_viewport(device
, 0, 0, 256, 256);
12447 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12448 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12450 memset(&transformdata
, 0, sizeof(transformdata
));
12451 transformdata
.dwSize
= sizeof(transformdata
);
12452 transformdata
.lpIn
= position_tests
;
12453 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12454 transformdata
.lpOut
= out
;
12455 transformdata
.dwOutSize
= sizeof(out
[0]);
12456 transformdata
.lpHOut
= NULL
;
12458 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12459 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12460 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12461 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12463 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12465 static const struct vec4 cmp
[] =
12467 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
12468 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
12471 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12472 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12473 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12474 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
12475 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
12476 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
12477 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
12478 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
12481 vp_data
= vp_template
;
12482 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12483 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12484 offscreen
= 0xdeadbeef;
12485 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12486 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12487 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12488 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12490 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12492 static const struct vec4 cmp
[] =
12494 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
12495 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
12497 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12498 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12499 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12504 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12505 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12506 offscreen
= 0xdeadbeef;
12507 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12508 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12509 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12510 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12511 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12513 static const struct vec4 cmp
[] =
12515 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
12516 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12518 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12519 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12520 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12523 transformdata
.lpHOut
= out_h
;
12524 offscreen
= 0xdeadbeef;
12525 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12526 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12527 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12528 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12529 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12531 static const D3DHVERTEX cmp_h
[] =
12533 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
12534 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
12535 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
12537 ok(compare_float(cmp_h
[i
].hx
, out_h
[i
].hx
, 4096)
12538 && compare_float(cmp_h
[i
].hy
, out_h
[i
].hy
, 4096)
12539 && compare_float(cmp_h
[i
].hz
, out_h
[i
].hz
, 4096)
12540 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12541 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
12542 out_h
[i
].dwFlags
, out_h
[i
].hx
, out_h
[i
].hy
, out_h
[i
].hz
);
12544 /* No scheme has been found behind those return values. It seems to be
12545 * whatever data windows has when throwing the vertex away. Modify the
12546 * input test vertices to test this more. Depending on the input data
12547 * it can happen that the z coord gets written into y, or similar things. */
12550 static const struct vec4 cmp
[] =
12552 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
12553 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12555 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12556 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12557 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12561 transformdata
.lpIn
= cliptest
;
12562 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12563 offscreen
= 0xdeadbeef;
12564 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12565 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12566 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12567 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12568 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12570 static const DWORD flags
[] =
12573 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
12575 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
12577 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12580 vp_data
= vp_template
;
12581 vp_data
.dwWidth
= 10;
12582 vp_data
.dwHeight
= 480;
12583 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12584 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12585 offscreen
= 0xdeadbeef;
12586 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12587 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12588 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12589 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12590 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12592 static const DWORD flags
[] =
12595 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
12597 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
12599 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12602 vp_data
= vp_template
;
12603 vp_data
.dwWidth
= 256;
12604 vp_data
.dwHeight
= 256;
12605 vp_data
.dvScaleX
= 1;
12606 vp_data
.dvScaleY
= 1;
12607 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12608 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12609 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12610 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12611 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12612 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12613 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12615 static const DWORD flags
[] =
12622 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
12625 /* Finally try to figure out how the DWORD dwOffscreen works.
12626 * It is a logical AND of the vertices' dwFlags members. */
12627 vp_data
= vp_template
;
12628 vp_data
.dwWidth
= 5;
12629 vp_data
.dwHeight
= 5;
12630 vp_data
.dvScaleX
= 10000.0f
;
12631 vp_data
.dvScaleY
= 10000.0f
;
12632 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12633 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12634 transformdata
.lpIn
= cliptest
;
12635 offscreen
= 0xdeadbeef;
12636 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12637 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12638 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12639 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12641 offscreen
= 0xdeadbeef;
12642 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12643 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12644 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12645 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12646 offscreen
= 0xdeadbeef;
12647 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12648 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12649 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12650 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12651 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
12652 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12653 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12654 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12656 transformdata
.lpIn
= cliptest
+ 1;
12657 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12658 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12659 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12660 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
12662 transformdata
.lpIn
= cliptest
+ 2;
12663 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12664 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12665 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12666 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12667 offscreen
= 0xdeadbeef;
12668 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12669 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12670 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12671 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12673 transformdata
.lpIn
= cliptest
+ 3;
12674 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12675 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12676 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12677 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
12679 transformdata
.lpIn
= offscreentest
;
12680 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
12681 vp_data
= vp_template
;
12682 vp_data
.dwWidth
= 257;
12683 vp_data
.dwHeight
= 257;
12684 vp_data
.dvScaleX
= 1.0f
;
12685 vp_data
.dvScaleY
= 1.0f
;
12686 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12687 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12688 offscreen
= 0xdeadbeef;
12689 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12690 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12691 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12692 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12694 vp_data
.dwWidth
= 256;
12695 vp_data
.dwHeight
= 256;
12696 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12697 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12698 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12699 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12700 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12701 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %#lx.\n", offscreen
);
12703 /* Test the effect of Matrices.
12705 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
12706 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
12707 * the view matrix and the +1's from the world and projection matrix. */
12710 vp_data
.dwWidth
= 256;
12711 vp_data
.dwHeight
= 256;
12712 vp_data
.dvScaleX
= 5.0f
;
12713 vp_data
.dvScaleY
= 5.0f
;
12714 vp_data
.dvMinZ
= 0.0f
;
12715 vp_data
.dvMaxZ
= 1.0f
;
12716 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12717 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12719 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
12720 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12721 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
12722 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12723 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
12724 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12726 transformdata
.lpIn
= position_tests
;
12727 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12728 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12729 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12730 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12732 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12734 static const struct vec4 cmp
[] =
12736 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
12737 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
12740 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12741 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12742 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12745 /* Invalid flags. */
12746 offscreen
= 0xdeadbeef;
12747 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12748 &transformdata
, 0, &offscreen
);
12749 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12750 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12752 /* NULL transform data. */
12753 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12754 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12755 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12756 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12757 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12758 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12759 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12760 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12762 /* NULL transform data and NULL dwOffscreen.
12764 * Valid transform data + NULL dwOffscreen -> crash. */
12765 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12766 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
12767 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12770 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12771 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12772 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12773 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12774 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12775 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12776 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12777 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
12779 /* Invalid sizes. */
12780 offscreen
= 0xdeadbeef;
12781 transformdata
.dwSize
= sizeof(transformdata
) - 1;
12782 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12783 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12784 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12785 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12786 transformdata
.dwSize
= sizeof(transformdata
) + 1;
12787 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12788 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12789 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
12790 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
12792 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
12793 transformdata
.dwSize
= sizeof(transformdata
);
12794 transformdata
.lpIn
= NULL
;
12795 transformdata
.lpOut
= NULL
;
12796 offscreen
= 0xdeadbeef;
12797 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12798 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12799 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12800 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
12802 /* Test how vertices are transformed during draws. */
12805 vp_data
.dwWidth
= 200;
12806 vp_data
.dwHeight
= 400;
12807 vp_data
.dvScaleX
= 20.0f
;
12808 vp_data
.dvScaleY
= 50.0f
;
12809 vp_data
.dvMinZ
= 0.0f
;
12810 vp_data
.dvMaxZ
= 1.0f
;
12811 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12812 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
12813 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
12814 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12816 ok(SUCCEEDED(hr
), "Failed to clear the render target, hr %#lx.\n", hr
);
12817 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
12818 viewport_set_background(device
, viewport
, background
);
12819 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12820 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12822 hr
= IDirect3DDevice2_BeginScene(device
);
12823 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12824 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12825 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12826 hr
= IDirect3DDevice2_EndScene(device
);
12827 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12829 color
= get_surface_color(rt
, 128, 143);
12830 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12831 color
= get_surface_color(rt
, 132, 143);
12832 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12833 color
= get_surface_color(rt
, 128, 147);
12834 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12835 color
= get_surface_color(rt
, 132, 147);
12836 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12838 color
= get_surface_color(rt
, 177, 217);
12839 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12840 color
= get_surface_color(rt
, 181, 217);
12841 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12842 color
= get_surface_color(rt
, 177, 221);
12843 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12844 color
= get_surface_color(rt
, 181, 221);
12845 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12847 /* Test D3DVIEWPORT2 behavior. */
12848 vp2_data
.dwSize
= sizeof(vp2_data
);
12851 vp2_data
.dwWidth
= 200;
12852 vp2_data
.dwHeight
= 400;
12853 vp2_data
.dvClipX
= -0.5f
;
12854 vp2_data
.dvClipY
= 4.0f
;
12855 vp2_data
.dvClipWidth
= 5.0f
;
12856 vp2_data
.dvClipHeight
= 10.0f
;
12857 vp2_data
.dvMinZ
= 0.0f
;
12858 vp2_data
.dvMaxZ
= 2.0f
;
12859 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12860 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
12861 transformdata
.lpIn
= position_tests
;
12862 transformdata
.lpOut
= out
;
12863 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12864 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12865 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12866 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12868 static const struct vec4 cmp
[] =
12870 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
12871 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
12874 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12875 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
12876 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12879 memset(&mat
, 0, sizeof(mat
));
12880 mat
.dwSize
= sizeof(mat
);
12881 mat
.diffuse
.r
= 0.0f
;
12882 mat
.diffuse
.g
= 1.0f
;
12883 mat
.diffuse
.b
= 0.0f
;
12884 mat
.diffuse
.a
= 0.0f
;
12885 hr
= IDirect3DMaterial2_SetMaterial(background
, &mat
);
12886 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
12887 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12888 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12890 hr
= IDirect3DDevice2_BeginScene(device
);
12891 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12892 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
12893 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12894 hr
= IDirect3DDevice2_EndScene(device
);
12895 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12897 color
= get_surface_color(rt
, 58, 118);
12898 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12899 color
= get_surface_color(rt
, 62, 118);
12900 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12901 color
= get_surface_color(rt
, 58, 122);
12902 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12903 color
= get_surface_color(rt
, 62, 122);
12904 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12906 color
= get_surface_color(rt
, 157, 177);
12907 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12908 color
= get_surface_color(rt
, 161, 177);
12909 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12910 color
= get_surface_color(rt
, 157, 181);
12911 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12912 color
= get_surface_color(rt
, 161, 181);
12913 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12915 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
12916 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12917 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
12918 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12919 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
12920 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
12922 vp2_data
.dwX
= 0.0;
12923 vp2_data
.dwY
= 0.0;
12924 vp2_data
.dwWidth
= 1;
12925 vp2_data
.dwHeight
= 1;
12926 vp2_data
.dvClipX
= -12.8f
;
12927 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
12928 vp2_data
.dvClipWidth
= 25.6f
;
12929 vp2_data
.dvClipHeight
= 25.6f
;
12930 vp2_data
.dvMinZ
= 0.0f
;
12931 vp2_data
.dvMaxZ
= 0.5f
;
12932 hr
= IDirect3DViewport2_SetViewport2(viewport
, &vp2_data
);
12933 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
12934 transformdata
.lpIn
= cliptest
;
12935 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12936 offscreen
= 0xdeadbeef;
12937 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12938 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12939 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
12940 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
12941 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12943 static const D3DHVERTEX cmp_h
[] =
12945 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
12946 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
12947 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
12948 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
12950 ok(compare_float(cmp_h
[i
].hx
, out_h
[i
].hx
, 4096)
12951 && compare_float(cmp_h
[i
].hy
, out_h
[i
].hy
, 4096)
12952 && compare_float(cmp_h
[i
].hz
, out_h
[i
].hz
, 4096)
12953 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12954 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
12955 out_h
[i
].dwFlags
, out_h
[i
].hx
, out_h
[i
].hy
, out_h
[i
].hz
);
12958 IDirectDrawSurface_Release(rt
);
12959 destroy_viewport(device
, viewport
);
12960 IDirect3DMaterial2_Release(background
);
12961 refcount
= IDirect3DDevice_Release(device
);
12962 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12963 IDirectDraw2_Release(ddraw
);
12964 DestroyWindow(window
);
12967 static void test_display_mode_surface_pixel_format(void)
12969 unsigned int width
, height
, bpp
;
12970 IDirectDrawSurface
*surface
;
12971 DDSURFACEDESC surface_desc
;
12972 IDirectDraw2
*ddraw
;
12977 if (!(ddraw
= create_ddraw()))
12979 skip("Failed to create ddraw.\n");
12983 surface_desc
.dwSize
= sizeof(surface_desc
);
12984 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
12985 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
12986 width
= surface_desc
.dwWidth
;
12987 height
= surface_desc
.dwHeight
;
12989 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
12990 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
12991 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
12992 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12995 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
12997 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
12999 if (SUCCEEDED(IDirectDraw2_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
13001 ok(bpp
, "Set display mode failed.\n");
13003 surface_desc
.dwSize
= sizeof(surface_desc
);
13004 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
13005 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
13006 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
13007 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
13008 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
13009 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
13011 memset(&surface_desc
, 0, sizeof(surface_desc
));
13012 surface_desc
.dwSize
= sizeof(surface_desc
);
13013 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13014 surface_desc
.dwBackBufferCount
= 1;
13015 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
13016 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13017 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
13018 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
13019 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13020 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
13021 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
13022 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
13023 surface_desc
.ddpfPixelFormat
.dwFlags
);
13024 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
13025 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
13026 IDirectDrawSurface_Release(surface
);
13028 memset(&surface_desc
, 0, sizeof(surface_desc
));
13029 surface_desc
.dwSize
= sizeof(surface_desc
);
13030 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13031 surface_desc
.dwWidth
= width
;
13032 surface_desc
.dwHeight
= height
;
13033 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13034 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13035 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
13036 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
13037 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13038 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
13039 surface_desc
.ddpfPixelFormat
.dwFlags
);
13040 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
13041 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
13042 IDirectDrawSurface_Release(surface
);
13044 refcount
= IDirectDraw2_Release(ddraw
);
13045 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13046 DestroyWindow(window
);
13049 static void test_surface_desc_size(void)
13054 DDSURFACEDESC desc1
;
13055 DDSURFACEDESC2 desc2
;
13058 IDirectDrawSurface7
*surface7
;
13059 IDirectDrawSurface2
*surface2
;
13060 IDirectDrawSurface
*surface
;
13061 DDSURFACEDESC surface_desc
;
13062 HRESULT expected_hr
, hr
;
13063 IDirectDraw2
*ddraw
;
13067 static const struct
13074 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
13075 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
13076 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
13078 static const unsigned int desc_sizes
[] =
13080 sizeof(DDSURFACEDESC
),
13081 sizeof(DDSURFACEDESC2
),
13082 sizeof(DDSURFACEDESC
) + 1,
13083 sizeof(DDSURFACEDESC2
) + 1,
13084 2 * sizeof(DDSURFACEDESC
),
13085 2 * sizeof(DDSURFACEDESC2
),
13086 sizeof(DDSURFACEDESC
) - 1,
13087 sizeof(DDSURFACEDESC2
) - 1,
13088 sizeof(DDSURFACEDESC
) / 2,
13089 sizeof(DDSURFACEDESC2
) / 2,
13094 sizeof(desc
) - 100,
13097 if (!(ddraw
= create_ddraw()))
13099 skip("Failed to create ddraw.\n");
13102 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13103 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13105 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
13107 memset(&surface_desc
, 0, sizeof(surface_desc
));
13108 surface_desc
.dwSize
= sizeof(surface_desc
);
13109 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13110 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
13111 surface_desc
.dwHeight
= 128;
13112 surface_desc
.dwWidth
= 128;
13113 if (FAILED(IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13115 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
13118 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
13119 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface2, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
13120 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
13121 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
13123 /* GetSurfaceDesc() */
13124 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13126 memset(&desc
, 0, sizeof(desc
));
13127 desc
.dwSize
= desc_sizes
[j
];
13128 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13129 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
13130 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13131 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13133 memset(&desc
, 0, sizeof(desc
));
13134 desc
.dwSize
= desc_sizes
[j
];
13135 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13136 hr
= IDirectDrawSurface2_GetSurfaceDesc(surface2
, &desc
.desc1
);
13137 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13138 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13140 memset(&desc
, 0, sizeof(desc
));
13141 desc
.dwSize
= desc_sizes
[j
];
13142 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13143 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
13144 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13145 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13149 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13151 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
13152 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
13153 DWORD expected_texture_stage
;
13155 memset(&desc
, 0, sizeof(desc
));
13156 desc
.dwSize
= desc_sizes
[j
];
13157 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13158 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13159 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
13160 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13161 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13162 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13163 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
13164 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13165 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
13166 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13169 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
13170 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13171 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13172 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13173 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13174 todo_wine_if(!expected_texture_stage
)
13175 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13176 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13177 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13178 IDirectDrawSurface_Unlock(surface
, NULL
);
13181 memset(&desc
, 0, sizeof(desc
));
13182 desc
.dwSize
= desc_sizes
[j
];
13183 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13184 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13185 hr
= IDirectDrawSurface2_Lock(surface2
, NULL
, &desc
.desc1
, 0, 0);
13186 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13187 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13188 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13189 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
13190 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13191 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
13192 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13195 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
13196 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13197 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13198 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13199 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13200 todo_wine_if(!expected_texture_stage
)
13201 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13202 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13203 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13204 IDirectDrawSurface2_Unlock(surface2
, NULL
);
13207 memset(&desc
, 0, sizeof(desc
));
13208 desc
.dwSize
= desc_sizes
[j
];
13209 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13210 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13211 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
13212 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13213 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
13214 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13215 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
13216 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13217 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
13218 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13221 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
13222 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13223 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
13224 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13225 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13226 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13227 "Got unexpected texture stage %#lx, size %u, type %s.\n",
13228 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13229 IDirectDrawSurface7_Unlock(surface7
, NULL
);
13233 IDirectDrawSurface7_Release(surface7
);
13234 IDirectDrawSurface2_Release(surface2
);
13235 IDirectDrawSurface_Release(surface
);
13238 /* GetDisplayMode() */
13239 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13241 memset(&desc
, 0xcc, sizeof(desc
));
13242 desc
.dwSize
= desc_sizes
[j
];
13243 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
13244 ? DD_OK
: DDERR_INVALIDPARAMS
;
13245 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
.desc1
);
13246 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
13249 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %lu for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
13250 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
13251 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
13255 refcount
= IDirectDraw2_Release(ddraw
);
13256 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13259 static void test_ck_operation(void)
13261 IDirectDrawSurface2
*src
, *dst
;
13262 IDirectDrawSurface7
*src7
, *dst7
;
13263 IDirectDrawSurface
*surface1
;
13264 DDSURFACEDESC surface_desc
;
13265 unsigned int i
, *color
;
13266 IDirectDraw2
*ddraw
;
13273 window
= create_window();
13274 ddraw
= create_ddraw();
13275 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13276 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13277 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13279 memset(&surface_desc
, 0, sizeof(surface_desc
));
13280 surface_desc
.dwSize
= sizeof(surface_desc
);
13281 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13282 surface_desc
.dwWidth
= 4;
13283 surface_desc
.dwHeight
= 1;
13284 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13285 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13286 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
13287 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
13288 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
13289 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
13290 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13291 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13292 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
13293 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13294 IDirectDrawSurface_Release(surface1
);
13296 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
13297 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
13298 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
13299 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13300 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13301 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
13302 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13303 IDirectDrawSurface_Release(surface1
);
13305 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13306 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13307 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13308 color
= surface_desc
.lpSurface
;
13309 color
[0] = 0x77010203;
13310 color
[1] = 0x00010203;
13311 color
[2] = 0x77ff00ff;
13312 color
[3] = 0x00ff00ff;
13313 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
13314 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13316 for (i
= 0; i
< 2; ++i
)
13318 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13319 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13320 color
= surface_desc
.lpSurface
;
13321 color
[0] = 0xcccccccc;
13322 color
[1] = 0xcccccccc;
13323 color
[2] = 0xcccccccc;
13324 color
[3] = 0xcccccccc;
13325 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13326 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13330 hr
= IDirectDrawSurface2_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
13331 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13335 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
13336 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13339 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
13340 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13341 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13342 color
= surface_desc
.lpSurface
;
13343 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
13344 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
13345 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
13346 * color keying nor copies it. */
13347 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
13348 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
13349 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13350 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
13351 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13352 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
13353 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
13354 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
13355 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
13356 color
[0], color
[1], color
[2], color
[3], i
);
13357 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13358 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13361 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13362 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13363 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
13364 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13366 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13367 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13368 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13370 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13371 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13372 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13373 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
13374 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13376 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
13377 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
13378 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
13379 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13380 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
13381 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
13382 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13383 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13385 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
13386 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13387 ckey
.dwColorSpaceHighValue
= 0x00000000;
13388 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13389 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13391 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13392 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13393 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13394 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13395 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13397 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13398 ckey
.dwColorSpaceHighValue
= 0x00000001;
13399 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13400 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13402 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13403 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13404 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13405 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13406 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13408 ckey
.dwColorSpaceLowValue
= 0x000000fe;
13409 ckey
.dwColorSpaceHighValue
= 0x000000fd;
13410 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13411 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13413 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13414 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13415 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
13416 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
13417 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13419 IDirectDrawSurface2_Release(src
);
13420 IDirectDrawSurface2_Release(dst
);
13422 /* Test source and destination keys and where they are read from. Use a surface with alpha
13423 * to avoid driver-dependent content in the X channel. */
13424 memset(&surface_desc
, 0, sizeof(surface_desc
));
13425 surface_desc
.dwSize
= sizeof(surface_desc
);
13426 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13427 surface_desc
.dwWidth
= 6;
13428 surface_desc
.dwHeight
= 1;
13429 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13430 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13431 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
13432 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
13433 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
13434 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
13435 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
13436 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13437 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13438 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&dst
);
13439 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13440 IDirectDrawSurface_Release(surface1
);
13442 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
13443 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13444 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&src
);
13445 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface2, hr %#lx.\n", hr
);
13446 IDirectDrawSurface_Release(surface1
);
13448 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
13449 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13450 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
13451 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13452 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
13453 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
13454 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
13455 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#lx.\n", hr
);
13458 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
13459 skip("Failed to set destination color key, skipping related tests.\n");
13463 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13464 ckey
.dwColorSpaceHighValue
= 0x000000ff;
13465 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13466 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13467 ckey
.dwColorSpaceLowValue
= 0x000000aa;
13468 ckey
.dwColorSpaceHighValue
= 0x000000aa;
13469 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13470 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13472 memset(&fx
, 0, sizeof(fx
));
13473 fx
.dwSize
= sizeof(fx
);
13474 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
13475 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
13476 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
13477 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
13479 hr
= IDirectDrawSurface2_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13480 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13481 color
= surface_desc
.lpSurface
;
13482 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
13483 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
13484 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
13485 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
13486 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
13487 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
13488 hr
= IDirectDrawSurface2_Unlock(src
, NULL
);
13489 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13491 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13492 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13493 color
= surface_desc
.lpSurface
;
13494 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13495 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13496 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13498 /* Test a blit without keying. */
13499 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
13500 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13502 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13503 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13504 color
= surface_desc
.lpSurface
;
13505 /* Should have copied src data unmodified to dst. */
13506 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13507 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13508 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13509 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13511 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13512 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13513 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13516 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13517 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13519 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13520 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13521 color
= surface_desc
.lpSurface
;
13522 /* Src key applied to color[0]. It is unmodified, the others are copied. */
13523 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13524 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13525 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13526 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13528 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13529 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13530 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13532 /* Src override. */
13533 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
13534 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13536 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13537 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13538 color
= surface_desc
.lpSurface
;
13539 /* Override key applied to color[5]. It is unmodified, the others are copied. */
13540 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13541 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
13542 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13543 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13545 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13546 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13547 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13549 /* Src override AND src key. That is not supposed to work. */
13550 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
13551 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13553 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13554 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13555 color
= surface_desc
.lpSurface
;
13556 /* Ensure the destination was not changed. */
13557 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
13558 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
13559 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13560 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13562 /* Use different dst colors for the dst key test. */
13563 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13564 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13565 color
[2] = 0x00001100; /* Dest key in override. */
13566 color
[3] = 0x00001100; /* Dest key in override. */
13567 color
[4] = 0x000000aa; /* Dest key in src surface. */
13568 color
[5] = 0x000000aa; /* Dest key in src surface. */
13569 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13570 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13572 /* Dest key blit. The key is taken from the SOURCE surface in v2! */
13573 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13574 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13576 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13577 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13578 color
= surface_desc
.lpSurface
;
13579 /* Dst key applied to color[4,5], they are the only changed pixels. */
13580 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13581 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13582 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13583 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13585 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13586 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13587 color
[2] = 0x00001100; /* Dest key in override. */
13588 color
[3] = 0x00001100; /* Dest key in override. */
13589 color
[4] = 0x000000aa; /* Dest key in src surface. */
13590 color
[5] = 0x000000aa; /* Dest key in src surface. */
13591 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13592 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13594 /* What happens with a QI'd newer version of the interface? It takes the key
13595 * from the destination surface. */
13596 hr
= IDirectDrawSurface2_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
13597 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
13598 hr
= IDirectDrawSurface2_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
13599 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
13601 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
13602 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13604 IDirectDrawSurface7_Release(dst7
);
13605 IDirectDrawSurface7_Release(src7
);
13607 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13608 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13609 color
= surface_desc
.lpSurface
;
13610 /* Dst key applied to color[0,1], they are the only changed pixels. */
13611 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13612 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13613 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13614 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13616 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13617 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13618 color
[2] = 0x00001100; /* Dest key in override. */
13619 color
[3] = 0x00001100; /* Dest key in override. */
13620 color
[4] = 0x000000aa; /* Dest key in src surface. */
13621 color
[5] = 0x000000aa; /* Dest key in src surface. */
13622 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13623 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13625 /* Dest override key blit. */
13626 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
13627 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13629 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13630 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13631 color
= surface_desc
.lpSurface
;
13632 /* Dst key applied to color[2,3], they are the only changed pixels. */
13633 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
13634 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13635 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13636 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13638 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13639 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13640 color
[2] = 0x00001100; /* Dest key in override. */
13641 color
[3] = 0x00001100; /* Dest key in override. */
13642 color
[4] = 0x000000aa; /* Dest key in src surface. */
13643 color
[5] = 0x000000aa; /* Dest key in src surface. */
13644 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13645 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13647 /* Dest override together with surface key. Supposed to fail. */
13648 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
13649 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13651 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13652 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13653 color
= surface_desc
.lpSurface
;
13654 /* Destination is unchanged. */
13655 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13656 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13657 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13658 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13659 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13660 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13662 /* Source and destination key. This is driver dependent. New HW treats it like
13663 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
13666 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
13667 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13669 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13670 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13671 color
= surface_desc
.lpSurface
;
13672 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
13673 * the driver applies it. */
13674 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13675 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13676 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13677 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13679 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13680 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13681 color
[2] = 0x00001100; /* Dest key in override. */
13682 color
[3] = 0x00001100; /* Dest key in override. */
13683 color
[4] = 0x000000aa; /* Dest key in src surface. */
13684 color
[5] = 0x000000aa; /* Dest key in src surface. */
13685 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13686 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13689 /* Override keys without ddbltfx parameter fail */
13690 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
13691 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13692 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
13693 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13695 /* Try blitting without keys in the source surface. */
13696 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
13697 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13698 hr
= IDirectDrawSurface2_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
13699 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13701 /* That fails now. Do not bother to check that the data is unmodified. */
13702 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13703 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13705 /* Surprisingly this still works. It uses the old key from the src surface. */
13706 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13707 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13709 hr
= IDirectDrawSurface2_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13710 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13711 color
= surface_desc
.lpSurface
;
13712 /* Dst key applied to color[4,5], they are the only changed pixels. */
13713 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13714 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13715 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13716 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13717 hr
= IDirectDrawSurface2_Unlock(dst
, NULL
);
13718 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13720 /* This returns DDERR_NOCOLORKEY as expected. */
13721 hr
= IDirectDrawSurface2_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13722 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
13724 /* GetSurfaceDesc returns a zeroed key as expected. */
13725 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
13726 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
13727 hr
= IDirectDrawSurface2_GetSurfaceDesc(src
, &surface_desc
);
13728 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
13729 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
13730 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
13731 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13732 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13734 /* Try blitting without keys in the destination surface. */
13735 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
13736 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13737 hr
= IDirectDrawSurface2_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
13738 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
13740 /* This fails, as sanity would dictate. */
13741 hr
= IDirectDrawSurface2_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13742 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13745 IDirectDrawSurface2_Release(src
);
13746 IDirectDrawSurface2_Release(dst
);
13747 refcount
= IDirectDraw2_Release(ddraw
);
13748 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13749 DestroyWindow(window
);
13752 static void test_set_render_state(void)
13754 IDirect3DDevice2
*device
;
13755 IDirectDraw2
*ddraw
;
13761 window
= create_window();
13762 ddraw
= create_ddraw();
13763 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13764 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13766 skip("Failed to create 3D device.\n");
13767 DestroyWindow(window
);
13771 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
13772 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13773 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
13774 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13776 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
13777 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13778 state
= 0xdeadbeef;
13779 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
13780 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13781 ok(!state
, "Got unexpected render state %#lx.\n", state
);
13782 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
13783 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13784 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
13785 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13786 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#lx.\n", state
);
13788 refcount
= IDirect3DDevice2_Release(device
);
13789 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13790 refcount
= IDirectDraw2_Release(ddraw
);
13791 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13792 DestroyWindow(window
);
13795 static void test_depth_readback(void)
13797 unsigned int depth
, expected_depth
, i
, x
, y
, max_diff
, passed_fmts
= 0;
13798 IDirect3DMaterial2
*blue_background
;
13799 IDirectDrawSurface
*rt
, *ds
;
13800 IDirect3DViewport2
*viewport
;
13801 DDSURFACEDESC surface_desc
;
13802 IDirect3DDevice2
*device
;
13803 IDirectDraw2
*ddraw
;
13810 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
13811 static D3DLVERTEX quad
[] =
13813 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
13814 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
13815 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
13816 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
13819 static const struct
13821 unsigned int z_depth
, z_mask
;
13830 window
= create_window();
13831 ok(!!window
, "Failed to create a window.\n");
13832 ddraw
= create_ddraw();
13833 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13834 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13836 skip("Failed to create a D3D device, skipping tests.\n");
13837 IDirectDraw2_Release(ddraw
);
13838 DestroyWindow(window
);
13842 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13843 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13844 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13845 viewport
= create_viewport(device
, 0, 0, 640, 480);
13846 viewport_set_background(device
, viewport
, blue_background
);
13847 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13848 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13850 ds
= get_depth_stencil(device
);
13851 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13852 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
13853 IDirectDrawSurface_Release(ds
);
13855 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13857 memset(&surface_desc
, 0, sizeof(surface_desc
));
13858 surface_desc
.dwSize
= sizeof(surface_desc
);
13859 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
13860 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
13861 surface_desc
.dwZBufferBitDepth
= tests
[i
].z_depth
;
13862 surface_desc
.dwWidth
= 640;
13863 surface_desc
.dwHeight
= 480;
13864 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
13867 skip("Format %u not supported, skipping test.\n", i
);
13871 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
13872 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
13873 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
13874 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
13876 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
13877 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13878 hr
= IDirect3DDevice2_BeginScene(device
);
13879 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
13880 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
13881 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
13882 hr
= IDirect3DDevice2_EndScene(device
);
13883 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
13885 memset(&surface_desc
, 0, sizeof(surface_desc
));
13886 surface_desc
.dwSize
= sizeof(surface_desc
);
13887 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13888 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
13891 for (y
= 60; y
< 480; y
+= 120)
13893 for (x
= 80; x
< 640; x
+= 160)
13895 ptr
= (BYTE
*)surface_desc
.lpSurface
13896 + y
* surface_desc
.lPitch
13897 + x
* (tests
[i
].z_depth
== 16 ? 2 : 4);
13898 depth
= *((DWORD
*)ptr
) & tests
[i
].z_mask
;
13899 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
13900 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
13901 /* The ddraw2 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
13902 * except that we only have D16 (broken on geforce 9) and D24X8 (broken on geforce 7) available.
13903 * Accept all nvidia GPUs as broken here, but still expect one of the formats to pass. */
13904 ok(compare_uint(expected_depth
, depth
, max_diff
) || ddraw_is_nvidia(ddraw
)
13905 || (ddraw_is_amd(ddraw
) && tests
[i
].z_depth
== 24),
13906 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
13907 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
13908 if (!compare_uint(expected_depth
, depth
, max_diff
))
13913 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
13914 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13919 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
13920 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
13921 IDirectDrawSurface_Release(ds
);
13924 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
13926 destroy_viewport(device
, viewport
);
13927 destroy_material(blue_background
);
13928 IDirectDrawSurface_Release(rt
);
13929 refcount
= IDirect3DDevice2_Release(device
);
13930 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13931 IDirectDraw2_Release(ddraw
);
13932 DestroyWindow(window
);
13935 static void test_clear(void)
13937 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
13938 IDirect3DViewport2
*viewport
, *viewport2
, *viewport3
;
13939 IDirect3DMaterial2
*white
, *red
, *green
, *blue
;
13940 IDirect3DDevice2
*device
;
13941 IDirectDrawSurface
*rt
;
13942 IDirectDraw2
*ddraw
;
13943 unsigned int color
;
13949 window
= create_window();
13950 ddraw
= create_ddraw();
13951 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13952 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13954 skip("Failed to create a 3D device, skipping test.\n");
13955 IDirectDraw2_Release(ddraw
);
13956 DestroyWindow(window
);
13959 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
13960 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13962 viewport
= create_viewport(device
, 0, 0, 640, 480);
13963 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
13964 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
13966 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
13967 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13968 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
13969 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13971 viewport_set_background(device
, viewport
, white
);
13972 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13973 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13975 /* Positive x, negative y. */
13981 /* Positive x, positive y. */
13987 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
13988 * refuse negative rectangles, but it will not clear them either. */
13989 viewport_set_background(device
, viewport
, red
);
13990 hr
= IDirect3DViewport2_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
13991 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
13993 color
= get_surface_color(rt
, 160, 360);
13994 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
13995 color
= get_surface_color(rt
, 160, 120);
13996 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
13997 color
= get_surface_color(rt
, 480, 360);
13998 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
13999 color
= get_surface_color(rt
, 480, 120);
14000 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
14002 viewport_set_background(device
, viewport
, white
);
14003 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14004 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14006 /* negative x, negative y.
14007 * Also ignored, except on WARP, which clears the entire screen. */
14008 rect_negneg
.x1
= 640;
14009 rect_negneg
.y1
= 240;
14010 rect_negneg
.x2
= 320;
14011 rect_negneg
.y2
= 0;
14012 viewport_set_background(device
, viewport
, green
);
14013 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
14014 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14016 color
= get_surface_color(rt
, 160, 360);
14017 ok(compare_color(color
, 0x00ffffff, 0)
14018 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14019 "Got unexpected color 0x%08x.\n", color
);
14020 color
= get_surface_color(rt
, 160, 120);
14021 ok(compare_color(color
, 0x00ffffff, 0)
14022 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14023 "Got unexpected color 0x%08x.\n", color
);
14024 color
= get_surface_color(rt
, 480, 360);
14025 ok(compare_color(color
, 0x00ffffff, 0)
14026 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14027 "Got unexpected color 0x%08x.\n", color
);
14028 color
= get_surface_color(rt
, 480, 120);
14029 ok(compare_color(color
, 0x00ffffff, 0)
14030 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14031 "Got unexpected color 0x%08x.\n", color
);
14033 /* Test how the viewport affects clears. */
14034 viewport_set_background(device
, viewport
, white
);
14035 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14036 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14038 viewport2
= create_viewport(device
, 160, 120, 160, 120);
14039 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport2
);
14040 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
14042 viewport_set_background(device
, viewport2
, blue
);
14043 hr
= IDirect3DViewport2_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
14044 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14046 viewport3
= create_viewport(device
, 320, 240, 320, 240);
14047 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport3
);
14048 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
14054 viewport_set_background(device
, viewport3
, green
);
14055 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
14056 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14058 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14059 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
14061 color
= get_surface_color(rt
, 158, 118);
14062 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
14063 color
= get_surface_color(rt
, 162, 118);
14064 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
14065 color
= get_surface_color(rt
, 158, 122);
14066 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
14067 color
= get_surface_color(rt
, 162, 122);
14068 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
14070 color
= get_surface_color(rt
, 318, 238);
14071 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
14072 color
= get_surface_color(rt
, 322, 238);
14073 ok(compare_color(color
, 0x00ffffff, 0), "(322, 238) has color 0x%08x.\n", color
);
14074 color
= get_surface_color(rt
, 318, 242);
14075 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
14076 color
= get_surface_color(rt
, 322, 242);
14077 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
14079 color
= get_surface_color(rt
, 478, 358);
14080 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
14081 color
= get_surface_color(rt
, 482, 358);
14082 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
14083 color
= get_surface_color(rt
, 478, 362);
14084 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
14085 color
= get_surface_color(rt
, 482, 362);
14086 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
14088 /* The clear rectangle is rendertarget absolute, not relative to the
14090 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14091 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14096 hr
= IDirect3DViewport2_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
14097 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
14099 color
= get_surface_color(rt
, 328, 248);
14100 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
14101 color
= get_surface_color(rt
, 332, 248);
14102 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
14103 color
= get_surface_color(rt
, 328, 252);
14104 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
14105 color
= get_surface_color(rt
, 332, 252);
14106 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
14108 color
= get_surface_color(rt
, 338, 248);
14109 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
14110 color
= get_surface_color(rt
, 342, 248);
14111 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
14112 color
= get_surface_color(rt
, 338, 252);
14113 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
14114 color
= get_surface_color(rt
, 342, 252);
14115 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
14117 color
= get_surface_color(rt
, 328, 258);
14118 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
14119 color
= get_surface_color(rt
, 332, 258);
14120 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
14121 color
= get_surface_color(rt
, 328, 262);
14122 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
14123 color
= get_surface_color(rt
, 332, 262);
14124 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
14126 color
= get_surface_color(rt
, 338, 258);
14127 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
14128 color
= get_surface_color(rt
, 342, 258);
14129 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
14130 color
= get_surface_color(rt
, 338, 262);
14131 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
14132 color
= get_surface_color(rt
, 342, 262);
14133 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
14135 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
14138 IDirect3DViewport2_Release(viewport3
);
14139 IDirect3DViewport2_Release(viewport2
);
14140 IDirect3DViewport2_Release(viewport
);
14141 IDirect3DMaterial2_Release(white
);
14142 IDirect3DMaterial2_Release(red
);
14143 IDirect3DMaterial2_Release(green
);
14144 IDirect3DMaterial2_Release(blue
);
14145 IDirectDrawSurface_Release(rt
);
14146 refcount
= IDirect3DDevice2_Release(device
);
14147 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14148 refcount
= IDirectDraw2_Release(ddraw
);
14149 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
14150 DestroyWindow(window
);
14153 struct enum_surfaces_param
14155 IDirectDraw2
*ddraw
;
14156 DDSURFACEDESC modes
[20];
14157 unsigned int mode_count
;
14159 IDirectDrawSurface
*surfaces
[8];
14160 unsigned int count
;
14163 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC
*desc
, void *context
)
14165 struct enum_surfaces_param
*param
= context
;
14166 IDirectDrawSurface
*surface
;
14168 if (SUCCEEDED(IDirectDraw2_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
14170 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
14171 param
->modes
[param
->mode_count
] = *desc
;
14172 ++param
->mode_count
;
14173 IDirectDrawSurface_Release(surface
);
14176 return DDENUMRET_OK
;
14179 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
14181 struct enum_surfaces_param
*param
= context
;
14182 BOOL found
= FALSE
;
14185 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
14187 if (param
->surfaces
[i
] == surface
)
14194 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
14195 IDirectDrawSurface_Release(surface
);
14198 return DDENUMRET_OK
;
14201 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
14203 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
14204 struct enum_surfaces_param
*param
= context
;
14206 ok(!surface
, "Unexpected surface %p.\n", surface
);
14207 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#lx.\n", desc
->dwFlags
);
14208 if (param
->count
< ARRAY_SIZE(param
->modes
))
14210 const DDSURFACEDESC
*expect
= ¶m
->modes
[param
->count
];
14211 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %lu, got %lu.\n", expect
->dwWidth
, desc
->dwWidth
);
14212 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %lu, got %lu.\n", expect
->dwHeight
, desc
->dwHeight
);
14213 ok(!memcmp(&desc
->ddpfPixelFormat
, &expect
->ddpfPixelFormat
, sizeof(desc
->ddpfPixelFormat
)),
14214 "Pixel formats didn't match.\n");
14219 return DDENUMRET_OK
;
14222 static void test_enum_surfaces(void)
14224 struct enum_surfaces_param param
= {0};
14225 DDPIXELFORMAT current_format
;
14226 IDirectDraw2
*ddraw
;
14227 DDSURFACEDESC desc
;
14230 ddraw
= create_ddraw();
14231 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14232 param
.ddraw
= ddraw
;
14234 memset(&desc
, 0, sizeof(desc
));
14235 desc
.dwSize
= sizeof(desc
);
14236 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &desc
);
14237 ok(hr
== DD_OK
, "Failed to get display mode, hr %#lx.\n", hr
);
14238 current_format
= desc
.ddpfPixelFormat
;
14240 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
14241 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#lx.\n", hr
);
14243 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
14244 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14246 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
14247 NULL
, NULL
, enum_surfaces_cb
);
14248 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14250 memset(&desc
, 0, sizeof(desc
));
14251 desc
.dwSize
= sizeof(desc
);
14252 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
14253 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
14254 desc
.dwMipMapCount
= 3;
14256 desc
.dwHeight
= 32;
14257 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
14258 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
14260 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
14261 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
14262 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
14263 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
14264 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
14265 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14266 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
14269 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14270 &desc
, ¶m
, enum_surfaces_cb
);
14271 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14272 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14275 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14276 NULL
, ¶m
, enum_surfaces_cb
);
14277 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14278 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14280 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
14282 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14283 &desc
, ¶m
, enum_surfaces_cb
);
14284 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14285 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14288 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
14289 &desc
, ¶m
, enum_surfaces_cb
);
14290 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14291 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14295 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14296 &desc
, ¶m
, enum_surfaces_cb
);
14297 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14298 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14302 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
14303 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14304 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14306 IDirectDrawSurface_Release(param
.surfaces
[2]);
14307 IDirectDrawSurface_Release(param
.surfaces
[1]);
14308 IDirectDrawSurface_Release(param
.surfaces
[0]);
14311 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14312 NULL
, ¶m
, enum_surfaces_cb
);
14313 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14314 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14316 memset(&desc
, 0, sizeof(desc
));
14317 desc
.dwSize
= sizeof(desc
);
14318 desc
.dwFlags
= DDSD_CAPS
;
14319 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
14321 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
14322 &desc
, ¶m
, enum_surfaces_create_cb
);
14323 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14325 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
14326 &desc
, ¶m
, enum_surfaces_create_cb
);
14327 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14329 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
14330 &desc
, ¶m
, enum_surfaces_create_cb
);
14331 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14333 /* When not passed width and height, the callback is called with every
14334 * available display resolution. */
14336 param
.mode_count
= 0;
14337 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
14338 desc
.ddpfPixelFormat
= current_format
;
14339 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
14340 ok(hr
== DD_OK
, "Failed to build mode list, hr %#lx.\n", hr
);
14343 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
14344 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14345 &desc
, ¶m
, enum_surfaces_create_cb
);
14346 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14347 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
14349 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
14350 desc
.dwWidth
= desc
.dwHeight
= 32;
14352 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
14355 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14356 &desc
, ¶m
, enum_surfaces_create_cb
);
14357 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14358 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14360 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
14361 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
14363 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
14364 &desc
, ¶m
, enum_surfaces_create_cb
);
14365 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14366 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14367 IDirectDrawSurface2_Release(param
.surfaces
[0]);
14369 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
14370 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
14371 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
14372 desc
.ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
14375 hr
= IDirectDraw2_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
14376 &desc
, ¶m
, enum_surfaces_create_cb
);
14377 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
14378 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14380 IDirectDraw2_Release(ddraw
);
14383 static void test_viewport(void)
14388 RECT expected_rect
;
14389 const char *message
;
14393 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
14394 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
14395 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
14396 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
14397 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
14398 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
14400 static const struct
14406 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
14408 static D3DMATRIX mat
=
14410 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14411 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14412 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14413 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14415 static D3DLVERTEX quad
[] =
14417 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14418 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14419 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
14420 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
14422 IDirect3DViewport2
*viewport
, *full_viewport
;
14423 IDirect3DMaterial2
*black_background
;
14424 IDirectDrawSurface
*rt
, *ds
;
14425 DDSURFACEDESC surface_desc
;
14426 IDirect3DDevice2
*device
;
14427 BOOL expected_failure
;
14428 IDirectDraw2
*ddraw
;
14429 DDPIXELFORMAT z_fmt
;
14430 D3DRECT clear_rect
;
14438 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14439 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
14440 ddraw
= create_ddraw();
14441 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14442 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14444 skip("Failed to create a 3D device, skipping test.\n");
14445 IDirectDraw2_Release(ddraw
);
14446 DestroyWindow(window
);
14450 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
14451 ok(SUCCEEDED(hr
), "Failed to get Direct3D2 interface, hr %#lx.\n", hr
);
14453 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
14454 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#lx.\n", hr
);
14455 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
14456 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
14458 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
14459 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14460 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
14461 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
14462 hr
= IDirect3DDevice2_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
14463 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
14465 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
14467 ds
= get_depth_stencil(device
);
14468 memset(&surface_desc
, 0, sizeof(surface_desc
));
14469 surface_desc
.dwSize
= sizeof(surface_desc
);
14470 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &surface_desc
);
14471 z_fmt
= surface_desc
.ddpfPixelFormat
;
14473 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
14475 winetest_push_context("Size %ux%u", rt_sizes
[i
].x
, rt_sizes
[i
].y
);
14479 memset(&surface_desc
, 0, sizeof(surface_desc
));
14480 surface_desc
.dwSize
= sizeof(surface_desc
);
14481 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14482 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
14483 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
14484 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
14485 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
14486 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14488 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
14489 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14490 surface_desc
.ddpfPixelFormat
= z_fmt
;
14491 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
14492 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14493 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
14494 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14496 hr
= IDirect3DDevice2_SetRenderTarget(device
, rt
, 0);
14497 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14501 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14502 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14505 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
14506 viewport_set_background(device
, full_viewport
, black_background
);
14508 clear_rect
.x1
= clear_rect
.y1
= 0;
14509 clear_rect
.x2
= rt_sizes
[i
].x
;
14510 clear_rect
.y2
= rt_sizes
[i
].y
;
14512 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
14514 winetest_push_context("%s", tests
[j
].message
);
14516 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
14517 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
14519 hr
= IDirect3DViewport2_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
14520 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14522 hr
= IDirect3D2_CreateViewport(d3d
, &viewport
, NULL
);
14523 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14524 hr
= IDirect3DViewport2_SetViewport2(viewport
, NULL
);
14525 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
14526 memset(&vp
, 0, sizeof(vp
));
14527 vp
.dwSize
= sizeof(vp
);
14528 vp
.dwX
= tests
[j
].vp
.dwX
;
14529 vp
.dwY
= tests
[j
].vp
.dwY
;
14530 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
14531 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
14532 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
14533 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
14536 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14537 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
14538 hr
= IDirect3DDevice2_AddViewport(device
, viewport
);
14539 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14540 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp
);
14541 ok(hr
== (expected_failure
? E_INVALIDARG
: DD_OK
), "Got unexpected hr %#lx.\n", hr
);
14543 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14544 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14545 if (expected_failure
)
14547 destroy_viewport(device
, viewport
);
14548 winetest_pop_context();
14552 hr
= IDirect3DDevice2_BeginScene(device
);
14553 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14554 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, 4, 0);
14555 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14556 hr
= IDirect3DDevice2_EndScene(device
);
14557 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14559 check_rect(rt
, tests
[j
].expected_rect
);
14561 destroy_viewport(device
, viewport
);
14562 winetest_pop_context();
14565 destroy_viewport(device
, full_viewport
);
14567 hr
= IDirectDrawSurface_DeleteAttachedSurface(rt
, 0, ds
);
14568 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx (i %u).\n", hr
, i
);
14569 IDirectDrawSurface_Release(ds
);
14571 IDirectDrawSurface_Release(rt
);
14573 winetest_pop_context();
14576 destroy_material(black_background
);
14577 refcount
= IDirect3DDevice2_Release(device
);
14578 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14579 IDirect3D2_Release(d3d
);
14580 IDirectDraw2_Release(ddraw
);
14581 DestroyWindow(window
);
14584 static void test_find_device(void)
14586 D3DFINDDEVICESEARCH search
= {0};
14587 D3DFINDDEVICERESULT result
= {0};
14588 IDirect3DDevice2
*device
;
14589 IDirectDraw2
*ddraw
;
14599 D3DDEVICEDESC_V1 hw_desc
;
14600 D3DDEVICEDESC_V1 sw_desc
;
14607 D3DDEVICEDESC_V2 hw_desc
;
14608 D3DDEVICEDESC_V2 sw_desc
;
14611 static const struct
14618 {&IID_IDirect3D
, DDERR_NOTFOUND
},
14619 {&IID_IDirect3DRampDevice
, D3D_OK
},
14620 {&IID_IDirect3DRGBDevice
, D3D_OK
},
14621 {&IID_IDirect3DMMXDevice
, D3D_OK
},
14622 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
14623 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
14624 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
14627 ddraw
= create_ddraw();
14628 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14630 if (FAILED(IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
)))
14632 skip("D3D interface is not available, skipping test.\n");
14633 IDirectDraw2_Release(ddraw
);
14637 result
.dwSize
= sizeof(result
);
14638 search
.dwSize
= sizeof(search
);
14639 hr
= IDirect3D2_FindDevice(d3d
, NULL
, NULL
);
14640 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14641 hr
= IDirect3D2_FindDevice(d3d
, NULL
, &result
);
14642 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14643 hr
= IDirect3D2_FindDevice(d3d
, &search
, NULL
);
14644 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14645 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14646 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14647 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %lu.\n", result
.dwSize
);
14648 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14649 "Got unexpected HW desc size %lu.\n", result
.ddHwDesc
.dwSize
);
14650 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14651 "Got unexpected SW desc size %lu.\n", result
.ddSwDesc
.dwSize
);
14653 memset(&search
, 0, sizeof(search
));
14654 memset(&result
, 0, sizeof(result
));
14655 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14656 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14658 search
.dwSize
= sizeof(search
) + 1;
14659 result
.dwSize
= sizeof(result
) + 1;
14660 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14661 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14663 search
.dwSize
= sizeof(search
);
14665 memset(&result_v1
, 0, sizeof(result_v1
));
14666 result_v1
.size
= sizeof(result_v1
);
14667 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
14668 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14669 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14670 "Got unexpected HW desc size %lu.\n", result_v1
.hw_desc
.dwSize
);
14671 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14672 "Got unexpected SW desc size %lu.\n", result_v1
.sw_desc
.dwSize
);
14674 memset(&result_v2
, 0, sizeof(result_v2
));
14675 result_v2
.size
= sizeof(result_v2
);
14676 hr
= IDirect3D2_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
14677 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14678 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v2
.hw_desc
),
14679 "Got unexpected HW desc size %lu.\n", result_v2
.hw_desc
.dwSize
);
14680 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v2
.sw_desc
),
14681 "Got unexpected SW desc size %lu.\n", result_v2
.sw_desc
.dwSize
);
14683 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14685 memset(&search
, 0, sizeof(search
));
14686 search
.dwSize
= sizeof(search
);
14687 search
.dwFlags
= D3DFDS_GUID
;
14688 search
.guid
= *tests
[i
].guid
;
14690 memset(&result
, 0, sizeof(result
));
14691 result
.dwSize
= sizeof(result
);
14693 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14694 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
14695 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %lu.\n", i
, result
.dwSize
);
14698 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v2
.hw_desc
),
14699 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
14700 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v2
.sw_desc
),
14701 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
14705 ok(!result
.ddHwDesc
.dwSize
,
14706 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
14707 ok(!result
.ddSwDesc
.dwSize
,
14708 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
14712 /* The HAL device can only be enumerated if hardware acceleration is present. */
14713 search
.dwSize
= sizeof(search
);
14714 search
.dwFlags
= D3DFDS_GUID
;
14715 search
.guid
= IID_IDirect3DHALDevice
;
14716 result
.dwSize
= sizeof(result
);
14717 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14719 window
= create_window();
14720 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
14722 ok(!!device
, "Failed to create a 3D device.\n");
14724 ok(!device
, "Succeeded to create a 3D device.\n");
14726 IDirect3DDevice2_Release(device
);
14727 DestroyWindow(window
);
14729 /* Curiously the colour model criteria seem to be ignored. */
14730 search
.dwSize
= sizeof(search
);
14731 search
.dwFlags
= D3DFDS_COLORMODEL
;
14732 search
.dcmColorModel
= 0xdeadbeef;
14733 result
.dwSize
= sizeof(result
);
14734 hr
= IDirect3D2_FindDevice(d3d
, &search
, &result
);
14735 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14737 IDirect3D2_Release(d3d
);
14738 IDirectDraw2_Release(ddraw
);
14741 static IDirectDraw2
*killfocus_ddraw
;
14742 static IDirectDrawSurface
*killfocus_surface
;
14744 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
14748 if (message
== WM_KILLFOCUS
)
14750 ref
= IDirectDrawSurface_Release(killfocus_surface
);
14751 ok(!ref
, "Unexpected surface refcount %lu.\n", ref
);
14752 ref
= IDirectDraw2_Release(killfocus_ddraw
);
14753 ok(!ref
, "Unexpected ddraw refcount %lu.\n", ref
);
14754 killfocus_ddraw
= NULL
;
14757 return DefWindowProcA(window
, message
, wparam
, lparam
);
14760 static void test_killfocus(void)
14762 DDSURFACEDESC surface_desc
;
14765 WNDCLASSA wc
= {0};
14767 wc
.lpfnWndProc
= killfocus_proc
;
14768 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
14769 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
14771 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
14772 0, 0, 640, 480, 0, 0, 0, 0);
14774 killfocus_ddraw
= create_ddraw();
14775 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
14777 hr
= IDirectDraw2_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
14778 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
14780 memset(&surface_desc
, 0, sizeof(surface_desc
));
14781 surface_desc
.dwSize
= sizeof(surface_desc
);
14782 surface_desc
.dwFlags
= DDSD_CAPS
;
14783 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14784 hr
= IDirectDraw2_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
14785 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
14787 SetForegroundWindow(GetDesktopWindow());
14788 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
14790 DestroyWindow(window
);
14791 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
14794 static void test_gdi_surface(void)
14796 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
14797 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
14798 DDSURFACEDESC surface_desc
;
14799 IDirectDraw2
*ddraw
;
14804 window
= create_window();
14805 ddraw
= create_ddraw();
14806 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14807 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14808 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14810 /* Retrieving the GDI surface requires a primary surface to exist. */
14811 gdi_surface
= (void *)0xc0dec0de;
14812 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14813 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14814 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
14816 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14817 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
14819 memset(&surface_desc
, 0, sizeof(surface_desc
));
14820 surface_desc
.dwSize
= sizeof(surface_desc
);
14821 surface_desc
.dwFlags
= DDSD_CAPS
;
14822 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14823 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14824 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14826 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14827 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14828 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14829 IDirectDrawSurface_Release(gdi_surface
);
14831 /* Flipping to the GDI surface requires the primary surface to be
14833 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14834 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#lx.\n", hr
);
14836 IDirectDrawSurface_Release(primary
);
14838 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14839 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14841 memset(&surface_desc
, 0, sizeof(surface_desc
));
14842 surface_desc
.dwSize
= sizeof(surface_desc
);
14843 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14844 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
14845 surface_desc
.dwBackBufferCount
= 1;
14846 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
14847 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14848 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
14849 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14850 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
14852 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14853 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14854 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14855 IDirectDrawSurface_Release(gdi_surface
);
14857 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
14858 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14859 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14860 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14861 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
14862 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
14863 IDirectDrawSurface_Release(gdi_surface
);
14865 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14866 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14868 hr
= IDirectDraw2_GetGDISurface(ddraw
, &gdi_surface
);
14869 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14870 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
14871 IDirectDrawSurface_Release(gdi_surface
);
14873 hr
= IDirectDraw2_FlipToGDISurface(ddraw
);
14874 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14876 IDirectDrawSurface_Release(backbuffer
);
14877 IDirectDrawSurface_Release(primary
);
14879 refcount
= IDirectDraw2_Release(ddraw
);
14880 ok(!refcount
, "%lu references left.\n", refcount
);
14881 DestroyWindow(window
);
14884 static void test_alphatest(void)
14886 #define ALPHATEST_PASSED 0x0000ff00
14887 #define ALPHATEST_FAILED 0x00ff0000
14888 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
14889 IDirect3DMaterial2
*blue
, *failed
;
14890 IDirect3DViewport2
*viewport
;
14891 IDirect3DDevice2
*device
;
14892 IDirectDrawSurface
*rt
;
14893 unsigned int color
, i
;
14894 IDirectDraw2
*ddraw
;
14900 static const struct
14903 unsigned int color_less
, color_equal
, color_greater
;
14907 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14908 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
14909 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14910 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
14911 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14912 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
14913 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14914 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
14916 static D3DLVERTEX quad
[] =
14918 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14919 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14920 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14921 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
14924 window
= create_window();
14925 ddraw
= create_ddraw();
14926 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14927 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
14929 skip("Failed to create a 3D device.\n");
14930 IDirectDraw2_Release(ddraw
);
14931 DestroyWindow(window
);
14934 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
14935 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14937 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
14938 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
14940 viewport
= create_viewport(device
, 0, 0, 640, 480);
14941 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
14942 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14944 viewport_set_background(device
, viewport
, blue
);
14945 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14946 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14947 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14948 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14949 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
14950 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14951 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
14952 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14954 viewport_set_background(device
, viewport
, failed
);
14955 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
14957 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
14958 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14960 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14961 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14962 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
14963 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14964 hr
= IDirect3DDevice2_BeginScene(device
);
14965 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14966 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14967 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14968 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14969 hr
= IDirect3DDevice2_EndScene(device
);
14970 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14971 color
= get_surface_color(rt
, 320, 240);
14972 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14973 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14974 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14976 hr
= IDirect3DViewport2_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
14977 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14978 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
14979 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14980 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
14981 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14982 ok(value
== 0xff70, "Got unexpected value %#lx.\n", value
);
14983 hr
= IDirect3DDevice2_BeginScene(device
);
14984 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14985 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
14986 D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
14987 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14988 hr
= IDirect3DDevice2_EndScene(device
);
14989 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14990 color
= get_surface_color(rt
, 320, 240);
14991 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
14992 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14993 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
14996 destroy_viewport(device
, viewport
);
14997 destroy_material(failed
);
14998 destroy_material(blue
);
14999 IDirectDrawSurface_Release(rt
);
15000 refcount
= IDirect3DDevice2_Release(device
);
15001 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15002 refcount
= IDirectDraw2_Release(ddraw
);
15003 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
15004 DestroyWindow(window
);
15007 static void test_clipper_refcount(void)
15009 IDirectDrawSurface
*surface
;
15010 IDirectDrawClipper
*clipper
, *clipper2
;
15011 DDSURFACEDESC surface_desc
;
15012 IDirectDraw2
*ddraw
;
15013 IDirectDraw
*ddraw1
;
15018 const IDirectDrawClipperVtbl
*orig_vtbl
;
15020 window
= create_window();
15021 ddraw
= create_ddraw();
15022 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15023 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15024 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15026 memset(&surface_desc
, 0, sizeof(surface_desc
));
15027 surface_desc
.dwSize
= sizeof(surface_desc
);
15028 surface_desc
.dwFlags
= DDSD_CAPS
;
15029 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
15030 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15031 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15033 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
15034 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
15035 refcount
= get_refcount((IUnknown
*)clipper
);
15036 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15038 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
15040 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
15041 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
15042 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
15043 clipper
->lpVtbl
, clipper2
->lpVtbl
);
15044 orig_vtbl
= clipper
->lpVtbl
;
15045 IDirectDrawClipper_Release(clipper2
);
15047 /* Surfaces hold a reference to clippers. No surprises there. */
15048 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
15049 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
15050 refcount
= get_refcount((IUnknown
*)clipper
);
15051 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
15053 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
15054 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
15055 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
15056 refcount
= IDirectDrawClipper_Release(clipper2
);
15057 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
15059 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
15060 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
15061 refcount
= get_refcount((IUnknown
*)clipper
);
15062 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15064 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
15065 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
15066 refcount
= get_refcount((IUnknown
*)clipper
);
15067 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
15069 refcount
= IDirectDrawSurface_Release(surface
);
15070 ok(!refcount
, "%lu references left.\n", refcount
);
15071 refcount
= get_refcount((IUnknown
*)clipper
);
15072 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15074 /* SetClipper with an invalid pointer crashes. */
15076 /* Clipper methods work with a broken vtable, with the exception of Release. */
15077 clipper
->lpVtbl
= (void *)0xdeadbeef;
15078 refcount
= orig_vtbl
->AddRef(clipper
);
15079 todo_wine
ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
15080 refcount
= orig_vtbl
->Release(clipper
);
15081 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
15083 clipper
->lpVtbl
= orig_vtbl
;
15084 refcount
= orig_vtbl
->Release(clipper
);
15085 todo_wine
ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15087 /* Fix the refcount difference because Wine did not increase the ref in the
15088 * AddRef call above. */
15091 refcount
= IDirectDrawClipper_Release(clipper
);
15092 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
15095 /* Steal the reference and see what happens - releasing the surface works fine.
15096 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
15097 * release it after the GetClipper call is likely to crash, and certain to crash
15098 * if we allocate and zero as much heap memory as we can get. */
15099 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15100 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15101 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
15102 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
15103 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
15104 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
15106 IDirectDrawClipper_Release(clipper
);
15107 IDirectDrawClipper_Release(clipper
);
15111 /* Disabled because it causes heap corruption (HeapValidate fails and random
15112 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
15113 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
15114 * is affected too. Some testbot machines have crashes directly in GetClipper
15115 * or proceed with a corrupted heap too.
15117 * The same Windows and driver versions run the test without heap corruption on
15118 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
15119 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
15120 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
15121 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
15124 /* Show that invoking the Release method does not crash, but don't get the
15125 * vtable through the clipper pointer because it is no longer pointing to
15127 refcount
= orig_vtbl
->Release(clipper
);
15128 ok(!refcount
, "%lu references left.\n", refcount
);
15130 refcount
= IDirectDrawSurface_Release(surface
);
15131 ok(!refcount
, "%lu references left.\n", refcount
);
15133 /* It looks like the protection against invalid thispointers is part of
15134 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
15135 clipper
= calloc(1, 0x1000);
15136 ok(!!clipper
, "failed to allocate memory\n");
15138 /* Assigning the vtable to our fake clipper does NOT make a difference on
15139 * native - there is a different member of the clipper implementation struct
15140 * that is used to determine if a clipper is valid. */
15141 clipper
->lpVtbl
= orig_vtbl
;
15143 refcount
= orig_vtbl
->AddRef(clipper
);
15144 todo_wine
ok(!refcount
, "Got refcount %lu.\n", refcount
);
15145 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
15146 ok(!refcount
, "Got refcount %lu.\n", refcount
);
15149 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
15150 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15151 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
15154 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
15155 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15156 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
15158 /* Nope, we can't initialize our fake clipper. */
15159 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
15160 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#lx.\n", hr
);
15162 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
15163 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15165 IDirectDraw_Release(ddraw1
);
15169 refcount
= IDirectDraw2_Release(ddraw
);
15170 ok(!refcount
, "%lu references left.\n", refcount
);
15171 DestroyWindow(window
);
15174 static void test_caps(void)
15176 DWORD caps_never
, caps_always
, caps_hal
;
15177 DDCAPS hal_caps
, hel_caps
;
15178 IDirectDraw2
*ddraw
;
15179 IDirectDraw
*ddraw1
;
15183 caps_never
= DDSCAPS_RESERVED1
15185 | DDSCAPS_PRIMARYSURFACELEFT
15186 | DDSCAPS_SYSTEMMEMORY
15188 | DDSCAPS_WRITEONLY
15189 | DDSCAPS_LIVEVIDEO
15192 | DDSCAPS_RESERVED2
15195 | DDSCAPS_ALLOCONLOAD
15196 | DDSCAPS_VIDEOPORT
15197 | DDSCAPS_STANDARDVGAMODE
15198 | DDSCAPS_OPTIMIZED
;
15200 caps_always
= DDSCAPS_FLIP
15201 | DDSCAPS_OFFSCREENPLAIN
15202 | DDSCAPS_PRIMARYSURFACE
15207 caps_hal
= DDSCAPS_BACKBUFFER
15209 | DDSCAPS_FRONTBUFFER
15211 | DDSCAPS_VIDEOMEMORY
15212 | DDSCAPS_LOCALVIDMEM
15213 | DDSCAPS_NONLOCALVIDMEM
;
15215 ddraw
= create_ddraw();
15216 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15218 memset(&hal_caps
, 0, sizeof(hal_caps
));
15219 memset(&hel_caps
, 0, sizeof(hel_caps
));
15220 hal_caps
.dwSize
= sizeof(hal_caps
);
15221 hel_caps
.dwSize
= sizeof(hel_caps
);
15222 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15223 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15224 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15225 "Got unexpected caps %#lx, expected %#lx.\n",
15226 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15227 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15228 "Got unexpected caps %#lx, expected %#lx.\n",
15229 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15231 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
15232 if (hal_caps
.ddsCaps
.dwCaps
)
15234 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15235 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15236 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
15237 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15239 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15240 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15241 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15242 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15244 IDirectDraw2_Release(ddraw
);
15246 if (hal_caps
.ddsCaps
.dwCaps
)
15248 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw1
, NULL
);
15249 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15250 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
15251 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15252 IDirectDraw_Release(ddraw1
);
15254 memset(&hal_caps
, 0, sizeof(hal_caps
));
15255 memset(&hel_caps
, 0, sizeof(hel_caps
));
15256 hal_caps
.dwSize
= sizeof(hal_caps
);
15257 hel_caps
.dwSize
= sizeof(hel_caps
);
15258 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15259 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15260 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15261 "Got unexpected caps %#lx, expected %#lx.\n",
15262 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15263 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15264 "Got unexpected caps %#lx, expected %#lx.\n",
15265 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15267 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15268 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15269 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
15270 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15273 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15274 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15275 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15276 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15280 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15283 IDirectDraw2_Release(ddraw
);
15286 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw1
, NULL
);
15287 ok(hr
== DD_OK
|| (is_ddraw64
&& hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
15290 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw
);
15291 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15292 IDirectDraw_Release(ddraw1
);
15294 memset(&hal_caps
, 0, sizeof(hal_caps
));
15295 memset(&hel_caps
, 0, sizeof(hel_caps
));
15296 hal_caps
.dwSize
= sizeof(hal_caps
);
15297 hel_caps
.dwSize
= sizeof(hel_caps
);
15298 hr
= IDirectDraw2_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
15299 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15300 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
15301 "Got unexpected caps %#lx, expected %#lx.\n",
15302 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
15303 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
15304 "Got unexpected caps %#lx, expected %#lx.\n",
15305 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
15307 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
15308 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15309 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15310 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
15311 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
15313 IDirectDraw2_Release(ddraw
);
15317 static void test_d32_support(void)
15319 IDirectDrawSurface
*surface
;
15320 DDSURFACEDESC surface_desc
;
15321 IDirectDraw2
*ddraw
;
15326 window
= create_window();
15327 ddraw
= create_ddraw();
15328 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15329 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15330 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15332 memset(&surface_desc
, 0, sizeof(surface_desc
));
15333 surface_desc
.dwSize
= sizeof(surface_desc
);
15334 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
15335 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
15336 surface_desc
.dwZBufferBitDepth
= 32;
15337 surface_desc
.dwWidth
= 64;
15338 surface_desc
.dwHeight
= 64;
15339 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15340 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15342 memset(&surface_desc
, 0, sizeof(surface_desc
));
15343 surface_desc
.dwSize
= sizeof(surface_desc
);
15344 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
15345 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15346 ok((surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "Got unexpected flags %#lx.\n", surface_desc
.dwFlags
);
15347 ok(surface_desc
.dwZBufferBitDepth
== 32,
15348 "Got unexpected dwZBufferBitDepth %lu.\n", surface_desc
.dwZBufferBitDepth
);
15349 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
15350 "Got unexpected surface caps %#lx.\n", surface_desc
.ddsCaps
.dwCaps
);
15351 IDirectDrawSurface_Release(surface
);
15353 refcount
= IDirectDraw2_Release(ddraw
);
15354 ok(!refcount
, "%lu references left.\n", refcount
);
15355 DestroyWindow(window
);
15358 struct find_different_mode_param
15360 unsigned int old_width
;
15361 unsigned int old_height
;
15362 unsigned int old_frequency
;
15363 unsigned int new_width
;
15364 unsigned int new_height
;
15365 unsigned int new_frequency
;
15366 unsigned int new_bpp
;
15369 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC
*surface_desc
, void *context
)
15371 struct find_different_mode_param
*param
= context
;
15373 if (surface_desc
->ddpfPixelFormat
.dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
15374 return DDENUMRET_OK
;
15376 /* See comment in ddraw7 about the frequency. */
15377 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
15378 (!compare_uint(surface_desc
->dwRefreshRate
, param
->old_frequency
, 1) || !param
->old_frequency
))
15380 /* See test_coop_level_mode_set_enum_cb() for why enumeration might accidentally continue. */
15381 if (!param
->new_width
|| (param
->new_width
< registry_mode
.dmPelsWidth
15382 && param
->new_height
< registry_mode
.dmPelsHeight
))
15384 param
->new_width
= surface_desc
->dwWidth
;
15385 param
->new_height
= surface_desc
->dwHeight
;
15386 param
->new_frequency
= surface_desc
->dwRefreshRate
;
15387 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
15389 return DDENUMRET_CANCEL
;
15392 return DDENUMRET_OK
;
15395 static void test_cursor_clipping(void)
15397 struct find_different_mode_param param
;
15398 DDSURFACEDESC surface_desc
;
15399 RECT rect
, clip_rect
;
15400 IDirectDraw2
*ddraw
;
15405 window
= create_window();
15406 ok(!!window
, "Failed to create a window.\n");
15407 ddraw
= create_ddraw();
15408 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15410 memset(&surface_desc
, 0, sizeof(surface_desc
));
15411 surface_desc
.dwSize
= sizeof(surface_desc
);
15412 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15413 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15415 memset(¶m
, 0, sizeof(param
));
15416 param
.old_width
= surface_desc
.dwWidth
;
15417 param
.old_height
= surface_desc
.dwHeight
;
15418 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
15419 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
15420 if (!(param
.new_width
&& param
.new_height
))
15422 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
15426 ret
= ClipCursor(NULL
);
15427 ok(ret
, "ClipCursor failed, error %lu.\n", GetLastError());
15428 get_virtual_rect(&rect
);
15429 ret
= GetClipCursor(&clip_rect
);
15430 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15431 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15432 wine_dbgstr_rect(&clip_rect
));
15434 /* Set cooperative level to normal */
15435 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15436 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15438 get_virtual_rect(&rect
);
15439 ret
= GetClipCursor(&clip_rect
);
15440 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15441 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15442 wine_dbgstr_rect(&clip_rect
));
15444 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15445 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15448 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
15452 get_virtual_rect(&rect
);
15453 ret
= GetClipCursor(&clip_rect
);
15454 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15455 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15456 wine_dbgstr_rect(&clip_rect
));
15458 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15459 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
15461 get_virtual_rect(&rect
);
15462 ret
= GetClipCursor(&clip_rect
);
15463 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15464 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15465 wine_dbgstr_rect(&clip_rect
));
15467 /* Switch to full screen cooperative level */
15468 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15469 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15471 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15472 ret
= GetClipCursor(&clip_rect
);
15473 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15474 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15475 wine_dbgstr_rect(&clip_rect
));
15477 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
15478 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15481 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
15485 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
15486 ret
= GetClipCursor(&clip_rect
);
15487 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15488 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15489 wine_dbgstr_rect(&clip_rect
));
15491 /* Restore display mode */
15492 hr
= IDirectDraw2_RestoreDisplayMode(ddraw
);
15493 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
15495 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
15496 ret
= GetClipCursor(&clip_rect
);
15497 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15498 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15499 wine_dbgstr_rect(&clip_rect
));
15501 /* Switch to normal cooperative level */
15502 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15503 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15505 get_virtual_rect(&rect
);
15506 ret
= GetClipCursor(&clip_rect
);
15507 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
15508 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
15509 wine_dbgstr_rect(&clip_rect
));
15512 IDirectDraw2_Release(ddraw
);
15513 DestroyWindow(window
);
15516 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15519 RECT primary_rect
, window_rect
, new_rect
;
15520 IDirectDraw2
*ddraw
;
15525 ddraw
= create_ddraw();
15526 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15527 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
15528 monitor_rect
->top
, 100, 100, NULL
, NULL
, NULL
, NULL
);
15529 ok(!!window
, "Failed to create a window.\n");
15532 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15533 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15535 ret
= GetWindowRect(window
, &window_rect
);
15536 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15537 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
15538 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15539 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15541 new_rect
= window_rect
;
15545 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
15546 new_rect
.bottom
- new_rect
.top
, TRUE
);
15547 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15548 ret
= GetWindowRect(window
, &window_rect
);
15549 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15550 ok(EqualRect(&window_rect
, &new_rect
),
15551 "Expected window rect %s, got %s.\n",
15552 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15553 /* After processing window events window rectangle gets restored. But only once, the size set
15554 * on the second resize remains. */
15556 ret
= GetWindowRect(window
, &window_rect
);
15557 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15558 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
15559 * it may get adjusted depending on window manager. */
15560 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
15561 "Expected window rect %s, got %s.\n",
15562 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15564 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
15565 new_rect
.bottom
- new_rect
.top
, TRUE
);
15566 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15567 ret
= GetWindowRect(window
, &window_rect
);
15568 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15569 ok(EqualRect(&window_rect
, &new_rect
),
15570 "Expected window rect %s, got %s.\n",
15571 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15573 ret
= GetWindowRect(window
, &window_rect
);
15574 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
15575 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
15576 "Expected window rect %s, got %s.\n",
15577 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
15579 /* Window activation should restore the window to fit the whole primary monitor */
15580 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15581 SWP_NOZORDER
| SWP_NOSIZE
);
15582 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
15583 ret
= SetForegroundWindow(GetDesktopWindow());
15584 ok(ret
, "Failed to set foreground window.\n");
15586 ret
= ShowWindow(window
, SW_RESTORE
);
15587 ok(ret
, "Failed to restore window, error %lu.\n", GetLastError());
15589 ret
= SetForegroundWindow(window
);
15590 ok(ret
, "SetForegroundWindow failed, error %lu.\n", GetLastError());
15592 ret
= GetWindowRect(window
, &window_rect
);
15593 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15594 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15595 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15597 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15598 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15599 ret
= GetWindowRect(window
, &window_rect
);
15600 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
15601 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
15602 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
15604 DestroyWindow(window
);
15605 IDirectDraw2_Release(ddraw
);
15609 static void test_window_position(void)
15611 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
15614 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
15617 DDSURFACEDESC surface_desc
;
15618 IDirectDraw2
*ddraw
;
15623 ddraw
= create_ddraw();
15624 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15625 window
= create_window();
15626 ok(!!window
, "Failed to create a window.\n");
15628 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
15629 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
15630 SWP_NOZORDER
| SWP_NOSIZE
);
15631 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
15633 surface_desc
.dwSize
= sizeof(surface_desc
);
15634 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15635 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15636 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %lu.\n",
15637 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
15638 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %lu.\n",
15639 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
15641 DestroyWindow(window
);
15642 IDirectDraw2_Release(ddraw
);
15646 static void test_get_display_mode(void)
15648 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
15649 struct find_different_mode_param param
;
15650 DDSURFACEDESC surface_desc
;
15651 IDirectDraw2
*ddraw
;
15657 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
15659 ddraw
= create_ddraw();
15660 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15661 window
= create_window();
15662 ok(!!window
, "Failed to create a window.\n");
15664 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15665 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
15667 memset(&devmode
, 0, sizeof(devmode
));
15668 devmode
.dmSize
= sizeof(devmode
);
15669 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
15670 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
15672 surface_desc
.dwSize
= sizeof(surface_desc
);
15673 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15674 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15675 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Got dwSize %lu.\n", surface_desc
.dwSize
);
15676 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#lx, got %#lx.\n", flags
,
15677 surface_desc
.dwFlags
);
15678 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %lu, got %lu.\n",
15679 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
15680 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %lu, got %lu.\n",
15681 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
15682 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %lu, got %lu.\n",
15683 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
15684 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
15685 "Got ddpfPixelFormat.dwSize %lu.\n", surface_desc
.ddpfPixelFormat
.dwSize
);
15686 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
15687 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
15688 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15689 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15690 "Expected pitch %lu, got %lu.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
15691 surface_desc
.lPitch
);
15693 memset(¶m
, 0, sizeof(param
));
15694 param
.old_frequency
= surface_desc
.dwRefreshRate
;
15695 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
15696 find_different_mode_callback
);
15697 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
15698 if (!param
.new_frequency
)
15700 skip("Failed to find a display mode with a different frequency.\n");
15704 hr
= IDirectDraw2_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
15705 param
.new_frequency
, 0);
15706 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#lx.\n", hr
);
15707 hr
= IDirectDraw2_GetDisplayMode(ddraw
, &surface_desc
);
15708 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
15709 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %lu.\n", param
.new_width
,
15710 surface_desc
.dwWidth
);
15711 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %lu.\n", param
.new_height
,
15712 surface_desc
.dwHeight
);
15713 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %lu.\n",
15714 param
.new_frequency
, surface_desc
.dwRefreshRate
);
15715 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
15716 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
15717 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
15720 DestroyWindow(window
);
15721 IDirectDraw2_Release(ddraw
);
15724 static void test_texture_wrong_caps(const GUID
*device_guid
)
15726 static D3DLVERTEX quad
[] =
15728 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
15729 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
15730 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
15731 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
15733 static DDPIXELFORMAT fmt
=
15735 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
15736 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
15738 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
15739 D3DTEXTUREHANDLE texture_handle
, ret_handle
;
15740 unsigned int color
, expected_color
;
15741 IDirectDrawSurface
*surface
, *rt
;
15742 IDirect3DMaterial2
*background
;
15743 IDirect3DViewport2
*viewport
;
15744 IDirect3DTexture2
*texture
;
15745 IDirect3DDevice2
*device
;
15746 IDirectDraw2
*ddraw
;
15747 DDSURFACEDESC ddsd
;
15752 window
= create_window();
15753 ddraw
= create_ddraw();
15754 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15755 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
, NULL
)))
15757 skip("Failed to create a 3D device, skipping test.\n");
15758 DestroyWindow(window
);
15761 hr
= IDirect3DDevice2_GetRenderTarget(device
, &rt
);
15762 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15764 viewport
= create_viewport(device
, 0, 0, 640, 480);
15765 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
15766 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15768 memset(&ddsd
, 0, sizeof(ddsd
));
15769 ddsd
.dwSize
= sizeof(ddsd
);
15770 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
15771 ddsd
.dwHeight
= 16;
15773 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
15774 ddsd
.ddpfPixelFormat
= fmt
;
15775 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
15776 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15777 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
15778 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
15779 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
15780 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15782 fill_surface(surface
, 0xff00ff00);
15784 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
15785 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15786 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15787 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15788 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
15789 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15790 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &ret_handle
);
15791 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15792 todo_wine_if (!is_software_device_type(device_guid
))
15793 ok(ret_handle
== texture_handle
, "Got handle %#lx.\n", ret_handle
);
15795 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
15796 viewport_set_background(device
, viewport
, background
);
15798 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
15799 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15800 if (is_software_device_type(device_guid
))
15801 fill_surface(rt
, 0xffff0000);
15803 hr
= IDirect3DDevice2_BeginScene(device
);
15804 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15805 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DVT_LVERTEX
, quad
, ARRAY_SIZE(quad
), 0);
15806 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15807 hr
= IDirect3DDevice2_EndScene(device
);
15808 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15810 expected_color
= is_software_device_type(device_guid
) ? 0x0000ff00 : 0x00ffffff;
15811 color
= get_surface_color(rt
, 320, 240);
15812 ok(compare_color(color
, expected_color
, 1), "Got color 0x%08x, expected 0x%08x.\n", color
, expected_color
);
15814 IDirect3DTexture2_Release(texture
);
15815 IDirectDrawSurface_Release(surface
);
15816 IDirectDrawSurface_Release(rt
);
15817 destroy_viewport(device
, viewport
);
15818 destroy_material(background
);
15819 refcount
= IDirect3DDevice2_Release(device
);
15820 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15821 IDirectDraw2_Release(ddraw
);
15822 DestroyWindow(window
);
15825 static void test_filling_convention(void)
15827 IDirectDrawSurface
*rt
, *backbuffer
, *cur
, *ds
;
15828 static const DWORD colour_bottom
= 0x00ffff00;
15829 static const DWORD colour_clear
= 0x000000ff;
15830 static const DWORD colour_right
= 0x00000000;
15831 static const DWORD colour_left
= 0x00ff0000;
15832 static const DWORD colour_top
= 0x0000ff00;
15833 unsigned int colour
, expected
, i
, j
, x
, y
;
15834 IDirect3DMaterial2
*background
;
15835 IDirect3DViewport2
*viewport
;
15836 IDirect3DDevice2
*device
;
15837 IDirectDraw2
*ddraw
;
15838 DDSURFACEDESC desc
;
15845 static const unsigned int vp_size
= 8;
15846 D3DRECT clear_rect
= {{0}, {0}, {vp_size
}, {vp_size
}};
15848 /* This test data follows the examples in MSDN's
15849 * "Rasterization Rules (Direct3D 9)" article.
15851 * See the d3d9 test for a comment about the eps value. */
15852 static const float eps
= 1.0f
/ 64.0f
;
15853 D3DLVERTEX center_tris
[] =
15856 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15857 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15858 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15861 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15862 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15863 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15866 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15867 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15868 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15871 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15872 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15873 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15878 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15879 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15880 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15883 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15884 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15885 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15888 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15889 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15890 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15893 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15894 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15895 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15897 nudge_right_tris
[] =
15900 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15901 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15902 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15905 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15906 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15907 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15910 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15911 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15912 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15915 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15916 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15917 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15919 nudge_left_tris
[] =
15921 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15922 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15923 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15926 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15927 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15928 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15931 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15932 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15933 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15936 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15937 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15938 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15943 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15944 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15945 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15948 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15949 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15950 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15953 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15954 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15955 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15958 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15959 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15960 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15962 nudge_bottom_tris
[] =
15965 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15966 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15967 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15970 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15971 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15972 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15975 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15976 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15977 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15980 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15981 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15982 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15985 D3DTLVERTEX center_tris_t
[] =
15988 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15989 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15990 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15993 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15994 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15995 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15998 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15999 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
16000 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
16003 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16004 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16005 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16010 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
16011 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
16012 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
16015 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
16016 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
16017 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
16020 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
16021 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
16022 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
16025 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16026 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16027 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
16034 const char *expected
[8];
16152 window
= create_window();
16153 ddraw
= create_ddraw();
16154 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16155 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
16157 skip("Failed to create a 3D device.\n");
16158 IDirectDraw2_Release(ddraw
);
16159 DestroyWindow(window
);
16163 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
16164 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16165 hr
= IDirect3DDevice2_GetRenderTarget(device
, &backbuffer
);
16166 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16168 viewport
= create_viewport(device
, 0, 0, vp_size
, vp_size
);
16169 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
16170 viewport_set_background(device
, viewport
, background
);
16171 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
16172 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16174 memset(&desc
, 0, sizeof(desc
));
16175 desc
.dwSize
= sizeof(desc
);
16176 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16177 desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
16178 desc
.dwWidth
= vp_size
;
16179 desc
.dwHeight
= vp_size
;
16180 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
16181 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
16182 desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
16183 desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
16184 desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
16185 desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
16186 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, &rt
, NULL
);
16187 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16189 /* Nvidia on Windows 10 refuses to set the offscreen RT
16190 * if it does not have an attached depth stencil. */
16191 ds
= get_depth_stencil(device
);
16192 memset(&desc
, 0, sizeof(desc
));
16193 desc
.dwSize
= sizeof(desc
);
16194 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
16195 hr
= IDirectDrawSurface_GetPixelFormat(ds
, &desc
.ddpfPixelFormat
);
16196 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16197 IDirectDrawSurface4_Release(ds
);
16199 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16200 desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16201 desc
.dwWidth
= vp_size
;
16202 desc
.dwHeight
= vp_size
;
16203 hr
= IDirectDraw2_CreateSurface(ddraw
, &desc
, &ds
, NULL
);
16204 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16205 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
16206 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
16208 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16209 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16210 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
16211 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16213 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16215 for (j
= 0; j
< 2; ++j
)
16217 cur
= j
? rt
: backbuffer
;
16219 hr
= IDirect3DDevice2_SetRenderTarget(device
, cur
, 0);
16220 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16221 hr
= IDirect3DViewport2_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
16222 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16224 hr
= IDirect3DDevice2_BeginScene(device
);
16225 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16226 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLELIST
,
16227 tests
[i
].fvf
, tests
[i
].geometry
, 12, 0);
16228 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16229 hr
= IDirect3DDevice2_EndScene(device
);
16230 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16232 for (y
= 0; y
< 8; y
++)
16234 for (x
= 0; x
< 8; x
++)
16237 switch (tests
[i
].expected
[y
][x
])
16239 case 'l': todo
= TRUE
;
16241 expected
= colour_left
;
16243 case 't': todo
= TRUE
;
16245 expected
= colour_top
;
16247 case 'r': todo
= TRUE
;
16249 expected
= colour_right
;
16251 case 'b': todo
= TRUE
;
16253 expected
= colour_bottom
;
16256 expected
= colour_clear
;
16259 ok(0, "Unexpected entry in expected test char\n");
16260 expected
= 0xdeadbeef;
16262 colour
= get_surface_color(cur
, x
, y
);
16263 /* The nudge-to-bottom test fails on cards that give us a bottom-left
16264 * filling convention. The cause isn't the bottom part of the filling
16265 * convention, but because wined3d will nudge geometry to the left to
16266 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
16267 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
16268 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
16269 colour
, x
, y
, i
, j
);
16275 destroy_viewport(device
, viewport
);
16276 IDirectDrawSurface_Release(backbuffer
);
16277 IDirectDrawSurface_Release(rt
);
16278 IDirectDrawSurface_Release(ds
);
16279 IDirect3D2_Release(d3d
);
16280 refcount
= IDirect3DDevice2_Release(device
);
16281 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16282 refcount
= IDirectDraw2_Release(ddraw
);
16283 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16284 DestroyWindow(window
);
16287 static HRESULT WINAPI
test_enum_devices_caps_callback(GUID
*guid
, char *device_desc
,
16288 char *device_name
, D3DDEVICEDESC
*hal
, D3DDEVICEDESC
*hel
, void *ctx
)
16290 if(IsEqualGUID(&IID_IDirect3DRGBDevice
, guid
))
16292 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16293 "RGB Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16294 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16295 "RGB Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16296 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16297 "RGB Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16298 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16299 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16301 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16302 "RGB Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16303 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16304 "RGB Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16305 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16306 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16307 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16308 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16310 ok(hal
->dcmColorModel
== 0, "RGB Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16311 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "RGB Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16313 ok(hal
->dwFlags
== 0, "RGB Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16314 ok(hel
->dwFlags
!= 0, "RGB Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16316 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16317 "RGB Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16318 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16319 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16320 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16321 "RGB Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16322 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16323 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16324 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWRASTERIZATION
) == 0,
16325 "RGB Device hal device caps has D3DDEVCAPS_HWRASTERIZATION set\n");
16326 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWRASTERIZATION
) == 0,
16327 "RGB Device hel device caps has D3DDEVCAPS_HWRASTERIZATION set\n");
16329 else if(IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
16331 ok(hal
->dcmColorModel
== D3DCOLOR_RGB
, "HAL Device hal caps has colormodel %lu\n", hel
->dcmColorModel
);
16332 ok(hel
->dcmColorModel
== 0, "HAL Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16334 ok(hal
->dwFlags
!= 0, "HAL Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16335 ok(hel
->dwFlags
!= 0, "HAL Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16337 ok(hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
,
16338 "HAL Device hal device caps does not have D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16339 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16340 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16341 ok(hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
,
16342 "HAL Device hal device caps does not have D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16343 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16344 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16346 else if(IsEqualGUID(&IID_IDirect3DRefDevice
, guid
))
16348 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16349 "REF Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16350 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16351 "REF Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16352 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16353 "REF Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16354 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16355 "REF Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16357 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16358 "REF Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16359 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16360 "REF Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16361 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16362 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16363 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16364 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16366 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16367 "REF Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16368 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16369 "REF Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16370 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16371 "REF Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16372 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16373 "REF Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16375 else if(IsEqualGUID(&IID_IDirect3DRampDevice
, guid
))
16377 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16378 "Ramp Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16379 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16380 "Ramp Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16381 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16382 "Ramp Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16383 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16384 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16386 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16387 "Ramp Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16388 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16389 "Ramp Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16390 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16391 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16392 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16393 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16395 ok(hal
->dcmColorModel
== 0, "Ramp Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16396 ok(hel
->dcmColorModel
== D3DCOLOR_MONO
, "Ramp Device hel caps has colormodel %lu\n",
16397 hel
->dcmColorModel
);
16399 ok(hal
->dwFlags
== 0, "Ramp Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16400 ok(hel
->dwFlags
!= 0, "Ramp Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16402 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16403 "Ramp Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16404 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16405 "Ramp Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16406 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16407 "Ramp Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16408 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16409 "Ramp Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16411 else if(IsEqualGUID(&IID_IDirect3DMMXDevice
, guid
))
16413 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16414 "MMX Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
16415 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
16416 "MMX Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
16417 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16418 "MMX Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16419 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
16420 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
16422 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16423 "MMX Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16424 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
16425 "MMX Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
16426 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16427 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16428 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
16429 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
16431 ok(hal
->dcmColorModel
== 0, "MMX Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
16432 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "MMX Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
16434 ok(hal
->dwFlags
== 0, "MMX Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
16435 ok(hel
->dwFlags
!= 0, "MMX Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
16437 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16438 "MMX Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16439 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
16440 "MMX Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
16441 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16442 "MMX Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16443 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
16444 "MMX Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
16448 ok(FALSE
, "Unexpected device enumerated: \"%s\" \"%s\"\n", device_desc
, device_name
);
16449 if (hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16450 trace("hal line has pow2 set\n");
16452 trace("hal line does NOT have pow2 set\n");
16453 if (hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16454 trace("hal tri has pow2 set\n");
16456 trace("hal tri does NOT have pow2 set\n");
16457 if (hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16458 trace("hel line has pow2 set\n");
16460 trace("hel line does NOT have pow2 set\n");
16461 if (hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
16462 trace("hel tri has pow2 set\n");
16464 trace("hel tri does NOT have pow2 set\n");
16467 return DDENUMRET_OK
;
16470 static void test_enum_devices(void)
16472 IDirectDraw2
*ddraw
;
16477 ddraw
= create_ddraw();
16478 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16480 hr
= IDirectDraw2_QueryInterface(ddraw
, &IID_IDirect3D2
, (void **)&d3d
);
16483 skip("D3D interface is not available, skipping test.\n");
16484 IDirectDraw2_Release(ddraw
);
16488 hr
= IDirect3D2_EnumDevices(d3d
, NULL
, NULL
);
16489 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
16491 hr
= IDirect3D2_EnumDevices(d3d
, test_enum_devices_caps_callback
, NULL
);
16492 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
16494 IDirect3D2_Release(d3d
);
16495 refcount
= IDirectDraw2_Release(ddraw
);
16496 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16499 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
16501 test_func(&IID_IDirect3DHALDevice
);
16502 test_func(&IID_IDirect3DRGBDevice
);
16505 static void test_multiple_devices(void)
16507 D3DTEXTUREHANDLE texture_handle
, texture_handle2
;
16508 IDirect3DDevice2
*device
, *device2
, *device3
;
16509 IDirectDrawSurface
*surface
, *texture_surf
;
16510 D3DMATERIALHANDLE mat_handle
, mat_handle2
;
16511 IDirect3DViewport2
*viewport
, *viewport2
;
16512 IDirectDraw2
*ddraw
, *ddraw2
;
16513 IDirect3DMaterial2
*material
;
16514 DDSURFACEDESC surface_desc
;
16515 IDirect3DTexture2
*texture
;
16522 window
= create_window();
16523 ddraw
= create_ddraw();
16524 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16526 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, &IID_IDirect3DHALDevice
, &surface
)))
16528 skip("Failed to create a 3D device, skipping test.\n");
16529 DestroyWindow(window
);
16533 hr
= IDirect3DDevice2_GetDirect3D(device
, &d3d
);
16534 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16535 hr
= IDirect3D2_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device2
);
16536 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16538 ddraw2
= create_ddraw();
16539 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
16540 device3
= create_device(ddraw2
, window
, DDSCL_NORMAL
);
16541 ok(!!device3
, "got NULL.\n");
16543 viewport
= create_viewport(device
, 0, 0, 640, 480);
16544 viewport2
= create_viewport(device2
, 0, 0, 640, 480);
16545 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
16546 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16547 hr
= IDirect3DDevice2_SetCurrentViewport(device2
, viewport
);
16548 ok(hr
== DDERR_INVALIDPARAMS
, "got %#lx.\n", hr
);
16549 hr
= IDirect3DDevice2_SetCurrentViewport(device2
, viewport2
);
16550 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16552 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
16553 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
16554 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16555 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle2
);
16556 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16557 ok(mat_handle
== mat_handle2
, "got different handles.\n");
16559 hr
= IDirect3DMaterial2_GetHandle(material
, device2
, &mat_handle2
);
16560 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16561 todo_wine
ok(mat_handle
!= mat_handle2
, "got same handles.\n");
16563 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
16564 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16565 hr
= IDirect3DDevice2_SetLightState(device2
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
16566 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16567 hr
= IDirect3DDevice2_SetLightState(device3
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
16568 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16569 hr
= IDirect3DDevice2_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle2
);
16570 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16572 hr
= IDirect3DViewport2_SetBackground(viewport
, mat_handle
);
16573 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16574 hr
= IDirect3DViewport2_SetBackground(viewport2
, mat_handle
);
16575 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16577 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
16578 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16579 hr
= IDirect3DDevice2_SetRenderState(device2
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
16580 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16581 hr
= IDirect3DDevice2_SetRenderState(device3
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
16582 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16584 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
16585 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16586 value
= 0xdeadbeef;
16587 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
16588 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16589 ok(value
== TRUE
, "got %#lx.\n", value
);
16590 hr
= IDirect3DDevice2_GetRenderState(device2
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
16591 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16592 ok(!value
, "got %#lx.\n", value
);
16593 hr
= IDirect3DDevice2_GetRenderState(device3
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
16594 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16595 ok(!value
, "got %#lx.\n", value
);
16597 memset(&surface_desc
, 0, sizeof(surface_desc
));
16598 surface_desc
.dwSize
= sizeof(surface_desc
);
16599 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
16600 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16601 surface_desc
.dwWidth
= 256;
16602 surface_desc
.dwHeight
= 256;
16603 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &texture_surf
, NULL
);
16604 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16605 hr
= IDirectDrawSurface_QueryInterface(texture_surf
, &IID_IDirect3DTexture2
, (void **)&texture
);
16606 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16607 hr
= IDirect3DTexture2_GetHandle(texture
, device
, &texture_handle
);
16608 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16609 hr
= IDirect3DTexture2_GetHandle(texture
, device2
, &texture_handle2
);
16610 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16611 ok(texture_handle
== texture_handle2
, "got different handles.\n");
16612 hr
= IDirect3DTexture2_GetHandle(texture
, device3
, &texture_handle2
);
16613 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16614 ok(texture_handle
== texture_handle2
, "got different handles.\n");
16615 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
16616 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16617 hr
= IDirect3DDevice2_SetRenderState(device2
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
16618 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16619 hr
= IDirect3DDevice2_SetRenderState(device3
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
16620 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
16622 IDirect3DTexture2_Release(texture
);
16623 IDirectDrawSurface_Release(texture_surf
);
16624 IDirect3DMaterial2_Release(material
);
16625 IDirect3DViewport2_Release(viewport
);
16626 IDirect3DViewport2_Release(viewport2
);
16628 refcount
= IDirect3DDevice2_Release(device
);
16629 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16630 refcount
= IDirect3DDevice2_Release(device2
);
16631 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16632 refcount
= IDirect3DDevice2_Release(device3
);
16633 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16634 refcount
= IDirectDrawSurface_Release(surface
);
16635 ok(!refcount
, "Surface has %lu references left.\n", refcount
);
16637 IDirectDraw2_Release(ddraw
);
16638 IDirectDraw_Release(ddraw2
);
16639 IDirect3D2_Release(d3d
);
16640 DestroyWindow(window
);
16643 static void test_d3d_state_reset(void)
16645 struct find_different_mode_param param
;
16646 IDirect3DViewport2
*viewport
;
16647 IDirectDrawSurface
*surface
;
16648 IDirect3DDevice2
*device
;
16649 D3DVIEWPORT2 vp1
, vp2
;
16650 IDirectDraw2
*ddraw
;
16651 DDSURFACEDESC ddsd
;
16656 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
, 0, 0, 100, 100, 0, 0, 0, 0);
16658 window
= create_window();
16659 ddraw
= create_ddraw();
16660 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16662 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
16664 skip("Failed to create 3D device.\n");
16665 DestroyWindow(window
);
16669 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x00282828);
16670 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16671 hr
= IDirect3DDevice2_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, TRUE
);
16672 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16674 memset(¶m
, 0, sizeof(param
));
16675 hr
= IDirectDraw2_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
16676 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16678 viewport
= create_viewport(device
, 0, 0, param
.old_width
, param
.old_height
);
16679 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16681 vp1
.dwSize
= sizeof(vp1
);
16682 vp2
.dwSize
= sizeof(vp2
);
16684 hr
= IDirect3DDevice2_SetCurrentViewport(device
, viewport
);
16685 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16686 hr
= IDirect3DViewport2_GetViewport2(viewport
, &vp1
);
16687 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16689 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
16690 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16692 hr
= IDirect3DViewport2_GetViewport2(viewport
, &vp2
);
16693 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16694 ok(vp2
.dwWidth
== vp1
.dwWidth
, "got %ld, expected %ld.\n", vp2
.dwWidth
, vp1
.dwWidth
);
16695 ok(vp2
.dwHeight
== vp1
.dwHeight
, "got %ld, expected %ld.\n", vp2
.dwHeight
, vp1
.dwHeight
);
16697 memset(&ddsd
, 0, sizeof(ddsd
));
16698 ddsd
.dwSize
= sizeof(ddsd
);
16699 ddsd
.dwFlags
= DDSD_CAPS
;
16700 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
16702 hr
= IDirectDraw2_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
16703 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16705 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
16706 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16707 ok(ddsd
.dwWidth
== param
.new_width
, "got %ld, expected %d.\n", ddsd
.dwWidth
, param
.new_width
);
16708 ok(ddsd
.dwHeight
== param
.new_height
, "got %ld, expected %d.\n", ddsd
.dwHeight
, param
.new_height
);
16710 hr
= IDirect3DViewport2_GetViewport2(viewport
, &vp2
);
16711 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16712 ok(vp2
.dwWidth
== vp1
.dwWidth
, "got %ld, expected %ld.\n", vp2
.dwWidth
, vp1
.dwWidth
);
16713 ok(vp2
.dwHeight
== vp1
.dwHeight
, "got %ld, expected %ld.\n", vp2
.dwHeight
, vp1
.dwHeight
);
16715 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, &state
);
16716 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16717 ok(state
== 0x00282828, "got %#lx.\n", state
);
16718 hr
= IDirect3DDevice2_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &state
);
16719 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16720 ok(state
== TRUE
, "got %#lx.\n", state
);
16722 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
16723 ok(hr
== DD_OK
, "got %#lx.\n", hr
);
16725 IDirect3DViewport2_Release(viewport
);
16726 IDirectDrawSurface_Release(surface
);
16727 IDirectDraw2_Release(ddraw
);
16728 IDirect3DDevice2_Release(device
);
16729 DestroyWindow(window
);
16734 DDDEVICEIDENTIFIER identifier
;
16735 DEVMODEW current_mode
;
16736 IDirectDraw2
*ddraw
;
16739 if (!(ddraw
= create_ddraw()))
16741 skip("Failed to create a ddraw object, skipping tests.\n");
16745 if (ddraw_get_identifier(ddraw
, &identifier
))
16747 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
16748 trace("Description string: \"%s\"\n", identifier
.szDescription
);
16749 trace("Driver version %d.%d.%d.%d\n",
16750 HIWORD(identifier
.liDriverVersion
.HighPart
), LOWORD(identifier
.liDriverVersion
.HighPart
),
16751 HIWORD(identifier
.liDriverVersion
.LowPart
), LOWORD(identifier
.liDriverVersion
.LowPart
));
16753 IDirectDraw2_Release(ddraw
);
16755 memset(¤t_mode
, 0, sizeof(current_mode
));
16756 current_mode
.dmSize
= sizeof(current_mode
);
16757 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
16758 registry_mode
.dmSize
= sizeof(registry_mode
);
16759 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
16760 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
16761 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
16763 skip("Current mode does not match registry mode, skipping test.\n");
16767 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
16768 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
16770 test_coop_level_create_device_window();
16771 test_clipper_blt();
16772 test_coop_level_d3d_state();
16773 test_surface_interface_mismatch();
16774 test_coop_level_threaded();
16775 run_for_each_device_type(test_depth_blit
);
16776 test_texture_load_ckey();
16777 test_viewport_object();
16778 run_for_each_device_type(test_zenable
);
16779 run_for_each_device_type(test_ck_rgba
);
16785 test_window_style();
16786 test_redundant_mode_set();
16787 test_coop_level_mode_set();
16788 test_coop_level_mode_set_multi();
16790 test_coop_level_surf_create();
16791 test_coop_level_multi_window();
16792 test_clear_rect_count();
16793 test_coop_level_versions();
16794 test_lighting_interface_versions();
16795 test_coop_level_activateapp();
16796 test_unsupported_formats();
16797 run_for_each_device_type(test_rt_caps
);
16798 test_primary_caps();
16799 test_surface_lock();
16800 test_surface_discard();
16802 test_set_surface_desc();
16803 test_user_memory_getdc();
16804 test_sysmem_overlay();
16805 test_primary_palette();
16806 test_surface_attachment();
16807 test_pixel_format();
16808 test_create_surface_pitch();
16810 test_palette_complex();
16814 test_specular_lighting();
16815 test_palette_gdi();
16816 test_palette_alpha();
16817 test_lost_device();
16818 test_surface_desc_lock();
16819 test_texturemapblend();
16820 test_viewport_clear_rect();
16822 test_colorkey_precision();
16823 test_range_colorkey();
16825 test_lockrect_invalid();
16826 test_yv12_overlay();
16827 test_offscreen_overlay();
16828 test_overlay_rect();
16830 test_blt_z_alpha();
16831 test_cross_device_blt();
16833 test_draw_primitive();
16834 test_edge_antialiasing_blending();
16835 test_transform_vertices();
16836 test_display_mode_surface_pixel_format();
16837 test_surface_desc_size();
16838 test_ck_operation();
16839 test_set_render_state();
16840 test_depth_readback();
16842 test_enum_surfaces();
16844 test_find_device();
16846 test_gdi_surface();
16848 test_clipper_refcount();
16850 test_d32_support();
16851 test_cursor_clipping();
16852 test_window_position();
16853 test_get_display_mode();
16854 run_for_each_device_type(test_texture_wrong_caps
);
16855 test_filling_convention();
16856 test_enum_devices();
16857 test_multiple_devices();
16858 test_d3d_state_reset();