2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2006, 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
22 #include "wine/test.h"
23 #include "wine/heap.h"
28 HRESULT WINAPI
GetSurfaceFromDC(HDC dc
, struct IDirectDrawSurface
**surface
, HDC
*device_dc
);
30 static HRESULT (WINAPI
*pDirectDrawCreateEx
)(GUID
*guid
, void **ddraw
, REFIID iid
, IUnknown
*outer_unknown
);
31 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
32 static DEVMODEW registry_mode
;
33 static const GUID
*hw_device_guid
= &IID_IDirect3DHALDevice
;
35 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
52 struct create_window_thread_param
55 HANDLE window_created
;
56 HANDLE destroy_window
;
60 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
70 if (abs(x
- y
) > ulps
)
76 static BOOL
compare_vec3(struct vec3
*vec
, float x
, float y
, float z
, unsigned int ulps
)
78 return compare_float(vec
->x
, x
, ulps
)
79 && compare_float(vec
->y
, y
, ulps
)
80 && compare_float(vec
->z
, z
, ulps
);
83 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
85 return compare_float(vec
->x
, x
, ulps
)
86 && compare_float(vec
->y
, y
, ulps
)
87 && compare_float(vec
->z
, z
, ulps
)
88 && compare_float(vec
->w
, w
, ulps
);
91 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
93 unsigned int diff
= x
> y
? x
- y
: y
- x
;
95 return diff
<= max_diff
;
98 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
100 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
101 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
102 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
103 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
106 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
108 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
109 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
110 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
111 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
114 static ULONG
get_refcount(IUnknown
*iface
)
116 IUnknown_AddRef(iface
);
117 return IUnknown_Release(iface
);
120 static void get_virtual_rect(RECT
*rect
)
122 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
123 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
124 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
125 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
128 /* Try to make sure pending X events have been processed before continuing */
129 static void flush_events(void)
135 time
= GetTickCount() + diff
;
138 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
140 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
141 DispatchMessageA(&msg
);
142 diff
= time
- GetTickCount();
146 static BOOL
ddraw_get_identifier(IDirectDraw7
*ddraw
, DDDEVICEIDENTIFIER2
*identifier
)
150 hr
= IDirectDraw7_GetDeviceIdentifier(ddraw
, identifier
, 0);
151 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
153 return SUCCEEDED(hr
);
156 static BOOL
ddraw_is_warp(IDirectDraw7
*ddraw
)
158 DDDEVICEIDENTIFIER2 identifier
;
160 return strcmp(winetest_platform
, "wine")
161 && ddraw_get_identifier(ddraw
, &identifier
)
162 && strstr(identifier
.szDriver
, "warp");
165 static BOOL
ddraw_is_vendor(IDirectDraw7
*ddraw
, DWORD vendor
)
167 DDDEVICEIDENTIFIER2 identifier
;
169 return strcmp(winetest_platform
, "wine")
170 && ddraw_get_identifier(ddraw
, &identifier
)
171 && identifier
.dwVendorId
== vendor
;
174 static BOOL
ddraw_is_intel(IDirectDraw7
*ddraw
)
176 return ddraw_is_vendor(ddraw
, 0x8086);
179 static BOOL
ddraw_is_nvidia(IDirectDraw7
*ddraw
)
181 return ddraw_is_vendor(ddraw
, 0x10de);
184 static BOOL
ddraw_is_vmware(IDirectDraw7
*ddraw
)
186 return ddraw_is_vendor(ddraw
, 0x15ad);
189 static BOOL
ddraw_is_amd(IDirectDraw7
*ddraw
)
191 return ddraw_is_vendor(ddraw
, 0x1002);
194 static BOOL
is_software_device_type(const GUID
*device_guid
)
196 return device_guid
!= &IID_IDirect3DTnLHalDevice
&& device_guid
!= &IID_IDirect3DHALDevice
;
199 static IDirectDrawSurface7
*create_overlay(IDirectDraw7
*ddraw
,
200 unsigned int width
, unsigned int height
, DWORD format
)
202 IDirectDrawSurface7
*surface
;
205 memset(&desc
, 0, sizeof(desc
));
206 desc
.dwSize
= sizeof(desc
);
207 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
208 desc
.dwWidth
= width
;
209 desc
.dwHeight
= height
;
210 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
211 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
212 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
213 U4(desc
).ddpfPixelFormat
.dwFourCC
= format
;
215 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
220 static HWND
create_window(void)
222 RECT r
= {0, 0, 640, 480};
224 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
226 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
227 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
230 static DWORD WINAPI
create_window_thread_proc(void *param
)
232 struct create_window_thread_param
*p
= param
;
236 p
->window
= create_window();
237 ret
= SetEvent(p
->window_created
);
238 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
244 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
245 DispatchMessageA(&msg
);
246 res
= WaitForSingleObject(p
->destroy_window
, 100);
247 if (res
== WAIT_OBJECT_0
)
249 if (res
!= WAIT_TIMEOUT
)
251 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
256 DestroyWindow(p
->window
);
261 static void create_window_thread(struct create_window_thread_param
*p
)
265 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
266 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
267 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
268 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
269 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
270 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
271 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
272 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
275 static void destroy_window_thread(struct create_window_thread_param
*p
)
277 SetEvent(p
->destroy_window
);
278 WaitForSingleObject(p
->thread
, INFINITE
);
279 CloseHandle(p
->destroy_window
);
280 CloseHandle(p
->window_created
);
281 CloseHandle(p
->thread
);
284 static IDirectDrawSurface7
*get_depth_stencil(IDirect3DDevice7
*device
)
286 IDirectDrawSurface7
*rt
, *ret
;
287 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, {0}};
290 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
291 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
292 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &ret
);
293 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
294 IDirectDrawSurface7_Release(rt
);
298 /* Free original_modes after finished using it */
299 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
301 unsigned int number
, size
= 2, count
= 0, index
= 0;
302 DISPLAY_DEVICEW display_device
;
303 DEVMODEW
*modes
, *tmp
;
305 if (!(modes
= heap_alloc(size
* sizeof(*modes
))))
308 display_device
.cb
= sizeof(display_device
);
309 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
311 /* Skip software devices */
312 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
315 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
321 if (!(tmp
= heap_realloc(modes
, size
* sizeof(*modes
))))
329 memset(&modes
[count
], 0, sizeof(modes
[count
]));
330 modes
[count
].dmSize
= sizeof(modes
[count
]);
331 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
337 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
340 *original_modes
= modes
;
341 *display_count
= count
;
345 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
350 for (index
= 0; index
< count
; ++index
)
352 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
353 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
354 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
357 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
358 return ret
== DISP_CHANGE_SUCCESSFUL
;
361 static HRESULT
set_display_mode(IDirectDraw7
*ddraw
, DWORD width
, DWORD height
)
363 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
365 return IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
368 static D3DCOLOR
get_surface_color(IDirectDrawSurface7
*surface
, UINT x
, UINT y
)
370 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
371 DDSURFACEDESC2 surface_desc
;
375 memset(&surface_desc
, 0, sizeof(surface_desc
));
376 surface_desc
.dwSize
= sizeof(surface_desc
);
378 hr
= IDirectDrawSurface7_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
, NULL
);
379 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
383 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
385 hr
= IDirectDrawSurface7_Unlock(surface
, &rect
);
386 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
391 static void fill_surface(IDirectDrawSurface7
*surface
, D3DCOLOR color
)
393 DDSURFACEDESC2 surface_desc
= {sizeof(surface_desc
)};
398 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
399 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
401 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
403 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
404 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
410 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
411 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
414 #define check_rect(a, b, c) check_rect_(__LINE__, a, b, c)
415 static void check_rect_(unsigned int line
, IDirectDrawSurface7
*surface
, RECT r
, const char *message
)
417 LONG x_coords
[2][2] =
419 {r
.left
- 1, r
.left
+ 1},
420 {r
.right
+ 1, r
.right
- 1},
422 LONG y_coords
[2][2] =
424 {r
.top
- 1, r
.top
+ 1},
425 {r
.bottom
+ 1, r
.bottom
- 1}
427 unsigned int i
, j
, x_side
, y_side
;
431 for (i
= 0; i
< 2; ++i
)
433 for (j
= 0; j
< 2; ++j
)
435 for (x_side
= 0; x_side
< 2; ++x_side
)
437 for (y_side
= 0; y_side
< 2; ++y_side
)
439 DWORD expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
441 x
= x_coords
[i
][x_side
];
442 y
= y_coords
[j
][y_side
];
443 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
445 color
= get_surface_color(surface
, x
, y
);
446 ok_(__FILE__
, line
)(color
== expected
, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
447 message
, x
, y
, color
, expected
);
454 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
456 DDPIXELFORMAT
*z_fmt
= ctx
;
458 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
464 static IDirectDraw7
*create_ddraw(void)
468 if (FAILED(pDirectDrawCreateEx(NULL
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
)))
474 static HRESULT WINAPI
enum_devtype_cb(char *desc_str
, char *name
, D3DDEVICEDESC7
*desc
, void *ctx
)
477 if (IsEqualGUID(&desc
->deviceGUID
, &IID_IDirect3DTnLHalDevice
))
480 return DDENUMRET_CANCEL
;
485 static IDirect3DDevice7
*create_device_ex(HWND window
, DWORD coop_level
, const GUID
*device_guid
)
487 IDirectDrawSurface7
*surface
, *ds
;
488 IDirect3DDevice7
*device
= NULL
;
489 DDSURFACEDESC2 surface_desc
;
495 if (!(ddraw
= create_ddraw()))
498 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, coop_level
);
499 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
501 memset(&surface_desc
, 0, sizeof(surface_desc
));
502 surface_desc
.dwSize
= sizeof(surface_desc
);
503 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
504 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
505 if (is_software_device_type(device_guid
))
506 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
507 surface_desc
.dwWidth
= 640;
508 surface_desc
.dwHeight
= 480;
510 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
511 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
513 if (coop_level
& DDSCL_NORMAL
)
515 IDirectDrawClipper
*clipper
;
517 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
518 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
519 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
520 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
521 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
522 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
523 IDirectDrawClipper_Release(clipper
);
526 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d7
);
527 IDirectDraw7_Release(ddraw
);
530 IDirectDrawSurface7_Release(surface
);
534 memset(&z_fmt
, 0, sizeof(z_fmt
));
535 hr
= IDirect3D7_EnumZBufferFormats(d3d7
, device_guid
, enum_z_fmt
, &z_fmt
);
536 if (FAILED(hr
) || !z_fmt
.dwSize
)
538 IDirect3D7_Release(d3d7
);
539 IDirectDrawSurface7_Release(surface
);
543 memset(&surface_desc
, 0, sizeof(surface_desc
));
544 surface_desc
.dwSize
= sizeof(surface_desc
);
545 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
546 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
547 if (is_software_device_type(device_guid
))
548 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
549 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
550 surface_desc
.dwWidth
= 640;
551 surface_desc
.dwHeight
= 480;
552 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
553 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
556 IDirect3D7_Release(d3d7
);
557 IDirectDrawSurface7_Release(surface
);
561 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
562 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
563 IDirectDrawSurface7_Release(ds
);
566 IDirect3D7_Release(d3d7
);
567 IDirectDrawSurface7_Release(surface
);
571 hr
= IDirect3D7_CreateDevice(d3d7
, device_guid
, surface
, &device
);
572 IDirect3D7_Release(d3d7
);
573 IDirectDrawSurface7_Release(surface
);
580 static IDirect3DDevice7
*create_device(HWND window
, DWORD coop_level
)
582 const GUID
*device_guid
= &IID_IDirect3DHALDevice
;
588 if (!(ddraw
= create_ddraw()))
590 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d7
);
591 IDirectDraw7_Release(ddraw
);
595 hr
= IDirect3D7_EnumDevices(d3d7
, enum_devtype_cb
, &hal_ok
);
596 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
598 device_guid
= &IID_IDirect3DTnLHalDevice
;
600 IDirect3D7_Release(d3d7
);
602 return create_device_ex(window
, coop_level
, device_guid
);
609 WPARAM expect_wparam
;
613 static const struct message
*expect_messages
;
614 static IDirectDraw7
*focus_test_ddraw
;
616 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
620 if (expect_messages
&& message
== expect_messages
->message
)
622 if (expect_messages
->check_wparam
)
623 ok (wparam
== expect_messages
->expect_wparam
,
624 "Got unexpected wparam %lx for message %x, expected %lx.\n",
625 wparam
, message
, expect_messages
->expect_wparam
);
627 if (focus_test_ddraw
)
629 hr
= IDirectDraw7_TestCooperativeLevel(focus_test_ddraw
);
630 ok(hr
== expect_messages
->ddraw_state
, "Got ddraw state %#x on message %#x, expected %#x.\n",
631 hr
, message
, expect_messages
->ddraw_state
);
637 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
640 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
641 * interface. This prevents subsequent SetCooperativeLevel() calls on a
642 * different window from failing with DDERR_HWNDALREADYSET. */
643 static void fix_wndproc(HWND window
, LONG_PTR proc
)
648 if (!(ddraw
= create_ddraw()))
651 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
652 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
653 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
654 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
655 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
657 IDirectDraw7_Release(ddraw
);
660 static void test_process_vertices(void)
662 IDirect3DVertexBuffer7
*src_vb
, *dst_vb1
, *dst_vb2
;
663 D3DVERTEXBUFFERDESC vb_desc
;
664 IDirect3DDevice7
*device
;
665 struct vec4
*dst_data
;
666 struct vec3
*dst_data2
;
667 struct vec3
*src_data
;
673 static D3DMATRIX world
=
675 0.0f
, 1.0f
, 0.0f
, 0.0f
,
676 1.0f
, 0.0f
, 0.0f
, 0.0f
,
677 0.0f
, 0.0f
, 0.0f
, 1.0f
,
678 0.0f
, 1.0f
, 1.0f
, 1.0f
,
680 static D3DMATRIX view
=
682 2.0f
, 0.0f
, 0.0f
, 0.0f
,
683 0.0f
, -1.0f
, 0.0f
, 0.0f
,
684 0.0f
, 0.0f
, 1.0f
, 0.0f
,
685 0.0f
, 0.0f
, 0.0f
, 3.0f
,
687 static D3DMATRIX proj
=
689 1.0f
, 0.0f
, 0.0f
, 1.0f
,
690 0.0f
, 1.0f
, 1.0f
, 0.0f
,
691 0.0f
, 1.0f
, 1.0f
, 0.0f
,
692 1.0f
, 0.0f
, 0.0f
, 1.0f
,
695 window
= create_window();
696 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
698 skip("Failed to create a 3D device, skipping test.\n");
699 DestroyWindow(window
);
703 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d7
);
704 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
706 memset(&vb_desc
, 0, sizeof(vb_desc
));
707 vb_desc
.dwSize
= sizeof(vb_desc
);
708 vb_desc
.dwFVF
= D3DFVF_XYZ
;
709 vb_desc
.dwNumVertices
= 4;
710 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &src_vb
, 0);
711 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
713 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
714 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
715 src_data
[0].x
= 0.0f
;
716 src_data
[0].y
= 0.0f
;
717 src_data
[0].z
= 0.0f
;
718 src_data
[1].x
= 1.0f
;
719 src_data
[1].y
= 1.0f
;
720 src_data
[1].z
= 1.0f
;
721 src_data
[2].x
= -1.0f
;
722 src_data
[2].y
= -1.0f
;
723 src_data
[2].z
= 0.5f
;
724 src_data
[3].x
= 0.5f
;
725 src_data
[3].y
= -0.5f
;
726 src_data
[3].z
= 0.25f
;
727 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
728 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
730 memset(&vb_desc
, 0, sizeof(vb_desc
));
731 vb_desc
.dwSize
= sizeof(vb_desc
);
732 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
733 vb_desc
.dwNumVertices
= 4;
734 /* MSDN says that the last parameter must be 0 - check that. */
735 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb1
, 4);
736 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
738 memset(&vb_desc
, 0, sizeof(vb_desc
));
739 vb_desc
.dwSize
= sizeof(vb_desc
);
740 vb_desc
.dwFVF
= D3DFVF_XYZ
;
741 vb_desc
.dwNumVertices
= 5;
742 /* MSDN says that the last parameter must be 0 - check that. */
743 hr
= IDirect3D7_CreateVertexBuffer(d3d7
, &vb_desc
, &dst_vb2
, 12345678);
744 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
746 memset(&vp
, 0, sizeof(vp
));
753 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
754 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
756 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
757 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
758 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
759 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
761 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
762 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
763 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
764 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
765 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
766 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e+0f
, +1.000e+0f
, 4096),
767 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
768 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
769 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-1f
, +1.000e+0f
, 4096),
770 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
771 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
772 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-1f
, +1.000e+0f
, 4096),
773 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
774 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
775 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
776 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
778 hr
= IDirect3DVertexBuffer7_Lock(dst_vb2
, 0, (void **)&dst_data2
, NULL
);
779 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
780 /* Small thing without much practical meaning, but I stumbled upon it,
781 * so let's check for it: If the output vertex buffer has no RHW value,
782 * the RHW value of the last vertex is written into the next vertex. */
783 ok(compare_vec3(&dst_data2
[4], +1.000e+0f
, +0.000e+0f
, +0.000e+0f
, 4096),
784 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
785 dst_data2
[4].x
, dst_data2
[4].y
, dst_data2
[4].z
);
786 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb2
);
787 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
789 /* Test degenerate viewport z ranges. */
792 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
793 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
795 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
796 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
797 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
798 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
800 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
801 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
802 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +0.000e+0f
, +1.000e+0f
, 4096),
803 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
804 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
805 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.000e-3f
, +1.000e+0f
, 4096),
806 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
807 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
808 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +5.000e-4f
, +1.000e+0f
, 4096),
809 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
810 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
811 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +2.500e-4f
, +1.000e+0f
, 4096),
812 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
813 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
814 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
815 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
819 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
820 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
822 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
823 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
824 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb2
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
827 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
828 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
829 ok(compare_vec4(&dst_data
[0], +1.280e+2f
, +1.280e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
830 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
831 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
832 ok(compare_vec4(&dst_data
[1], +1.920e+2f
, +6.400e+1f
, +1.001e+0f
, +1.000e+0f
, 4096),
833 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
834 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
835 ok(compare_vec4(&dst_data
[2], +6.400e+1f
, +1.920e+2f
, +1.0005e+0f
, +1.000e+0f
, 4096),
836 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
837 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
838 ok(compare_vec4(&dst_data
[3], +1.600e+2f
, +1.600e+2f
, +1.00025e+0f
, +1.000e+0f
, 4096),
839 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
840 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
841 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
842 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
844 /* Try a more complicated viewport, same vertices. */
845 memset(&vp
, 0, sizeof(vp
));
852 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
853 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
855 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
856 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
858 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
859 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
860 ok(compare_vec4(&dst_data
[0], +1.330e+2f
, +7.000e+1f
, -2.000e+0f
, +1.000e+0f
, 4096),
861 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
862 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
863 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +5.000e+0f
, +4.000e+0f
, +1.000e+0f
, 4096),
864 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
865 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
866 ok(compare_vec4(&dst_data
[2], +1.000e+1f
, +1.350e+2f
, +1.000e+0f
, +1.000e+0f
, 4096),
867 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
868 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
869 ok(compare_vec4(&dst_data
[3], +1.945e+2f
, +1.025e+2f
, -5.000e-1f
, +1.000e+0f
, 4096),
870 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
871 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
872 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
873 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
875 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &world
);
876 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
877 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view
);
878 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
879 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &proj
);
880 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
882 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb1
, D3DVOP_TRANSFORM
, 0, 4, src_vb
, 0, device
, 0);
883 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
885 hr
= IDirect3DVertexBuffer7_Lock(dst_vb1
, 0, (void **)&dst_data
, NULL
);
886 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
887 ok(compare_vec4(&dst_data
[0], +2.560e+2f
, +7.000e+1f
, -2.000e+0f
, +3.333e-1f
, 4096),
888 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
889 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
890 ok(compare_vec4(&dst_data
[1], +2.560e+2f
, +7.813e+1f
, -2.750e+0f
, +1.250e-1f
, 4096),
891 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
892 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
893 ok(compare_vec4(&dst_data
[2], +2.560e+2f
, +4.400e+1f
, +4.000e-1f
, +4.000e-1f
, 4096),
894 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
895 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
896 ok(compare_vec4(&dst_data
[3], +2.560e+2f
, +8.182e+1f
, -3.091e+0f
, +3.636e-1f
, 4096),
897 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
898 dst_data
[3].x
, dst_data
[3].y
, dst_data
[3].z
, dst_data
[3].w
);
899 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb1
);
900 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
902 IDirect3DVertexBuffer7_Release(dst_vb2
);
903 IDirect3DVertexBuffer7_Release(dst_vb1
);
904 IDirect3DVertexBuffer7_Release(src_vb
);
905 IDirect3D7_Release(d3d7
);
906 IDirect3DDevice7_Release(device
);
907 DestroyWindow(window
);
910 static void test_coop_level_create_device_window(void)
912 HWND focus_window
, device_window
;
916 focus_window
= create_window();
917 ddraw
= create_ddraw();
918 ok(!!ddraw
, "Failed to create a ddraw object.\n");
920 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
921 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
922 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
923 ok(!device_window
, "Unexpected device window found.\n");
924 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
925 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
926 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
927 ok(!device_window
, "Unexpected device window found.\n");
928 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
929 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
930 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
931 ok(!device_window
, "Unexpected device window found.\n");
932 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
933 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
934 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
935 ok(!device_window
, "Unexpected device window found.\n");
936 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
937 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
938 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
939 ok(!device_window
, "Unexpected device window found.\n");
941 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
942 if (broken(hr
== DDERR_INVALIDPARAMS
))
944 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
945 IDirectDraw7_Release(ddraw
);
946 DestroyWindow(focus_window
);
950 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
951 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
952 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
953 ok(!device_window
, "Unexpected device window found.\n");
954 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
955 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
956 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
957 ok(!device_window
, "Unexpected device window found.\n");
959 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
960 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
961 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
962 ok(!device_window
, "Unexpected device window found.\n");
963 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
964 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
965 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
966 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
967 ok(!!device_window
, "Device window not found.\n");
969 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
970 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
971 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
972 ok(!device_window
, "Unexpected device window found.\n");
973 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
974 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
975 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
976 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
977 ok(!!device_window
, "Device window not found.\n");
979 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
980 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
981 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
982 ok(!device_window
, "Unexpected device window found.\n");
983 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
984 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
985 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
986 ok(!device_window
, "Unexpected device window found.\n");
987 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
988 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
989 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
990 ok(!device_window
, "Unexpected device window found.\n");
991 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
992 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
993 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
994 ok(!!device_window
, "Device window not found.\n");
996 IDirectDraw7_Release(ddraw
);
997 DestroyWindow(focus_window
);
1000 static void test_clipper_blt(void)
1002 IDirectDrawSurface7
*src_surface
, *dst_surface
;
1003 RECT client_rect
, src_rect
;
1004 IDirectDrawClipper
*clipper
;
1005 DDSURFACEDESC2 surface_desc
;
1006 unsigned int i
, j
, x
, y
;
1007 IDirectDraw7
*ddraw
;
1018 static const DWORD src_data
[] =
1020 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1021 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1022 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1024 static const D3DCOLOR expected1
[] =
1026 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1027 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1028 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1029 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1031 /* Nvidia on Windows seems to have an off-by-one error
1032 * when processing source rectangles. Our left = 1 and
1033 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
1034 * read as well, but only for the edge pixels on the
1035 * output image. The bug happens on the y axis as well,
1036 * but we only read one row there, and all source rows
1037 * contain the same data. This bug is not dependent on
1038 * the presence of a clipper. */
1039 static const D3DCOLOR expected1_broken
[] =
1041 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1042 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1043 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
1044 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
1046 static const D3DCOLOR expected2
[] =
1048 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1049 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1050 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1051 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1054 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1055 10, 10, 640, 480, 0, 0, 0, 0);
1056 ShowWindow(window
, SW_SHOW
);
1057 ddraw
= create_ddraw();
1058 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1060 ret
= GetClientRect(window
, &client_rect
);
1061 ok(ret
, "Failed to get client rect.\n");
1062 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
1063 ok(ret
, "Failed to map client rect.\n");
1065 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1066 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1068 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
1069 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
1070 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1071 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1072 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1073 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1074 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1075 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1076 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1077 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
1078 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
1079 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
1080 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
1081 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
1082 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
1083 "Got unexpected bounding rect %s, expected %s.\n",
1084 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
1085 HeapFree(GetProcessHeap(), 0, rgn_data
);
1087 r1
= CreateRectRgn(0, 0, 320, 240);
1088 ok(!!r1
, "Failed to create region.\n");
1089 r2
= CreateRectRgn(320, 240, 640, 480);
1090 ok(!!r2
, "Failed to create region.\n");
1091 CombineRgn(r1
, r1
, r2
, RGN_OR
);
1092 ret
= GetRegionData(r1
, 0, NULL
);
1093 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1094 ret
= GetRegionData(r1
, ret
, rgn_data
);
1095 ok(!!ret
, "Failed to get region data.\n");
1100 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1101 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
1102 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1103 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1104 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1105 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1107 HeapFree(GetProcessHeap(), 0, rgn_data
);
1109 memset(&surface_desc
, 0, sizeof(surface_desc
));
1110 surface_desc
.dwSize
= sizeof(surface_desc
);
1111 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1112 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1113 surface_desc
.dwWidth
= 640;
1114 surface_desc
.dwHeight
= 480;
1115 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1116 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1117 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1118 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1119 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1120 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1122 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
1123 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
1124 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
1125 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1127 memset(&fx
, 0, sizeof(fx
));
1128 fx
.dwSize
= sizeof(fx
);
1129 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1130 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
1131 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1132 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
1134 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
1135 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
1136 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
1137 ptr
= surface_desc
.lpSurface
;
1138 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
1139 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
1140 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
1141 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
1142 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
1144 hr
= IDirectDrawSurface7_SetClipper(dst_surface
, clipper
);
1145 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
1147 SetRect(&src_rect
, 1, 1, 5, 2);
1148 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
1149 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
1150 for (i
= 0; i
< 4; ++i
)
1152 for (j
= 0; j
< 4; ++j
)
1154 x
= 80 * ((2 * j
) + 1);
1155 y
= 60 * ((2 * i
) + 1);
1156 color
= get_surface_color(dst_surface
, x
, y
);
1157 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1158 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1159 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1163 U5(fx
).dwFillColor
= 0xff0000ff;
1164 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1165 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
1166 for (i
= 0; i
< 4; ++i
)
1168 for (j
= 0; j
< 4; ++j
)
1170 x
= 80 * ((2 * j
) + 1);
1171 y
= 60 * ((2 * i
) + 1);
1172 color
= get_surface_color(dst_surface
, x
, y
);
1173 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1174 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1178 hr
= IDirectDrawSurface7_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1179 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
1181 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1182 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1183 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1184 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1185 DestroyWindow(window
);
1186 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1187 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
1188 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1189 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1190 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1191 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1192 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1193 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1194 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1195 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1196 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1197 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1199 IDirectDrawSurface7_Release(dst_surface
);
1200 IDirectDrawSurface7_Release(src_surface
);
1201 refcount
= IDirectDrawClipper_Release(clipper
);
1202 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
1203 IDirectDraw7_Release(ddraw
);
1206 static void test_coop_level_d3d_state(void)
1208 IDirectDrawSurface7
*rt
, *surface
;
1209 IDirect3DDevice7
*device
;
1210 IDirectDraw7
*ddraw
;
1211 DDSURFACEDESC2 lock
;
1221 struct vec3 position
;
1226 {{-1.0f
, -1.0f
, 0.1f
}, 0x800000ff},
1227 {{-1.0f
, 1.0f
, 0.1f
}, 0x800000ff},
1228 {{ 1.0f
, -1.0f
, 0.1f
}, 0x800000ff},
1229 {{ 1.0f
, 1.0f
, 0.1f
}, 0x800000ff},
1232 window
= create_window();
1233 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1235 skip("Failed to create a 3D device, skipping test.\n");
1236 DestroyWindow(window
);
1240 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1241 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1242 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1243 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1244 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
1245 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1247 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1248 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1249 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1250 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1251 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1252 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1253 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1254 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1255 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1256 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1257 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1258 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1259 color
= get_surface_color(rt
, 320, 240);
1260 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1262 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1263 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1264 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1265 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1266 IDirect3D7_Release(d3d
);
1267 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1268 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1269 hr
= IDirectDrawSurface7_IsLost(rt
);
1270 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1272 memset(&lock
, 0, sizeof(lock
));
1273 lock
.dwSize
= sizeof(lock
);
1274 lock
.lpSurface
= (void *)0xdeadbeef;
1275 hr
= IDirectDrawSurface7_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1276 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1277 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1279 memset(&caps
, 0, sizeof(caps
));
1280 caps
.dwCaps
= DDSCAPS_ZBUFFER
;
1281 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &surface
);
1282 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1283 caps
.dwCaps
= DDSCAPS_FLIP
;
1284 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &surface
);
1285 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1287 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
1288 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1290 hr
= IDirectDrawSurface7_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1291 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1292 hr
= IDirectDrawSurface7_Unlock(rt
, NULL
);
1293 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1295 caps
.dwCaps
= DDSCAPS_ZBUFFER
;
1296 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &surface
);
1297 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1298 IDirectDrawSurface7_Release(surface
);
1300 caps
.dwCaps
= DDSCAPS_FLIP
;
1301 hr
= IDirectDrawSurface7_GetAttachedSurface(rt
, &caps
, &surface
);
1302 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
1304 IDirectDraw7_Release(ddraw
);
1306 hr
= IDirect3DDevice7_GetRenderTarget(device
, &surface
);
1307 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1308 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1309 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1310 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1311 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1312 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1313 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1314 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1315 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
1316 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1317 color
= get_surface_color(rt
, 320, 240);
1318 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1320 hr
= IDirect3DDevice7_BeginScene(device
);
1321 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1322 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
1323 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
1324 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1325 hr
= IDirect3DDevice7_EndScene(device
);
1326 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1327 color
= get_surface_color(rt
, 320, 240);
1328 ok(compare_color(color
, 0x0000ff80, 1), "Got unexpected color 0x%08x.\n", color
);
1330 IDirectDrawSurface7_Release(surface
);
1331 IDirectDrawSurface7_Release(rt
);
1332 IDirect3DDevice7_Release(device
);
1333 DestroyWindow(window
);
1336 static void test_surface_interface_mismatch(void)
1338 IDirectDraw7
*ddraw
= NULL
;
1339 IDirect3D7
*d3d
= NULL
;
1340 IDirectDrawSurface7
*surface
= NULL
, *ds
;
1341 IDirectDrawSurface3
*surface3
= NULL
;
1342 IDirect3DDevice7
*device
= NULL
;
1343 DDSURFACEDESC2 surface_desc
;
1344 DDPIXELFORMAT z_fmt
;
1350 window
= create_window();
1351 ddraw
= create_ddraw();
1352 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1353 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1354 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1356 memset(&surface_desc
, 0, sizeof(surface_desc
));
1357 surface_desc
.dwSize
= sizeof(surface_desc
);
1358 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1359 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1360 surface_desc
.dwWidth
= 640;
1361 surface_desc
.dwHeight
= 480;
1363 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1364 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1366 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1367 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
1369 if (FAILED(IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
)))
1371 skip("D3D interface is not available, skipping test.\n");
1375 memset(&z_fmt
, 0, sizeof(z_fmt
));
1376 hr
= IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
1377 if (FAILED(hr
) || !z_fmt
.dwSize
)
1379 skip("No depth buffer formats available, skipping test.\n");
1383 memset(&surface_desc
, 0, sizeof(surface_desc
));
1384 surface_desc
.dwSize
= sizeof(surface_desc
);
1385 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
1386 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1387 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
1388 surface_desc
.dwWidth
= 640;
1389 surface_desc
.dwHeight
= 480;
1390 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1391 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1395 /* Using a different surface interface version still works */
1396 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1397 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1398 refcount
= IDirectDrawSurface7_Release(ds
);
1399 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1404 hr
= IDirect3D7_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface7
*)surface3
, &device
);
1405 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1409 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1410 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
1411 color
= get_surface_color(surface
, 320, 240);
1412 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1415 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1416 if (surface
) IDirectDrawSurface7_Release(surface
);
1417 if (device
) IDirect3DDevice7_Release(device
);
1418 if (d3d
) IDirect3D7_Release(d3d
);
1419 if (ddraw
) IDirectDraw7_Release(ddraw
);
1420 DestroyWindow(window
);
1423 static void test_coop_level_threaded(void)
1425 struct create_window_thread_param p
;
1426 IDirectDraw7
*ddraw
;
1429 ddraw
= create_ddraw();
1430 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1431 create_window_thread(&p
);
1433 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1434 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1436 destroy_window_thread(&p
);
1437 IDirectDraw7_Release(ddraw
);
1440 static void test_depth_blit(const GUID
*device_guid
)
1442 IDirect3DDevice7
*device
;
1450 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1451 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1452 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1453 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1455 static const D3DCOLOR expected_colors
[4][4] =
1457 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1458 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1459 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1460 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1462 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1464 IDirectDrawSurface7
*ds1
, *ds2
, *ds3
, *rt
;
1465 RECT src_rect
, dst_rect
;
1470 IDirectDraw7
*ddraw
;
1474 window
= create_window();
1475 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
1477 skip("Failed to create a 3D device, skipping test.\n");
1478 DestroyWindow(window
);
1482 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1483 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1484 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1485 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1486 IDirect3D7_Release(d3d
);
1488 ds1
= get_depth_stencil(device
);
1490 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1491 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1492 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1493 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1494 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds1
, &ddsd_existing
);
1495 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1496 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1497 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1498 if (is_software_device_type(device_guid
))
1499 ddsd_new
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1500 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1501 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1502 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1503 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1504 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1505 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1506 ok(SUCCEEDED(hr
), "Failed to create a z buffer, hr %#x.\n", hr
);
1507 IDirectDraw7_Release(ddraw
);
1509 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1510 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1511 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1512 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1513 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
1514 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
1516 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1517 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1520 SetRect(&src_rect
, 0, 0, 320, 240);
1521 SetRect(&dst_rect
, 0, 0, 320, 240);
1522 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1523 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1524 /* Different locations. */
1525 SetRect(&src_rect
, 0, 0, 320, 240);
1526 SetRect(&dst_rect
, 320, 240, 640, 480);
1527 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1528 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1530 SetRect(&src_rect
, 0, 0, 320, 240);
1531 SetRect(&dst_rect
, 0, 0, 640, 480);
1532 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1533 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1535 SetRect(&src_rect
, 0, 480, 640, 0);
1536 SetRect(&dst_rect
, 0, 0, 640, 480);
1537 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1538 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1539 SetRect(&src_rect
, 0, 0, 640, 480);
1540 SetRect(&dst_rect
, 0, 480, 640, 0);
1541 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1542 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1543 /* Full, explicit. */
1544 SetRect(&src_rect
, 0, 0, 640, 480);
1545 SetRect(&dst_rect
, 0, 0, 640, 480);
1546 hr
= IDirectDrawSurface7_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1547 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1548 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1550 /* Depth blit inside a BeginScene / EndScene pair */
1551 hr
= IDirect3DDevice7_BeginScene(device
);
1552 ok(SUCCEEDED(hr
), "Failed to start scene, hr %#x.\n", hr
);
1553 /* From the current depth stencil */
1554 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1555 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1556 /* To the current depth stencil */
1557 hr
= IDirectDrawSurface7_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1558 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1559 /* Between unbound surfaces */
1560 hr
= IDirectDrawSurface7_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1561 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1562 hr
= IDirect3DDevice7_EndScene(device
);
1563 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1565 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1566 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1567 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1568 * a reliable result(z = 0.0) */
1569 memset(&fx
, 0, sizeof(fx
));
1570 fx
.dwSize
= sizeof(fx
);
1571 hr
= IDirectDrawSurface7_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1572 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1574 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1575 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1577 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1578 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1579 color
= get_surface_color(rt
, 80, 60);
1581 /* For some reason clears and colour fill blits randomly fail with software render target. */
1582 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1583 "Got unexpected colour 0x%08x.\n", color
);
1586 fill_surface(rt
, 0xffff0000);
1588 color
= get_surface_color(rt
, 80, 60);
1589 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1592 SetRect(&dst_rect
, 0, 0, 320, 240);
1593 hr
= IDirectDrawSurface7_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1594 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1595 IDirectDrawSurface7_Release(ds3
);
1596 IDirectDrawSurface7_Release(ds2
);
1597 IDirectDrawSurface7_Release(ds1
);
1599 hr
= IDirect3DDevice7_BeginScene(device
);
1600 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1601 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1603 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1604 hr
= IDirect3DDevice7_EndScene(device
);
1605 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1607 for (i
= 0; i
< 4; ++i
)
1609 for (j
= 0; j
< 4; ++j
)
1611 unsigned int x
= 80 * ((2 * j
) + 1);
1612 unsigned int y
= 60 * ((2 * i
) + 1);
1613 color
= get_surface_color(rt
, x
, y
);
1614 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1615 "Expected color 0x%08x at %u,%u, got 0x%08x, software device %#x.\n",
1616 expected_colors
[i
][j
], x
, y
, color
, is_software_device_type(device_guid
));
1620 IDirectDrawSurface7_Release(rt
);
1621 IDirect3DDevice7_Release(device
);
1622 DestroyWindow(window
);
1625 static void test_texture_load_ckey(void)
1628 IDirect3DDevice7
*device
;
1629 IDirectDraw7
*ddraw
;
1630 IDirectDrawSurface7
*src
;
1631 IDirectDrawSurface7
*dst
;
1632 DDSURFACEDESC2 ddsd
;
1637 window
= create_window();
1638 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1640 skip("Failed to create a 3D device, skipping test.\n");
1641 DestroyWindow(window
);
1645 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1646 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
1647 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1648 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
1649 IDirect3D7_Release(d3d
);
1651 memset(&ddsd
, 0, sizeof(ddsd
));
1652 ddsd
.dwSize
= sizeof(ddsd
);
1653 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1654 ddsd
.dwHeight
= 128;
1656 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1657 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1658 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1659 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1660 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1661 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1663 /* No surface has a color key */
1664 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1665 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1666 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1667 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1668 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1669 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1670 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1672 /* Source surface has a color key */
1673 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1674 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1675 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1676 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1677 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1678 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1679 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1680 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1681 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1683 /* Both surfaces have a color key: Dest ckey is overwritten */
1684 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1685 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1686 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1687 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1688 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1689 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1690 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1691 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1692 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1694 /* Only the destination has a color key: It is deleted. This behavior differs from
1695 * IDirect3DTexture(2)::Load */
1696 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1697 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1698 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1699 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1700 hr
= IDirect3DDevice7_Load(device
, dst
, NULL
, src
, NULL
, 0);
1701 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1702 hr
= IDirectDrawSurface7_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1703 todo_wine
ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1705 IDirectDrawSurface7_Release(dst
);
1706 IDirectDrawSurface7_Release(src
);
1707 IDirectDraw7_Release(ddraw
);
1708 IDirect3DDevice7_Release(device
);
1709 DestroyWindow(window
);
1712 static void test_zenable(const GUID
*device_guid
)
1716 struct vec4 position
;
1721 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1722 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1723 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1724 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1726 IDirect3DDevice7
*device
;
1727 IDirectDrawSurface7
*rt
;
1734 window
= create_window();
1735 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
1737 skip("Failed to create a 3D device, skipping test.\n");
1738 DestroyWindow(window
);
1742 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1743 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1745 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1746 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1748 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1749 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1751 color
= get_surface_color(rt
, 80, 60);
1752 /* For some reason clears and colour fill blits randomly fail with software render target. */
1753 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1754 "Got unexpected colour 0x%08x.\n", color
);
1757 fill_surface(rt
, 0xffff0000);
1759 color
= get_surface_color(rt
, 80, 60);
1760 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1763 hr
= IDirect3DDevice7_BeginScene(device
);
1764 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1765 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1766 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1767 hr
= IDirect3DDevice7_EndScene(device
);
1768 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1770 for (i
= 0; i
< 4; ++i
)
1772 for (j
= 0; j
< 4; ++j
)
1774 x
= 80 * ((2 * j
) + 1);
1775 y
= 60 * ((2 * i
) + 1);
1776 color
= get_surface_color(rt
, x
, y
);
1777 ok(compare_color(color
, 0x0000ff00, 1),
1778 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1781 IDirectDrawSurface7_Release(rt
);
1783 IDirect3DDevice7_Release(device
);
1784 DestroyWindow(window
);
1787 static void test_ck_rgba(const GUID
*device_guid
)
1791 struct vec4 position
;
1792 struct vec2 texcoord
;
1796 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1797 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1798 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1799 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1800 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1801 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1802 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1803 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1807 D3DCOLOR fill_color
;
1810 D3DCOLOR result1
, result1_broken
;
1811 D3DCOLOR result2
, result2_broken
;
1815 /* r200 on Windows doesn't check the alpha component when applying the color
1816 * key, so the key matches on every texel. */
1817 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1818 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1819 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1820 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1821 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1822 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1823 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1824 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1827 IDirectDrawSurface7
*texture
;
1828 DDSURFACEDESC2 surface_desc
;
1829 IDirect3DDevice7
*device
;
1830 IDirectDrawSurface7
*rt
;
1831 IDirectDraw7
*ddraw
;
1839 window
= create_window();
1840 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
1842 skip("Failed to create a 3D device, skipping test.\n");
1843 DestroyWindow(window
);
1847 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1848 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1849 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1850 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1851 IDirect3D7_Release(d3d
);
1853 memset(&surface_desc
, 0, sizeof(surface_desc
));
1854 surface_desc
.dwSize
= sizeof(surface_desc
);
1855 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1856 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1857 if (is_software_device_type(device_guid
))
1858 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1859 surface_desc
.dwWidth
= 256;
1860 surface_desc
.dwHeight
= 256;
1861 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1862 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1863 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1864 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1865 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1866 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1867 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1868 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1869 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1870 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
1871 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1873 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
1874 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1875 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1876 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1877 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1878 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1880 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1881 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1883 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1885 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1886 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1887 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1888 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1890 memset(&fx
, 0, sizeof(fx
));
1891 fx
.dwSize
= sizeof(fx
);
1892 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1893 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1894 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1896 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1897 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1898 /* RT clears are broken on Windows for software render target. */
1899 if (is_software_device_type(device_guid
))
1900 fill_surface(rt
, 0xffff0000);
1902 hr
= IDirect3DDevice7_BeginScene(device
);
1903 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1904 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1905 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1906 hr
= IDirect3DDevice7_EndScene(device
);
1907 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1909 color
= get_surface_color(rt
, 320, 240);
1910 ok(compare_color(color
, tests
[i
].result1
, 2) || compare_color(color
, tests
[i
].result1_broken
, 1),
1911 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1912 tests
[i
].result1
, i
, color
);
1914 U5(fx
).dwFillColor
= 0xff0000ff;
1915 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1916 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
1918 hr
= IDirect3DDevice7_BeginScene(device
);
1919 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1920 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1921 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1922 hr
= IDirect3DDevice7_EndScene(device
);
1923 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1925 /* This tests that fragments that are masked out by the color key are
1926 * discarded, instead of just fully transparent. */
1927 color
= get_surface_color(rt
, 320, 240);
1928 ok(compare_color(color
, tests
[i
].result2
, 2) || compare_color(color
, tests
[i
].result2_broken
, 1),
1929 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1930 tests
[i
].result2
, i
, color
);
1933 IDirectDrawSurface7_Release(rt
);
1934 IDirectDrawSurface7_Release(texture
);
1935 IDirectDraw7_Release(ddraw
);
1936 IDirect3DDevice7_Release(device
);
1937 DestroyWindow(window
);
1940 static void test_ck_default(void)
1944 struct vec4 position
;
1945 struct vec2 texcoord
;
1949 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
1950 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
1951 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
1952 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
1954 IDirectDrawSurface7
*surface
, *rt
;
1955 DDSURFACEDESC2 surface_desc
;
1956 IDirect3DDevice7
*device
;
1957 IDirectDraw7
*ddraw
;
1965 window
= create_window();
1966 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1968 skip("Failed to create a 3D device, skipping test.\n");
1969 DestroyWindow(window
);
1973 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
1974 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1975 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
1976 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1977 IDirect3D7_Release(d3d
);
1979 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
1980 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1982 memset(&surface_desc
, 0, sizeof(surface_desc
));
1983 surface_desc
.dwSize
= sizeof(surface_desc
);
1984 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1985 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1986 surface_desc
.dwWidth
= 256;
1987 surface_desc
.dwHeight
= 256;
1988 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1989 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1990 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1991 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1992 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1993 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1994 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1995 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1996 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1997 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1998 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
1999 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2001 memset(&fx
, 0, sizeof(fx
));
2002 fx
.dwSize
= sizeof(fx
);
2003 U5(fx
).dwFillColor
= 0x000000ff;
2004 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2005 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
2007 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2008 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
2009 hr
= IDirect3DDevice7_BeginScene(device
);
2010 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2011 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2012 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2013 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
2014 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2015 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2016 hr
= IDirect3DDevice7_EndScene(device
);
2017 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2018 color
= get_surface_color(rt
, 320, 240);
2019 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2021 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2022 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
2023 hr
= IDirect3DDevice7_BeginScene(device
);
2024 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2025 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2026 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
2027 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2028 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2029 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2030 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2031 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
2032 hr
= IDirect3DDevice7_EndScene(device
);
2033 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2034 color
= get_surface_color(rt
, 320, 240);
2035 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2037 IDirectDrawSurface7_Release(surface
);
2038 IDirectDrawSurface7_Release(rt
);
2039 IDirect3DDevice7_Release(device
);
2040 IDirectDraw7_Release(ddraw
);
2041 DestroyWindow(window
);
2044 static void test_ck_complex(void)
2046 IDirectDrawSurface7
*surface
, *mipmap
, *tmp
;
2047 D3DDEVICEDESC7 device_desc
;
2048 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
2049 DDSURFACEDESC2 surface_desc
;
2050 IDirect3DDevice7
*device
;
2051 DDCOLORKEY color_key
;
2052 IDirectDraw7
*ddraw
;
2059 window
= create_window();
2060 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2062 skip("Failed to create a 3D device, skipping test.\n");
2063 DestroyWindow(window
);
2066 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
2067 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
2068 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
2069 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2070 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
2071 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
2072 IDirect3D7_Release(d3d
);
2074 memset(&surface_desc
, 0, sizeof(surface_desc
));
2075 surface_desc
.dwSize
= sizeof(surface_desc
);
2076 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2077 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2078 surface_desc
.dwWidth
= 128;
2079 surface_desc
.dwHeight
= 128;
2080 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2081 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2083 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2084 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2085 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2086 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2087 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2088 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2089 memset(&color_key
, 0, sizeof(color_key
));
2090 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2091 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2092 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2093 color_key
.dwColorSpaceLowValue
);
2094 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2095 color_key
.dwColorSpaceHighValue
);
2098 IDirectDrawSurface_AddRef(mipmap
);
2099 for (i
= 0; i
< 7; ++i
)
2101 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2102 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2103 hr
= IDirectDrawSurface7_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2104 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2106 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2107 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2108 hr
= IDirectDrawSurface7_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2109 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2111 IDirectDrawSurface_Release(mipmap
);
2115 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2116 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2117 IDirectDrawSurface_Release(mipmap
);
2118 refcount
= IDirectDrawSurface7_Release(surface
);
2119 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2121 memset(&surface_desc
, 0, sizeof(surface_desc
));
2122 surface_desc
.dwSize
= sizeof(surface_desc
);
2123 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2124 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2125 U5(surface_desc
).dwBackBufferCount
= 1;
2126 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2127 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2129 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2130 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2131 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2132 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2133 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2134 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2135 memset(&color_key
, 0, sizeof(color_key
));
2136 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2137 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2138 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2139 color_key
.dwColorSpaceLowValue
);
2140 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2141 color_key
.dwColorSpaceHighValue
);
2143 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &tmp
);
2144 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2146 hr
= IDirectDrawSurface7_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2147 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2148 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2149 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2150 hr
= IDirectDrawSurface7_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2151 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2152 memset(&color_key
, 0, sizeof(color_key
));
2153 hr
= IDirectDrawSurface7_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2154 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2155 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2156 color_key
.dwColorSpaceLowValue
);
2157 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2158 color_key
.dwColorSpaceHighValue
);
2160 IDirectDrawSurface_Release(tmp
);
2162 refcount
= IDirectDrawSurface7_Release(surface
);
2163 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2165 if (!(device_desc
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
))
2167 skip("Device does not support cubemaps.\n");
2170 memset(&surface_desc
, 0, sizeof(surface_desc
));
2171 surface_desc
.dwSize
= sizeof(surface_desc
);
2172 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2173 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2174 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
2175 surface_desc
.dwWidth
= 128;
2176 surface_desc
.dwHeight
= 128;
2177 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2178 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2180 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2181 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2182 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2183 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2184 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2185 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2187 caps
.dwCaps2
= DDSCAPS2_CUBEMAP_NEGATIVEZ
;
2188 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
2189 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2191 hr
= IDirectDrawSurface7_GetColorKey(mipmap
, DDCKEY_SRCBLT
, &color_key
);
2192 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2193 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2194 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2195 hr
= IDirectDrawSurface7_SetColorKey(mipmap
, DDCKEY_SRCBLT
, &color_key
);
2196 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2198 color_key
.dwColorSpaceLowValue
= 0;
2199 color_key
.dwColorSpaceHighValue
= 0;
2200 hr
= IDirectDrawSurface7_GetColorKey(mipmap
, DDCKEY_SRCBLT
, &color_key
);
2201 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2202 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x.\n",
2203 color_key
.dwColorSpaceLowValue
);
2204 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x.\n",
2205 color_key
.dwColorSpaceHighValue
);
2207 IDirectDrawSurface_AddRef(mipmap
);
2208 for (i
= 0; i
< 7; ++i
)
2210 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2211 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2212 hr
= IDirectDrawSurface7_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2213 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2215 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2216 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2217 hr
= IDirectDrawSurface7_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2218 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2220 IDirectDrawSurface_Release(mipmap
);
2224 IDirectDrawSurface7_Release(mipmap
);
2226 refcount
= IDirectDrawSurface7_Release(surface
);
2227 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2230 IDirectDraw7_Release(ddraw
);
2231 refcount
= IDirect3DDevice7_Release(device
);
2232 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2233 DestroyWindow(window
);
2239 REFIID refcount_iid
;
2243 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2244 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2246 ULONG refcount
, expected_refcount
;
2247 IUnknown
*iface1
, *iface2
;
2251 for (i
= 0; i
< entry_count
; ++i
)
2253 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2254 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2257 for (j
= 0; j
< entry_count
; ++j
)
2259 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2260 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2263 expected_refcount
= 0;
2264 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2265 ++expected_refcount
;
2266 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2267 ++expected_refcount
;
2268 refcount
= IUnknown_Release(iface2
);
2269 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2270 refcount
, test_name
, i
, j
, expected_refcount
);
2274 expected_refcount
= 0;
2275 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2276 ++expected_refcount
;
2277 refcount
= IUnknown_Release(iface1
);
2278 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2279 refcount
, test_name
, i
, expected_refcount
);
2284 static void test_surface_qi(void)
2286 static const struct qi_test tests
[] =
2288 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2289 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2290 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2291 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2292 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2293 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2294 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2295 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2296 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2297 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2298 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2299 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
2300 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
2301 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2302 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2303 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2304 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2305 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2306 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2307 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2308 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2309 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2310 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2311 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2312 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2313 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2314 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2315 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2316 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2317 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2318 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2319 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2320 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2321 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2322 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2323 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2324 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2325 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2326 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2327 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2328 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2329 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2330 {NULL
, NULL
, E_INVALIDARG
},
2333 IDirectDrawSurface7
*surface
;
2334 DDSURFACEDESC2 surface_desc
;
2335 IDirect3DDevice7
*device
;
2336 IDirectDraw7
*ddraw
;
2340 window
= create_window();
2341 /* Try to create a D3D device to see if the ddraw implementation supports
2342 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2343 * doesn't support e.g. the IDirect3DTexture interfaces. */
2344 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2346 skip("Failed to create a 3D device, skipping test.\n");
2347 DestroyWindow(window
);
2350 IDirect3DDevice_Release(device
);
2351 ddraw
= create_ddraw();
2352 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2353 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2354 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2356 memset(&surface_desc
, 0, sizeof(surface_desc
));
2357 surface_desc
.dwSize
= sizeof(surface_desc
);
2358 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2359 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2360 surface_desc
.dwWidth
= 512;
2361 surface_desc
.dwHeight
= 512;
2362 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface7
**)0xdeadbeef, NULL
);
2363 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2364 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2365 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2367 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface7
, tests
, ARRAY_SIZE(tests
));
2369 IDirectDrawSurface7_Release(surface
);
2370 IDirectDraw7_Release(ddraw
);
2371 DestroyWindow(window
);
2374 static void test_device_qi(void)
2376 static const struct qi_test tests
[] =
2378 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2379 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2380 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2381 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2382 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2383 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2384 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2385 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2386 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2387 {&IID_IDirect3DDevice7
, &IID_IDirect3DDevice7
, S_OK
},
2388 {&IID_IDirect3DDevice3
, NULL
, E_NOINTERFACE
},
2389 {&IID_IDirect3DDevice2
, NULL
, E_NOINTERFACE
},
2390 {&IID_IDirect3DDevice
, NULL
, E_NOINTERFACE
},
2391 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2392 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2393 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2394 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2395 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2396 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2397 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2398 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2399 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2400 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2401 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2402 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2403 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2404 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2405 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2406 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2407 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2408 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2409 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2410 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2411 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2412 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2413 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2414 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2415 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2416 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2417 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2418 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2419 {&IID_IUnknown
, &IID_IDirect3DDevice7
, S_OK
},
2422 IDirect3DDevice7
*device
;
2425 window
= create_window();
2426 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2428 skip("Failed to create a 3D device, skipping test.\n");
2429 DestroyWindow(window
);
2433 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice7
, tests
, ARRAY_SIZE(tests
));
2435 IDirect3DDevice7_Release(device
);
2436 DestroyWindow(window
);
2439 static void test_wndproc(void)
2441 LONG_PTR proc
, ddraw_proc
;
2442 IDirectDraw7
*ddraw
;
2448 static struct message messages
[] =
2450 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2451 {WM_MOVE
, FALSE
, 0},
2452 {WM_SIZE
, FALSE
, 0},
2453 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2454 {WM_ACTIVATE
, FALSE
, 0},
2455 {WM_SETFOCUS
, FALSE
, 0},
2459 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2460 ddraw
= create_ddraw();
2461 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2463 wc
.lpfnWndProc
= test_proc
;
2464 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2465 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2467 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2468 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2470 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2471 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2472 (LONG_PTR
)test_proc
, proc
);
2473 expect_messages
= messages
;
2474 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2475 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2476 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2477 expect_messages
= NULL
;
2478 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2479 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2480 (LONG_PTR
)test_proc
, proc
);
2481 ref
= IDirectDraw7_Release(ddraw
);
2482 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2483 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2484 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2485 (LONG_PTR
)test_proc
, proc
);
2487 /* DDSCL_NORMAL doesn't. */
2488 ddraw
= create_ddraw();
2489 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2490 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2491 (LONG_PTR
)test_proc
, proc
);
2492 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2493 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2494 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2495 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2496 (LONG_PTR
)test_proc
, proc
);
2497 ref
= IDirectDraw7_Release(ddraw
);
2498 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2499 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2500 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2501 (LONG_PTR
)test_proc
, proc
);
2503 /* The original window proc is only restored by ddraw if the current
2504 * window proc matches the one ddraw set. This also affects switching
2505 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2506 ddraw
= create_ddraw();
2507 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2508 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2509 (LONG_PTR
)test_proc
, proc
);
2510 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2511 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2512 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2513 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2514 (LONG_PTR
)test_proc
, proc
);
2516 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2517 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2518 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2519 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2520 (LONG_PTR
)test_proc
, proc
);
2521 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2522 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2523 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2524 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2525 (LONG_PTR
)test_proc
, proc
);
2526 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2527 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2528 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2529 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2530 (LONG_PTR
)DefWindowProcA
, proc
);
2531 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2532 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2533 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2534 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2535 (LONG_PTR
)DefWindowProcA
, proc
);
2536 ref
= IDirectDraw7_Release(ddraw
);
2537 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2538 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2539 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2540 (LONG_PTR
)test_proc
, proc
);
2542 ddraw
= create_ddraw();
2543 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2544 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2545 (LONG_PTR
)test_proc
, proc
);
2546 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2547 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2548 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2549 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2550 (LONG_PTR
)test_proc
, proc
);
2551 ref
= IDirectDraw7_Release(ddraw
);
2552 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2553 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2554 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2555 (LONG_PTR
)DefWindowProcA
, proc
);
2557 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2558 expect_messages
= NULL
;
2559 DestroyWindow(window
);
2560 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2563 static void test_window_style(void)
2565 LONG style
, exstyle
, tmp
, expected_style
;
2566 RECT fullscreen_rect
, r
;
2567 HWND window
, window2
;
2568 IDirectDraw7
*ddraw
;
2573 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2574 0, 0, 100, 100, 0, 0, 0, 0);
2575 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2576 0, 0, 50, 50, 0, 0, 0, 0);
2577 ddraw
= create_ddraw();
2578 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2580 style
= GetWindowLongA(window
, GWL_STYLE
);
2581 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2582 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2584 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2585 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2587 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2588 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2589 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2590 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2592 GetWindowRect(window
, &r
);
2593 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2594 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2595 GetClientRect(window
, &r
);
2596 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2598 ret
= SetForegroundWindow(GetDesktopWindow());
2599 ok(ret
, "Failed to set foreground window.\n");
2601 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2602 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2603 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2604 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2606 ret
= SetForegroundWindow(window
);
2607 ok(ret
, "Failed to set foreground window.\n");
2608 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2609 * the next tests expect this. */
2610 ShowWindow(window
, SW_HIDE
);
2612 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2613 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2615 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2616 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2617 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2618 ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2620 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2621 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2623 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2624 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2625 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2626 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2628 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2629 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2631 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2632 expected_style
= style
| WS_VISIBLE
;
2633 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2634 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2635 expected_style
= exstyle
| WS_EX_TOPMOST
;
2636 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2638 ShowWindow(window
, SW_HIDE
);
2639 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2640 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2641 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2642 expected_style
= exstyle
| WS_EX_TOPMOST
;
2643 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2645 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2646 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2648 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2649 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2650 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2651 expected_style
= exstyle
| WS_EX_TOPMOST
;
2652 ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2654 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2655 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2657 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2658 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2659 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2660 expected_style
= exstyle
| WS_EX_TOPMOST
;
2661 ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2663 ret
= SetForegroundWindow(window
);
2664 ok(ret
, "Failed to set foreground window.\n");
2666 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2667 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2669 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2670 expected_style
= style
| WS_VISIBLE
;
2671 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2672 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2673 expected_style
= exstyle
| WS_EX_TOPMOST
;
2674 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2676 ShowWindow(window
, SW_HIDE
);
2677 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2678 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2680 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2681 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2682 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2683 ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2685 ShowWindow(window
, SW_SHOW
);
2686 ret
= SetForegroundWindow(GetDesktopWindow());
2687 ok(ret
, "Failed to set foreground window.\n");
2688 SetActiveWindow(window
);
2689 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
2690 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2691 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2693 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2694 expected_style
= style
| WS_VISIBLE
;
2695 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2696 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2697 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2699 GetWindowRect(window
, &r
);
2700 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2701 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2703 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2704 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2706 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
2707 GetWindowRect(window
, &r
);
2708 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
2709 wine_dbgstr_rect(&r
));
2711 ret
= SetForegroundWindow(window2
);
2712 ok(ret
, "Failed to set foreground window.\n");
2713 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2714 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2716 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2717 expected_style
= style
| WS_VISIBLE
;
2718 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2719 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2720 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2722 GetWindowRect(window
, &r
);
2723 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2724 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2726 ret
= SetForegroundWindow(window
);
2727 ok(ret
, "Failed to set foreground window.\n");
2728 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2729 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2731 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2732 expected_style
= style
| WS_VISIBLE
;
2733 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2734 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2735 expected_style
= exstyle
| WS_EX_TOPMOST
;
2736 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2738 ShowWindow(window
, SW_HIDE
);
2739 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2740 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2742 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2743 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2744 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2745 ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2747 ShowWindow(window
, SW_SHOW
);
2748 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2749 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2751 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2752 expected_style
= style
| WS_VISIBLE
;
2753 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2754 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2755 expected_style
= exstyle
| WS_EX_TOPMOST
;
2756 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2758 ret
= SetForegroundWindow(GetDesktopWindow());
2759 ok(ret
, "Failed to set foreground window.\n");
2760 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2761 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2762 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2763 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2764 expected_style
= exstyle
| WS_EX_TOPMOST
;
2765 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2767 ref
= IDirectDraw7_Release(ddraw
);
2768 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2770 DestroyWindow(window2
);
2771 DestroyWindow(window
);
2774 static void test_redundant_mode_set(void)
2776 DDSURFACEDESC2 surface_desc
= {0};
2777 IDirectDraw7
*ddraw
;
2783 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2784 0, 0, 100, 100, 0, 0, 0, 0);
2785 ddraw
= create_ddraw();
2786 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2787 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2788 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2790 surface_desc
.dwSize
= sizeof(surface_desc
);
2791 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
2792 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2794 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2795 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2796 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2798 GetWindowRect(window
, &q
);
2802 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2803 GetWindowRect(window
, &s
);
2804 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2806 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2807 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2808 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2810 GetWindowRect(window
, &s
);
2811 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2812 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2814 ref
= IDirectDraw7_Release(ddraw
);
2815 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2817 DestroyWindow(window
);
2820 static SIZE screen_size
, screen_size2
;
2822 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2824 if (message
== WM_SIZE
)
2826 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2827 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2830 return test_proc(hwnd
, message
, wparam
, lparam
);
2833 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2835 if (message
== WM_SIZE
)
2837 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2838 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2841 return test_proc(hwnd
, message
, wparam
, lparam
);
2844 struct test_coop_level_mode_set_enum_param
2846 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2849 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
2851 struct test_coop_level_mode_set_enum_param
*param
= context
;
2853 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2854 return DDENUMRET_OK
;
2855 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2856 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2857 return DDENUMRET_OK
;
2859 if (!param
->ddraw_width
)
2861 param
->ddraw_width
= surface_desc
->dwWidth
;
2862 param
->ddraw_height
= surface_desc
->dwHeight
;
2863 return DDENUMRET_OK
;
2865 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2866 return DDENUMRET_OK
;
2868 param
->user32_width
= surface_desc
->dwWidth
;
2869 param
->user32_height
= surface_desc
->dwHeight
;
2870 return DDENUMRET_CANCEL
;
2873 static void test_coop_level_mode_set(void)
2875 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2876 unsigned int display_count
= 0;
2877 IDirectDrawSurface7
*primary
;
2878 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2879 IDirectDraw7
*ddraw
;
2880 DDSURFACEDESC2 ddsd
;
2882 HWND window
, window2
;
2886 struct test_coop_level_mode_set_enum_param param
;
2890 static const struct message exclusive_messages
[] =
2892 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2893 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2894 {WM_SIZE
, FALSE
, 0},
2895 {WM_DISPLAYCHANGE
, FALSE
, 0},
2898 static const struct message exclusive_focus_loss_messages
[] =
2900 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
, DD_OK
},
2901 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DD_OK
}, /* Window resize due to mode change. */
2902 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DD_OK
},
2903 {WM_SIZE
, TRUE
, SIZE_RESTORED
, DD_OK
}, /* Generated by DefWindowProc. */
2904 {WM_DISPLAYCHANGE
, FALSE
, 0, DD_OK
},
2905 {WM_KILLFOCUS
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2906 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
}, /* Window minimized. */
2907 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2908 * SW_MINIMIZED, causing a recursive window activation that does not
2909 * produce the same result in Wine yet. Ignore the difference for now.
2910 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2911 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2912 {WM_MOVE
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2913 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
, DDERR_NOEXCLUSIVEMODE
},
2914 {WM_ACTIVATEAPP
, TRUE
, FALSE
, DDERR_NOEXCLUSIVEMODE
},
2917 static const struct message exclusive_focus_restore_messages
[] =
2919 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2920 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2921 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2922 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2923 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2924 /* Native redundantly sets the window size here. */
2925 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2926 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2927 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2928 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2931 static const struct message sc_restore_messages
[] =
2933 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2934 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2935 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2936 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2939 static const struct message sc_minimize_messages
[] =
2941 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2942 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2943 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2944 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2947 static const struct message sc_maximize_messages
[] =
2949 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2950 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2951 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2952 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2956 static const struct message normal_messages
[] =
2958 {WM_DISPLAYCHANGE
, FALSE
, 0},
2962 memset(&devmode
, 0, sizeof(devmode
));
2963 devmode
.dmSize
= sizeof(devmode
);
2964 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2965 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2966 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2967 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
2968 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2969 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2971 ret
= save_display_modes(&original_modes
, &display_count
);
2972 ok(ret
, "Failed to save original display modes.\n");
2974 ddraw
= create_ddraw();
2975 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2977 memset(¶m
, 0, sizeof(param
));
2978 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2979 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2980 ref
= IDirectDraw7_Release(ddraw
);
2981 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2983 if (!param
.user32_height
)
2985 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2986 heap_free(original_modes
);
2990 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2991 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2992 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2994 memset(&devmode
, 0, sizeof(devmode
));
2995 devmode
.dmSize
= sizeof(devmode
);
2996 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2997 devmode
.dmPelsWidth
= param
.user32_width
;
2998 devmode
.dmPelsHeight
= param
.user32_height
;
2999 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3000 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3002 ddraw
= create_ddraw();
3003 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3005 wc
.lpfnWndProc
= mode_set_proc
;
3006 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3007 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3008 wc
.lpfnWndProc
= mode_set_proc2
;
3009 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
3010 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3012 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3013 0, 0, 100, 100, 0, 0, 0, 0);
3014 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3015 0, 0, 100, 100, 0, 0, 0, 0);
3017 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3018 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3020 GetWindowRect(window
, &r
);
3021 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3022 wine_dbgstr_rect(&r
));
3024 memset(&ddsd
, 0, sizeof(ddsd
));
3025 ddsd
.dwSize
= sizeof(ddsd
);
3026 ddsd
.dwFlags
= DDSD_CAPS
;
3027 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3029 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3030 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3031 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3032 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3033 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
3034 param
.user32_width
, ddsd
.dwWidth
);
3035 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
3036 param
.user32_height
, ddsd
.dwHeight
);
3038 GetWindowRect(window
, &r
);
3039 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3040 wine_dbgstr_rect(&r
));
3042 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3043 expect_messages
= exclusive_messages
;
3047 hr
= IDirectDrawSurface7_IsLost(primary
);
3048 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3049 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3050 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3051 hr
= IDirectDrawSurface7_IsLost(primary
);
3052 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3054 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3055 expect_messages
= NULL
;
3056 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3057 "Expected screen size %ux%u, got %ux%u.\n",
3058 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3060 GetWindowRect(window
, &r
);
3061 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3062 wine_dbgstr_rect(&r
));
3064 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3065 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3066 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
3067 param
.user32_width
, ddsd
.dwWidth
);
3068 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
3069 param
.user32_height
, ddsd
.dwHeight
);
3070 IDirectDrawSurface7_Release(primary
);
3072 memset(&ddsd
, 0, sizeof(ddsd
));
3073 ddsd
.dwSize
= sizeof(ddsd
);
3074 ddsd
.dwFlags
= DDSD_CAPS
;
3075 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3077 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3078 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3079 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3080 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3081 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3082 param
.ddraw_width
, ddsd
.dwWidth
);
3083 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3084 param
.ddraw_height
, ddsd
.dwHeight
);
3086 GetWindowRect(window
, &r
);
3087 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3088 wine_dbgstr_rect(&r
));
3090 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3091 expect_messages
= exclusive_messages
;
3095 hr
= IDirectDrawSurface7_IsLost(primary
);
3096 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3097 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3098 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3099 hr
= IDirectDrawSurface7_IsLost(primary
);
3100 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3102 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3103 expect_messages
= NULL
;
3104 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3105 "Expected screen size %ux%u, got %ux%u.\n",
3106 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3108 GetWindowRect(window
, &r
);
3109 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3110 wine_dbgstr_rect(&r
));
3112 expect_messages
= exclusive_focus_loss_messages
;
3113 focus_test_ddraw
= ddraw
;
3114 ret
= SetForegroundWindow(GetDesktopWindow());
3115 ok(ret
, "Failed to set foreground window.\n");
3116 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3117 focus_test_ddraw
= NULL
;
3119 memset(&devmode
, 0, sizeof(devmode
));
3120 devmode
.dmSize
= sizeof(devmode
);
3121 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3122 ok(ret
, "Failed to get display mode.\n");
3123 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3124 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %ux%u.\n",
3125 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3127 expect_messages
= exclusive_focus_restore_messages
;
3128 ShowWindow(window
, SW_RESTORE
);
3129 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3131 GetWindowRect(window
, &r
);
3132 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3133 wine_dbgstr_rect(&r
));
3134 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3135 ok(ret
, "Failed to get display mode.\n");
3136 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3137 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %ux%u.\n",
3138 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3140 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3141 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3142 /* Normally the primary should be restored here. Unfortunately this causes the
3143 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3144 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3145 * the point of the GetSurfaceDesc call. */
3147 expect_messages
= sc_minimize_messages
;
3148 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3149 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3150 expect_messages
= NULL
;
3152 expect_messages
= sc_restore_messages
;
3153 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3154 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3155 expect_messages
= NULL
;
3157 expect_messages
= sc_maximize_messages
;
3158 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3159 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3160 expect_messages
= NULL
;
3162 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3163 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3165 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3166 expect_messages
= exclusive_messages
;
3170 hr
= IDirectDrawSurface7_IsLost(primary
);
3171 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3172 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3173 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3174 hr
= IDirectDrawSurface7_IsLost(primary
);
3175 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3177 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3178 expect_messages
= NULL
;
3179 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3180 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3181 "Expected screen size %ux%u, got %ux%u.\n",
3182 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3184 GetWindowRect(window
, &r
);
3185 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3186 wine_dbgstr_rect(&r
));
3188 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3189 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3190 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3191 param
.ddraw_width
, ddsd
.dwWidth
);
3192 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3193 param
.ddraw_height
, ddsd
.dwHeight
);
3194 IDirectDrawSurface7_Release(primary
);
3197 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3198 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3200 memset(&ddsd
, 0, sizeof(ddsd
));
3201 ddsd
.dwSize
= sizeof(ddsd
);
3202 ddsd
.dwFlags
= DDSD_CAPS
;
3203 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3205 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3206 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3207 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3208 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3209 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3210 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3211 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3212 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3214 GetWindowRect(window
, &r
);
3215 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3216 wine_dbgstr_rect(&r
));
3218 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3219 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3221 GetWindowRect(window
, &r
);
3222 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3223 wine_dbgstr_rect(&r
));
3225 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3226 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3227 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3228 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3229 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3230 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3231 IDirectDrawSurface7_Release(primary
);
3233 memset(&ddsd
, 0, sizeof(ddsd
));
3234 ddsd
.dwSize
= sizeof(ddsd
);
3235 ddsd
.dwFlags
= DDSD_CAPS
;
3236 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3238 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3239 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3240 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3241 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3242 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3243 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3244 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3245 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3247 GetWindowRect(window
, &r
);
3248 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3249 wine_dbgstr_rect(&r
));
3251 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3252 expect_messages
= normal_messages
;
3256 hr
= IDirectDrawSurface7_IsLost(primary
);
3257 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3258 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3259 devmode
.dmPelsWidth
= param
.user32_width
;
3260 devmode
.dmPelsHeight
= param
.user32_height
;
3261 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3262 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3263 hr
= IDirectDrawSurface7_IsLost(primary
);
3264 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3266 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3267 expect_messages
= NULL
;
3268 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3270 GetWindowRect(window
, &r
);
3271 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3272 wine_dbgstr_rect(&r
));
3274 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3275 expect_messages
= normal_messages
;
3279 hr
= IDirectDrawSurface7_Restore(primary
);
3280 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3281 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3282 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3283 hr
= IDirectDrawSurface7_Restore(primary
);
3284 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3285 hr
= IDirectDrawSurface7_IsLost(primary
);
3286 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3288 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3289 expect_messages
= NULL
;
3290 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3292 GetWindowRect(window
, &r
);
3293 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3294 wine_dbgstr_rect(&r
));
3296 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3297 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3298 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3299 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3300 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3301 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3302 IDirectDrawSurface7_Release(primary
);
3304 memset(&ddsd
, 0, sizeof(ddsd
));
3305 ddsd
.dwSize
= sizeof(ddsd
);
3306 ddsd
.dwFlags
= DDSD_CAPS
;
3307 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3309 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3310 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3311 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3312 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3313 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3314 param
.ddraw_width
, ddsd
.dwWidth
);
3315 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3316 param
.ddraw_height
, ddsd
.dwHeight
);
3318 GetWindowRect(window
, &r
);
3319 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3320 wine_dbgstr_rect(&r
));
3322 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3323 expect_messages
= normal_messages
;
3327 hr
= IDirectDrawSurface7_IsLost(primary
);
3328 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3329 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3330 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3331 hr
= IDirectDrawSurface7_IsLost(primary
);
3332 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3334 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3335 expect_messages
= NULL
;
3336 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3338 GetWindowRect(window
, &r
);
3339 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3340 wine_dbgstr_rect(&r
));
3342 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3343 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3344 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3345 param
.ddraw_width
, ddsd
.dwWidth
);
3346 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3347 param
.ddraw_height
, ddsd
.dwHeight
);
3348 IDirectDrawSurface7_Release(primary
);
3350 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3351 ok(ret
, "Failed to get display mode.\n");
3352 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3353 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3354 "Expected resolution %ux%u, got %ux%u.\n",
3355 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3356 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3357 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3358 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3360 memset(&ddsd
, 0, sizeof(ddsd
));
3361 ddsd
.dwSize
= sizeof(ddsd
);
3362 ddsd
.dwFlags
= DDSD_CAPS
;
3363 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3365 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3366 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3367 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3368 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3369 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3370 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3371 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3372 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3374 GetWindowRect(window
, &r
);
3375 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3376 wine_dbgstr_rect(&r
));
3378 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3379 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3380 * not DDSCL_FULLSCREEN. */
3381 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3382 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3384 GetWindowRect(window
, &r
);
3385 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3386 wine_dbgstr_rect(&r
));
3388 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3389 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3390 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3391 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3392 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3393 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3394 IDirectDrawSurface7_Release(primary
);
3396 memset(&ddsd
, 0, sizeof(ddsd
));
3397 ddsd
.dwSize
= sizeof(ddsd
);
3398 ddsd
.dwFlags
= DDSD_CAPS
;
3399 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3401 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3402 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3403 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3404 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3405 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3406 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3407 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3408 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3410 GetWindowRect(window
, &r
);
3411 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3412 wine_dbgstr_rect(&r
));
3414 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3415 expect_messages
= normal_messages
;
3419 hr
= IDirectDrawSurface7_IsLost(primary
);
3420 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3421 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3422 devmode
.dmPelsWidth
= param
.user32_width
;
3423 devmode
.dmPelsHeight
= param
.user32_height
;
3424 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3425 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3426 hr
= IDirectDrawSurface7_IsLost(primary
);
3427 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3429 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3430 expect_messages
= NULL
;
3431 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3433 GetWindowRect(window
, &r
);
3434 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3435 wine_dbgstr_rect(&r
));
3437 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3438 expect_messages
= normal_messages
;
3442 hr
= IDirectDrawSurface7_Restore(primary
);
3443 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3444 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3445 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3446 hr
= IDirectDrawSurface7_Restore(primary
);
3447 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3448 hr
= IDirectDrawSurface7_IsLost(primary
);
3449 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3451 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3452 expect_messages
= NULL
;
3453 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3455 GetWindowRect(window
, &r
);
3456 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3457 wine_dbgstr_rect(&r
));
3459 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3460 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3461 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3462 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3463 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3464 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3465 IDirectDrawSurface7_Release(primary
);
3467 memset(&ddsd
, 0, sizeof(ddsd
));
3468 ddsd
.dwSize
= sizeof(ddsd
);
3469 ddsd
.dwFlags
= DDSD_CAPS
;
3470 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3472 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3473 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3474 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3475 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3476 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3477 param
.ddraw_width
, ddsd
.dwWidth
);
3478 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3479 param
.ddraw_height
, ddsd
.dwHeight
);
3481 GetWindowRect(window
, &r
);
3482 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3483 wine_dbgstr_rect(&r
));
3485 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3486 expect_messages
= normal_messages
;
3490 hr
= IDirectDrawSurface7_IsLost(primary
);
3491 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3492 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3493 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3494 hr
= IDirectDrawSurface7_IsLost(primary
);
3495 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3497 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3498 expect_messages
= NULL
;
3499 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3501 GetWindowRect(window
, &r
);
3502 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3503 wine_dbgstr_rect(&r
));
3505 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3506 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3507 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3508 param
.ddraw_width
, ddsd
.dwWidth
);
3509 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3510 param
.ddraw_height
, ddsd
.dwHeight
);
3511 IDirectDrawSurface7_Release(primary
);
3513 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3514 ok(ret
, "Failed to get display mode.\n");
3515 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3516 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3517 "Expected resolution %ux%u, got %ux%u.\n",
3518 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3519 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3520 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3521 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3523 memset(&ddsd
, 0, sizeof(ddsd
));
3524 ddsd
.dwSize
= sizeof(ddsd
);
3525 ddsd
.dwFlags
= DDSD_CAPS
;
3526 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3528 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3529 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3530 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3531 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3532 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3533 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3534 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3535 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3536 IDirectDrawSurface7_Release(primary
);
3538 GetWindowRect(window
, &r
);
3539 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3540 wine_dbgstr_rect(&r
));
3542 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3543 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3544 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3545 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3546 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3548 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3549 expect_messages
= exclusive_messages
;
3553 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3554 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3556 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3557 expect_messages
= NULL
;
3558 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3559 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3560 "Expected screen size %ux%u, got %ux%u.\n",
3561 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3562 screen_size
.cx
, screen_size
.cy
);
3564 GetWindowRect(window
, &r
);
3565 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3566 wine_dbgstr_rect(&r
));
3568 memset(&ddsd
, 0, sizeof(ddsd
));
3569 ddsd
.dwSize
= sizeof(ddsd
);
3570 ddsd
.dwFlags
= DDSD_CAPS
;
3571 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3573 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3574 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3575 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3576 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3577 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3578 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3579 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3580 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3581 IDirectDrawSurface7_Release(primary
);
3583 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3584 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3585 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3586 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3587 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3589 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3590 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3592 memset(&ddsd
, 0, sizeof(ddsd
));
3593 ddsd
.dwSize
= sizeof(ddsd
);
3594 ddsd
.dwFlags
= DDSD_CAPS
;
3595 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3597 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3598 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3599 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3600 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3601 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3602 param
.ddraw_width
, ddsd
.dwWidth
);
3603 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3604 param
.ddraw_height
, ddsd
.dwHeight
);
3605 IDirectDrawSurface7_Release(primary
);
3607 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3608 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3610 /* If the window is changed at the same time, messages are sent to the new window. */
3611 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3612 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3613 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3614 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3616 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3617 expect_messages
= exclusive_messages
;
3620 screen_size2
.cx
= 0;
3621 screen_size2
.cy
= 0;
3623 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3624 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3626 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3627 expect_messages
= NULL
;
3628 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3629 screen_size
.cx
, screen_size
.cy
);
3630 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3631 "Expected screen size 2 %ux%u, got %ux%u.\n",
3632 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3634 GetWindowRect(window
, &r
);
3635 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3636 wine_dbgstr_rect(&r
));
3637 GetWindowRect(window2
, &r
);
3638 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3639 wine_dbgstr_rect(&r
));
3641 memset(&ddsd
, 0, sizeof(ddsd
));
3642 ddsd
.dwSize
= sizeof(ddsd
);
3643 ddsd
.dwFlags
= DDSD_CAPS
;
3644 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3646 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3647 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3648 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3649 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3650 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3651 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3652 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3653 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3654 IDirectDrawSurface7_Release(primary
);
3656 ref
= IDirectDraw7_Release(ddraw
);
3657 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3659 GetWindowRect(window
, &r
);
3660 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3661 wine_dbgstr_rect(&r
));
3663 ret
= restore_display_modes(original_modes
, display_count
);
3664 ok(ret
, "Failed to restore display modes.\n");
3666 /* Test that no mode restorations if no mode changes happened */
3667 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3668 devmode
.dmPelsWidth
= param
.user32_width
;
3669 devmode
.dmPelsHeight
= param
.user32_height
;
3670 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3671 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3673 ddraw
= create_ddraw();
3674 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3675 ref
= IDirectDraw7_Release(ddraw
);
3676 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3678 memset(&devmode2
, 0, sizeof(devmode2
));
3679 devmode2
.dmSize
= sizeof(devmode2
);
3680 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3681 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3682 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3683 ret
= restore_display_modes(original_modes
, display_count
);
3684 ok(ret
, "Failed to restore display modes.\n");
3686 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3687 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3688 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3690 ddraw
= create_ddraw();
3691 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3692 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3693 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3694 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3695 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3696 ref
= IDirectDraw7_Release(ddraw
);
3697 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3699 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3700 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3701 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3702 ret
= restore_display_modes(original_modes
, display_count
);
3703 ok(ret
, "Failed to restore display modes.\n");
3705 /* Test that mode restorations use display settings in the registry after ddraw object releases
3706 * if SetDisplayMode() was called */
3707 ddraw
= create_ddraw();
3708 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3709 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3710 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3712 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3713 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3715 ref
= IDirectDraw7_Release(ddraw
);
3716 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3718 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3719 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3720 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3721 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3722 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3723 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3724 ret
= restore_display_modes(original_modes
, display_count
);
3725 ok(ret
, "Failed to restore display modes.\n");
3727 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3728 ddraw
= create_ddraw();
3729 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3730 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3731 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3733 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3734 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3736 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3737 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
3739 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3740 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3741 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3742 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3743 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3744 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3746 ref
= IDirectDraw7_Release(ddraw
);
3747 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3749 expect_messages
= NULL
;
3750 DestroyWindow(window
);
3751 DestroyWindow(window2
);
3752 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3753 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3754 ret
= restore_display_modes(original_modes
, display_count
);
3755 ok(ret
, "Failed to restore display modes.\n");
3756 heap_free(original_modes
);
3759 static void test_coop_level_mode_set_multi(void)
3761 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3762 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3763 WCHAR second_monitor_name
[CCHDEVICENAME
];
3764 IDirectDraw7
*ddraw1
, *ddraw2
;
3772 memset(&devmode
, 0, sizeof(devmode
));
3773 devmode
.dmSize
= sizeof(devmode
);
3774 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3775 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3776 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3777 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3778 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3779 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3781 ret
= save_display_modes(&original_modes
, &display_count
);
3782 ok(ret
, "Failed to save original display modes.\n");
3784 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3785 0, 0, 100, 100, 0, 0, 0, 0);
3786 ddraw1
= create_ddraw();
3787 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3789 /* With just a single ddraw object, the display mode is restored on
3791 hr
= set_display_mode(ddraw1
, 800, 600);
3792 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3793 w
= GetSystemMetrics(SM_CXSCREEN
);
3794 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3795 h
= GetSystemMetrics(SM_CYSCREEN
);
3796 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3798 ref
= IDirectDraw7_Release(ddraw1
);
3799 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3800 w
= GetSystemMetrics(SM_CXSCREEN
);
3801 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3802 h
= GetSystemMetrics(SM_CYSCREEN
);
3803 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3805 /* When there are multiple ddraw objects, the display mode is restored to
3806 * the initial mode, before the first SetDisplayMode() call. */
3807 ddraw1
= create_ddraw();
3808 hr
= set_display_mode(ddraw1
, 800, 600);
3809 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3810 w
= GetSystemMetrics(SM_CXSCREEN
);
3811 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3812 h
= GetSystemMetrics(SM_CYSCREEN
);
3813 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3815 ddraw2
= create_ddraw();
3816 hr
= set_display_mode(ddraw2
, 640, 480);
3817 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3818 w
= GetSystemMetrics(SM_CXSCREEN
);
3819 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3820 h
= GetSystemMetrics(SM_CYSCREEN
);
3821 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3823 ref
= IDirectDraw7_Release(ddraw2
);
3824 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3825 w
= GetSystemMetrics(SM_CXSCREEN
);
3826 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3827 h
= GetSystemMetrics(SM_CYSCREEN
);
3828 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3830 ref
= IDirectDraw7_Release(ddraw1
);
3831 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3832 w
= GetSystemMetrics(SM_CXSCREEN
);
3833 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3834 h
= GetSystemMetrics(SM_CYSCREEN
);
3835 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3837 /* Regardless of release ordering. */
3838 ddraw1
= create_ddraw();
3839 hr
= set_display_mode(ddraw1
, 800, 600);
3840 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3841 w
= GetSystemMetrics(SM_CXSCREEN
);
3842 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3843 h
= GetSystemMetrics(SM_CYSCREEN
);
3844 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3846 ddraw2
= create_ddraw();
3847 hr
= set_display_mode(ddraw2
, 640, 480);
3848 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3849 w
= GetSystemMetrics(SM_CXSCREEN
);
3850 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3851 h
= GetSystemMetrics(SM_CYSCREEN
);
3852 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3854 ref
= IDirectDraw7_Release(ddraw1
);
3855 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3856 w
= GetSystemMetrics(SM_CXSCREEN
);
3857 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3858 h
= GetSystemMetrics(SM_CYSCREEN
);
3859 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3861 ref
= IDirectDraw7_Release(ddraw2
);
3862 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3863 w
= GetSystemMetrics(SM_CXSCREEN
);
3864 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3865 h
= GetSystemMetrics(SM_CYSCREEN
);
3866 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3868 /* But only for ddraw objects that called SetDisplayMode(). */
3869 ddraw1
= create_ddraw();
3870 ddraw2
= create_ddraw();
3871 hr
= set_display_mode(ddraw2
, 640, 480);
3872 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3873 w
= GetSystemMetrics(SM_CXSCREEN
);
3874 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3875 h
= GetSystemMetrics(SM_CYSCREEN
);
3876 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3878 ref
= IDirectDraw7_Release(ddraw1
);
3879 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3880 w
= GetSystemMetrics(SM_CXSCREEN
);
3881 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3882 h
= GetSystemMetrics(SM_CYSCREEN
);
3883 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3885 ref
= IDirectDraw7_Release(ddraw2
);
3886 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3887 w
= GetSystemMetrics(SM_CXSCREEN
);
3888 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3889 h
= GetSystemMetrics(SM_CYSCREEN
);
3890 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3892 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3893 * restoring the display mode. */
3894 ddraw1
= create_ddraw();
3895 hr
= set_display_mode(ddraw1
, 800, 600);
3896 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3897 w
= GetSystemMetrics(SM_CXSCREEN
);
3898 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3899 h
= GetSystemMetrics(SM_CYSCREEN
);
3900 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3902 ddraw2
= create_ddraw();
3903 hr
= set_display_mode(ddraw2
, 640, 480);
3904 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3905 w
= GetSystemMetrics(SM_CXSCREEN
);
3906 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3907 h
= GetSystemMetrics(SM_CYSCREEN
);
3908 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3910 hr
= IDirectDraw7_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3911 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3913 ref
= IDirectDraw7_Release(ddraw1
);
3914 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3915 w
= GetSystemMetrics(SM_CXSCREEN
);
3916 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3917 h
= GetSystemMetrics(SM_CYSCREEN
);
3918 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3920 ref
= IDirectDraw7_Release(ddraw2
);
3921 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3922 w
= GetSystemMetrics(SM_CXSCREEN
);
3923 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3924 h
= GetSystemMetrics(SM_CYSCREEN
);
3925 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3927 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3928 ddraw1
= create_ddraw();
3929 hr
= set_display_mode(ddraw1
, 800, 600);
3930 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3931 w
= GetSystemMetrics(SM_CXSCREEN
);
3932 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3933 h
= GetSystemMetrics(SM_CYSCREEN
);
3934 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3936 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3937 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3939 ddraw2
= create_ddraw();
3940 hr
= set_display_mode(ddraw2
, 640, 480);
3941 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3943 ref
= IDirectDraw7_Release(ddraw1
);
3944 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3945 w
= GetSystemMetrics(SM_CXSCREEN
);
3946 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3947 h
= GetSystemMetrics(SM_CYSCREEN
);
3948 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3950 ref
= IDirectDraw7_Release(ddraw2
);
3951 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3952 w
= GetSystemMetrics(SM_CXSCREEN
);
3953 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3954 h
= GetSystemMetrics(SM_CYSCREEN
);
3955 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3957 if (display_count
< 2)
3959 skip("Following tests require two monitors.\n");
3963 ret
= restore_display_modes(original_modes
, display_count
);
3964 ok(ret
, "Failed to restore display modes.\n");
3966 second_monitor_name
[0] = '\0';
3967 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
3969 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
3971 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
3975 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
3976 memset(&old_devmode
, 0, sizeof(old_devmode
));
3977 old_devmode
.dmSize
= sizeof(old_devmode
);
3978 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
3979 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3981 devmode
= old_devmode
;
3982 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
3984 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3985 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
3988 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3989 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
3990 "Failed to find a different mode for the second monitor.\n");
3992 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
3993 ddraw1
= create_ddraw();
3994 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3995 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3996 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3998 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3999 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4001 memset(&devmode2
, 0, sizeof(devmode2
));
4002 devmode2
.dmSize
= sizeof(devmode2
);
4003 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4004 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4005 if (compare_mode_rect(&devmode2
, &old_devmode
))
4007 skip("Failed to change display settings of the second monitor.\n");
4008 ref
= IDirectDraw7_Release(ddraw1
);
4009 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4013 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
4014 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
4015 ref
= IDirectDraw7_Release(ddraw1
);
4016 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4018 memset(&devmode3
, 0, sizeof(devmode3
));
4019 devmode3
.dmSize
= sizeof(devmode3
);
4020 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
4021 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4022 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
4023 ret
= restore_display_modes(original_modes
, display_count
);
4024 ok(ret
, "Failed to restore display modes.\n");
4026 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
4027 * SetDisplayMode() was called */
4028 ddraw1
= create_ddraw();
4029 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4030 hr
= set_display_mode(ddraw1
, 800, 600);
4031 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4033 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4034 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4036 ref
= IDirectDraw7_Release(ddraw1
);
4037 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4039 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4040 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4041 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4042 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4043 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4044 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4045 ret
= restore_display_modes(original_modes
, display_count
);
4046 ok(ret
, "Failed to restore display modes.\n");
4048 /* Test that mode restorations happen for non-primary monitors as well */
4049 ddraw1
= create_ddraw();
4050 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4051 hr
= set_display_mode(ddraw1
, 800, 600);
4052 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4054 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4055 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4057 hr
= IDirectDraw7_RestoreDisplayMode(ddraw1
);
4058 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
4060 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4061 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4062 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4063 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4064 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4065 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4067 ref
= IDirectDraw7_Release(ddraw1
);
4068 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4069 ret
= restore_display_modes(original_modes
, display_count
);
4070 ok(ret
, "Failed to restore display modes.\n");
4072 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4073 ddraw1
= create_ddraw();
4074 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4075 hr
= set_display_mode(ddraw1
, 800, 600);
4076 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4078 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4079 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4080 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4082 ref
= IDirectDraw7_Release(ddraw1
);
4083 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4085 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4086 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4087 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4088 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4089 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4090 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4091 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4092 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4093 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4094 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4095 ret
= restore_display_modes(original_modes
, display_count
);
4096 ok(ret
, "Failed to restore display modes.\n");
4098 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4099 * objects and one of them restores display mode */
4100 ddraw1
= create_ddraw();
4101 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4102 ddraw2
= create_ddraw();
4103 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4104 hr
= set_display_mode(ddraw1
, 800, 600);
4105 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4106 hr
= set_display_mode(ddraw2
, 640, 480);
4107 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4109 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4110 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4112 hr
= IDirectDraw7_RestoreDisplayMode(ddraw2
);
4113 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
4115 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4116 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4117 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4118 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4119 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4120 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4122 ref
= IDirectDraw7_Release(ddraw2
);
4123 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4124 ref
= IDirectDraw7_Release(ddraw1
);
4125 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4126 ret
= restore_display_modes(original_modes
, display_count
);
4127 ok(ret
, "Failed to restore display modes.\n");
4129 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4130 * objects and one of them got released */
4131 ddraw1
= create_ddraw();
4132 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4133 ddraw2
= create_ddraw();
4134 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4135 hr
= set_display_mode(ddraw1
, 800, 600);
4136 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4137 hr
= set_display_mode(ddraw2
, 640, 480);
4138 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4140 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4141 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4143 ref
= IDirectDraw7_Release(ddraw2
);
4144 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4146 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4147 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4148 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4149 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4150 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4151 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4153 ref
= IDirectDraw7_Release(ddraw1
);
4154 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4157 DestroyWindow(window
);
4158 ret
= restore_display_modes(original_modes
, display_count
);
4159 ok(ret
, "Failed to restore display modes.\n");
4160 heap_free(original_modes
);
4163 static void test_initialize(void)
4165 IDirectDraw7
*ddraw
;
4168 ddraw
= create_ddraw();
4169 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4171 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4172 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
4173 IDirectDraw7_Release(ddraw
);
4176 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw7
, (void **)&ddraw
);
4177 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr
);
4178 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4179 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
4180 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4181 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4182 IDirectDraw7_Release(ddraw
);
4186 static void test_coop_level_surf_create(void)
4188 IDirectDrawSurface7
*surface
;
4189 IDirectDraw7
*ddraw
;
4190 DDSURFACEDESC2 ddsd
;
4193 ddraw
= create_ddraw();
4194 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4196 memset(&ddsd
, 0, sizeof(ddsd
));
4197 ddsd
.dwSize
= sizeof(ddsd
);
4198 ddsd
.dwFlags
= DDSD_CAPS
;
4199 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4200 surface
= (void *)0xdeadbeef;
4201 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4202 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4203 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4205 surface
= (void *)0xdeadbeef;
4206 hr
= IDirectDraw7_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4207 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4208 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4210 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4211 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4213 surface
= (void *)0xdeadbeef;
4214 hr
= IDirectDraw7_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4215 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
4216 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4218 IDirectDraw7_Release(ddraw
);
4221 static void test_vb_discard(void)
4223 static const struct vec4 quad
[] =
4225 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
4226 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
4227 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
4228 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
4231 IDirect3DDevice7
*device
;
4233 IDirect3DVertexBuffer7
*buffer
;
4236 D3DVERTEXBUFFERDESC desc
;
4238 static const unsigned int vbsize
= 16;
4241 window
= create_window();
4242 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4244 skip("Failed to create a 3D device, skipping test.\n");
4245 DestroyWindow(window
);
4249 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
4250 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
4252 memset(&desc
, 0, sizeof(desc
));
4253 desc
.dwSize
= sizeof(desc
);
4254 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
4255 desc
.dwFVF
= D3DFVF_XYZRHW
;
4256 desc
.dwNumVertices
= vbsize
;
4257 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0);
4258 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
4260 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4261 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4262 memcpy(data
, quad
, sizeof(quad
));
4263 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4264 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4266 hr
= IDirect3DDevice7_BeginScene(device
);
4267 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4268 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
4269 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4270 hr
= IDirect3DDevice7_EndScene(device
);
4271 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4273 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4274 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4275 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
4276 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4277 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4279 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4280 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4281 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
4283 if (data
[i
] != 0xaa)
4285 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
4289 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4290 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4292 IDirect3DVertexBuffer7_Release(buffer
);
4293 IDirect3D7_Release(d3d
);
4294 IDirect3DDevice7_Release(device
);
4295 DestroyWindow(window
);
4298 static void test_coop_level_multi_window(void)
4300 HWND window1
, window2
;
4301 IDirectDraw7
*ddraw
;
4304 window1
= create_window();
4305 window2
= create_window();
4306 ddraw
= create_ddraw();
4307 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4309 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4310 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4311 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4312 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4313 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4314 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4316 IDirectDraw7_Release(ddraw
);
4317 DestroyWindow(window2
);
4318 DestroyWindow(window1
);
4321 static void test_draw_strided(void)
4323 static struct vec3 position
[] =
4330 static DWORD diffuse
[] =
4332 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
4334 static WORD indices
[] =
4339 IDirectDrawSurface7
*rt
;
4340 IDirect3DDevice7
*device
;
4344 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
4346 window
= create_window();
4347 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4349 skip("Failed to create a 3D device, skipping test.\n");
4350 DestroyWindow(window
);
4354 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
4355 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4357 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4358 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4359 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 1.0f
, 0);
4360 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4361 hr
= IDirect3DDevice7_BeginScene(device
);
4362 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4364 memset(&strided
, 0x55, sizeof(strided
));
4365 strided
.position
.lpvData
= position
;
4366 strided
.position
.dwStride
= sizeof(*position
);
4367 strided
.diffuse
.lpvData
= diffuse
;
4368 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
4369 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
4370 &strided
, 4, indices
, 6, 0);
4371 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4373 hr
= IDirect3DDevice7_EndScene(device
);
4374 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4376 color
= get_surface_color(rt
, 320, 240);
4377 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4379 IDirectDrawSurface7_Release(rt
);
4380 IDirect3DDevice7_Release(device
);
4381 DestroyWindow(window
);
4384 static void test_lighting(void)
4386 static D3DMATRIX mat
=
4388 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4389 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4390 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4391 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4395 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4396 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4397 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4398 0.0f
, 0.0f
, 0.5f
, 1.0f
,
4402 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4403 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4404 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
4405 10.f
, 10.0f
, 10.0f
, 1.0f
,
4409 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4410 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4411 0.0f
, 0.0f
, 1.0f
, -1.0f
,
4412 10.f
, 10.0f
, 10.0f
, 0.0f
,
4414 static struct vertex
4416 struct vec3 position
;
4421 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4422 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4423 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4424 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4428 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4429 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4430 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4431 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4433 static struct vertex_normal
4435 struct vec3 position
;
4441 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4442 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4443 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4444 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4448 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4449 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4450 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4451 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4455 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4456 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4457 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4458 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4462 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4463 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4464 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4465 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4469 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4470 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4471 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4472 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4474 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
4477 D3DMATRIX
*world_matrix
;
4479 DWORD expected
, expected_process_vertices
;
4480 const char *message
;
4481 BOOL process_vertices_todo
;
4485 {&mat
, nquad
, 0x000000ff, 0xff0000ff, "Lit quad with light"},
4486 {&mat_singular
, nquad
, 0x000000ff, 0xff000000, "Lit quad with singular world matrix", TRUE
},
4487 {&mat_transf
, rotatedquad
, 0x000000ff, 0xff0000ff, "Lit quad with transformation matrix"},
4488 {&mat_nonaffine
, translatedquad
, 0x00000000, 0xff000000, "Lit quad with non-affine matrix"},
4491 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
4492 IDirect3DVertexBuffer7
*src_vb1
, *src_vb2
, *dst_vb
;
4493 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
4494 struct vertex_normal
*src_data2
;
4495 D3DVERTEXBUFFERDESC vb_desc
;
4496 struct vertex
*src_data1
;
4497 IDirect3DDevice7
*device
;
4498 IDirectDrawSurface7
*rt
;
4499 IDirectDraw7
*ddraw
;
4509 struct vec4 position
;
4515 window
= create_window();
4516 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4518 skip("Failed to create a 3D device, skipping test.\n");
4519 DestroyWindow(window
);
4522 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
4523 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4524 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
4525 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4527 is_warp
= ddraw_is_warp(ddraw
);
4529 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
4530 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4532 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
4533 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4535 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4536 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4537 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4538 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4539 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4540 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4541 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
4542 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4543 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4544 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4545 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4546 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4547 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
4548 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4549 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
4550 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4552 hr
= IDirect3DDevice7_BeginScene(device
);
4553 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4555 memset(&vb_desc
, 0, sizeof(vb_desc
));
4556 vb_desc
.dwSize
= sizeof(vb_desc
);
4557 vb_desc
.dwFVF
= fvf
;
4558 vb_desc
.dwNumVertices
= 2;
4559 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb1
, 0);
4560 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4561 vb_desc
.dwSize
= sizeof(vb_desc
);
4562 vb_desc
.dwFVF
= nfvf
;
4563 vb_desc
.dwNumVertices
= 2;
4564 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb2
, 0);
4565 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4567 memset(&vb_desc
, 0, sizeof(vb_desc
));
4568 vb_desc
.dwSize
= sizeof(vb_desc
);
4569 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4570 vb_desc
.dwNumVertices
= 4;
4571 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
4572 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4574 hr
= IDirect3DVertexBuffer7_Lock(src_vb1
, 0, (void **)&src_data1
, NULL
);
4575 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4576 memcpy(src_data1
, unlitquad
, sizeof(*src_data1
));
4577 memcpy(&src_data1
[1], litquad
, sizeof(*src_data1
));
4578 hr
= IDirect3DVertexBuffer7_Unlock(src_vb1
);
4579 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4581 hr
= IDirect3DVertexBuffer7_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4582 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4583 memcpy(src_data2
, unlitnquad
, sizeof(*src_data2
));
4584 memcpy(&src_data2
[1], litnquad
, sizeof(*src_data2
));
4585 hr
= IDirect3DVertexBuffer7_Unlock(src_vb2
);
4586 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4588 /* No lights are defined... That means, lit vertices should be entirely black. */
4589 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4590 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4591 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0,
4592 1, src_vb1
, 0, device
, 0);
4593 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4594 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
4596 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4598 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4599 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4600 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 1,
4601 1, src_vb1
, 1, device
, 0);
4602 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4603 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4605 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4607 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4608 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4609 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 2,
4610 1, src_vb2
, 0, device
, 0);
4611 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4612 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4614 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4616 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4617 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4618 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 3,
4619 1, src_vb2
, 1, device
, 0);
4620 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4621 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4623 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4625 hr
= IDirect3DDevice7_EndScene(device
);
4626 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4628 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4629 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4631 color
= get_surface_color(rt
, 160, 360);
4632 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color
);
4633 ok(dst_data
[0].diffuse
== 0xffff0000,
4634 "Unlit quad without normals has color 0x%08x, expected 0xffff0000.\n", dst_data
[0].diffuse
);
4635 ok(!dst_data
[0].specular
,
4636 "Unexpected specular color 0x%08x.\n", dst_data
[0].specular
);
4637 color
= get_surface_color(rt
, 160, 120);
4638 /* Broken on some of WARP drivers. */
4639 ok(color
== 0x00000000 || broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4640 "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color
);
4641 ok(dst_data
[1].diffuse
== 0xff000000,
4642 "Lit quad without normals has color 0x%08x, expected 0xff000000.\n", dst_data
[1].diffuse
);
4643 ok(!dst_data
[1].specular
,
4644 "Unexpected specular color 0x%08x.\n", dst_data
[1].specular
);
4645 color
= get_surface_color(rt
, 480, 360);
4646 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color
);
4647 ok(dst_data
[2].diffuse
== 0xff0000ff,
4648 "Unlit quad with normals has color 0x%08x, expected 0xff0000ff.\n", dst_data
[2].diffuse
);
4649 ok(!dst_data
[2].specular
,
4650 "Unexpected specular color 0x%08x.\n", dst_data
[2].specular
);
4651 color
= get_surface_color(rt
, 480, 120);
4652 ok(color
== 0x00000000 || broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4653 "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color
);
4654 ok(dst_data
[3].diffuse
== 0xff000000,
4655 "Lit quad with normals has color 0x%08x, expected 0xff000000.\n", dst_data
[3].diffuse
);
4656 ok(!dst_data
[3].specular
,
4657 "Unexpected specular color 0x%08x.\n", dst_data
[3].specular
);
4659 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
4660 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4662 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
4663 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4665 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4667 hr
= IDirect3DVertexBuffer7_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4668 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4669 memcpy(src_data2
, tests
[i
].quad
, sizeof(*src_data2
));
4670 hr
= IDirect3DVertexBuffer7_Unlock(src_vb2
);
4671 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4673 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
4674 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4676 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
4677 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4679 hr
= IDirect3DDevice7_BeginScene(device
);
4680 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4682 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
4683 1, src_vb2
, 0, device
, 0);
4684 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4686 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
4688 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4690 hr
= IDirect3DDevice7_EndScene(device
);
4691 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4693 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4694 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4696 color
= get_surface_color(rt
, 320, 240);
4697 ok(color
== tests
[i
].expected
|| broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4698 "%s has color 0x%08x.\n", tests
[i
].message
, color
);
4699 todo_wine_if(tests
[i
].process_vertices_todo
)
4700 ok(dst_data
[0].diffuse
== tests
[i
].expected_process_vertices
,
4701 "%s has color 0x%08x.\n", tests
[i
].message
, dst_data
[0].diffuse
);
4702 ok(!dst_data
[0].specular
,
4703 "%s has specular color 0x%08x.\n", tests
[i
].message
, dst_data
[0].specular
);
4705 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
4706 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4709 IDirect3DVertexBuffer7_Release(src_vb1
);
4710 IDirect3DVertexBuffer7_Release(src_vb2
);
4711 IDirect3DVertexBuffer7_Release(dst_vb
);
4713 IDirectDrawSurface7_Release(rt
);
4715 IDirectDraw7_Release(ddraw
);
4716 IDirect3D7_Release(d3d
);
4717 refcount
= IDirect3DDevice7_Release(device
);
4718 ok(!refcount
, "Device has %u references left.\n", refcount
);
4719 DestroyWindow(window
);
4722 static void test_specular_lighting(void)
4724 static const unsigned int vertices_side
= 5;
4725 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
4726 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
4727 static D3DMATRIX mat
=
4729 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4730 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4731 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4732 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4734 static const struct vertex
4736 struct vec3 position
;
4741 {{-0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4742 {{ 0.0f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4743 {{ 0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4744 {{-0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4745 {{ 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4746 {{ 0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4747 {{-0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4748 {{ 0.0f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4749 {{ 0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4752 static D3DLIGHT7 directional
=
4754 D3DLIGHT_DIRECTIONAL
,
4755 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4756 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4757 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4758 {{0.0f
}, {0.0f
}, {0.0f
}},
4759 {{0.0f
}, {0.0f
}, {1.0f
}},
4764 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4765 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4766 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4767 {{0.0f
}, {0.0f
}, {0.0f
}},
4768 {{0.0f
}, {0.0f
}, {0.0f
}},
4776 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4777 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4778 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4779 {{0.0f
}, {0.0f
}, {0.0f
}},
4780 {{0.0f
}, {0.0f
}, {1.0f
}},
4784 M_PI
/ 12.0f
, M_PI
/ 3.0f
4786 /* The chosen range value makes the test fail when using a manhattan
4787 * distance metric vs the correct euclidean distance. */
4791 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4792 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4793 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4794 {{0.0f
}, {0.0f
}, {0.0f
}},
4795 {{0.0f
}, {0.0f
}, {0.0f
}},
4803 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4804 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4805 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4806 {{-1.1f
}, {0.0f
}, {1.1f
}},
4807 {{0.0f
}, {0.0f
}, {0.0f
}},
4812 static const struct expected_color
4817 expected_directional
[] =
4819 {160, 120, 0x00ffffff},
4820 {320, 120, 0x00ffffff},
4821 {480, 120, 0x00ffffff},
4822 {160, 240, 0x00ffffff},
4823 {320, 240, 0x00ffffff},
4824 {480, 240, 0x00ffffff},
4825 {160, 360, 0x00ffffff},
4826 {320, 360, 0x00ffffff},
4827 {480, 360, 0x00ffffff},
4829 expected_directional_local
[] =
4831 {160, 120, 0x003c3c3c},
4832 {320, 120, 0x00717171},
4833 {480, 120, 0x003c3c3c},
4834 {160, 240, 0x00717171},
4835 {320, 240, 0x00ffffff},
4836 {480, 240, 0x00717171},
4837 {160, 360, 0x003c3c3c},
4838 {320, 360, 0x00717171},
4839 {480, 360, 0x003c3c3c},
4843 {160, 120, 0x00282828},
4844 {320, 120, 0x005a5a5a},
4845 {480, 120, 0x00282828},
4846 {160, 240, 0x005a5a5a},
4847 {320, 240, 0x00ffffff},
4848 {480, 240, 0x005a5a5a},
4849 {160, 360, 0x00282828},
4850 {320, 360, 0x005a5a5a},
4851 {480, 360, 0x00282828},
4853 expected_point_local
[] =
4855 {160, 120, 0x00000000},
4856 {320, 120, 0x00070707},
4857 {480, 120, 0x00000000},
4858 {160, 240, 0x00070707},
4859 {320, 240, 0x00ffffff},
4860 {480, 240, 0x00070707},
4861 {160, 360, 0x00000000},
4862 {320, 360, 0x00070707},
4863 {480, 360, 0x00000000},
4867 {160, 120, 0x00000000},
4868 {320, 120, 0x00141414},
4869 {480, 120, 0x00000000},
4870 {160, 240, 0x00141414},
4871 {320, 240, 0x00ffffff},
4872 {480, 240, 0x00141414},
4873 {160, 360, 0x00000000},
4874 {320, 360, 0x00141414},
4875 {480, 360, 0x00000000},
4877 expected_spot_local
[] =
4879 {160, 120, 0x00000000},
4880 {320, 120, 0x00020202},
4881 {480, 120, 0x00000000},
4882 {160, 240, 0x00020202},
4883 {320, 240, 0x00ffffff},
4884 {480, 240, 0x00020202},
4885 {160, 360, 0x00000000},
4886 {320, 360, 0x00020202},
4887 {480, 360, 0x00000000},
4889 expected_point_range
[] =
4891 {160, 120, 0x00000000},
4892 {320, 120, 0x005a5a5a},
4893 {480, 120, 0x00000000},
4894 {160, 240, 0x005a5a5a},
4895 {320, 240, 0x00ffffff},
4896 {480, 240, 0x005a5a5a},
4897 {160, 360, 0x00000000},
4898 {320, 360, 0x005a5a5a},
4899 {480, 360, 0x00000000},
4901 expected_point_side
[] =
4903 {160, 120, 0x00000000},
4904 {320, 120, 0x00000000},
4905 {480, 120, 0x00000000},
4906 {160, 240, 0x00000000},
4907 {320, 240, 0x00000000},
4908 {480, 240, 0x00000000},
4909 {160, 360, 0x00000000},
4910 {320, 360, 0x00000000},
4911 {480, 360, 0x00000000},
4913 expected_directional_local_0
[] =
4915 {160, 120, 0x00ffffff},
4916 {320, 120, 0x00ffffff},
4917 {480, 120, 0x00ffffff},
4918 {160, 240, 0x00ffffff},
4919 {320, 240, 0x00ffffff},
4920 {480, 240, 0x00ffffff},
4921 {160, 360, 0x00ffffff},
4922 {320, 360, 0x00ffffff},
4923 {480, 360, 0x00ffffff},
4925 expected_point_0
[] =
4927 {160, 120, 0x00aaaaaa},
4928 {320, 120, 0x00cccccc},
4929 {480, 120, 0x00aaaaaa},
4930 {160, 240, 0x00cccccc},
4931 {320, 240, 0x00ffffff},
4932 {480, 240, 0x00cccccc},
4933 {160, 360, 0x00aaaaaa},
4934 {320, 360, 0x00cccccc},
4935 {480, 360, 0x00aaaaaa},
4939 {160, 120, 0x00000000},
4940 {320, 120, 0x002e2e2e},
4941 {480, 120, 0x00000000},
4942 {160, 240, 0x002e2e2e},
4943 {320, 240, 0x00ffffff},
4944 {480, 240, 0x002e2e2e},
4945 {160, 360, 0x00000000},
4946 {320, 360, 0x002e2e2e},
4947 {480, 360, 0x00000000},
4949 expected_point_range_0
[] =
4951 {160, 120, 0x00000000},
4952 {320, 120, 0x00cccccc},
4953 {480, 120, 0x00000000},
4954 {160, 240, 0x00cccccc},
4955 {320, 240, 0x00ffffff},
4956 {480, 240, 0x00cccccc},
4957 {160, 360, 0x00000000},
4958 {320, 360, 0x00cccccc},
4959 {480, 360, 0x00000000},
4965 float specular_power
;
4966 const struct expected_color
*expected
, *expected_process_vertices
;
4967 unsigned int expected_count
;
4968 BOOL todo_process_vertices
;
4972 {&directional
, FALSE
, 30.0f
, expected_directional
, expected_directional
,
4973 ARRAY_SIZE(expected_directional
)},
4974 {&directional
, TRUE
, 30.0f
, expected_directional_local
, expected_directional_local
,
4975 ARRAY_SIZE(expected_directional_local
)},
4976 {&point
, FALSE
, 30.0f
, expected_point
, expected_point
, ARRAY_SIZE(expected_point
)},
4977 {&point
, TRUE
, 30.0f
, expected_point_local
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
4978 {&spot
, FALSE
, 30.0f
, expected_spot
, expected_spot
, ARRAY_SIZE(expected_spot
)},
4979 {&spot
, TRUE
, 30.0f
, expected_spot_local
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
4980 {&point_range
, FALSE
, 30.0f
, expected_point_range
, expected_point_range
,
4981 ARRAY_SIZE(expected_point_range
)},
4983 /* For zero material shininess _ProcessVertices() seem to keep non-zero material shininess set previously. */
4984 {&point_side
, TRUE
, 0.0f
, expected_point_side
, expected_point_side
, ARRAY_SIZE(expected_point_side
), TRUE
},
4985 {&directional
, FALSE
, 0.0f
, expected_directional
, expected_directional
,
4986 ARRAY_SIZE(expected_directional
), TRUE
},
4987 {&directional
, TRUE
, 0.0f
, expected_directional_local_0
, expected_directional_local
,
4988 ARRAY_SIZE(expected_directional_local_0
), TRUE
},
4989 {&point
, FALSE
, 0.0f
, expected_point_0
, expected_point
, ARRAY_SIZE(expected_point_0
), TRUE
},
4990 {&point
, TRUE
, 0.0f
, expected_point_0
, expected_point_local
, ARRAY_SIZE(expected_point_0
), TRUE
},
4991 {&spot
, FALSE
, 0.0f
, expected_spot_0
, expected_spot
, ARRAY_SIZE(expected_spot_0
), TRUE
},
4992 {&spot
, TRUE
, 0.0f
, expected_spot_0
, expected_spot_local
, ARRAY_SIZE(expected_spot_0
), TRUE
},
4993 {&point_range
, FALSE
, 0.0f
, expected_point_range_0
, expected_point_range
, ARRAY_SIZE(expected_point_range_0
), TRUE
},
4996 IDirect3DVertexBuffer7
*src_vb
, *dst_vb
;
4997 D3DCOLOR color
, expected_color
;
4998 D3DVERTEXBUFFERDESC vb_desc
;
4999 IDirect3DDevice7
*device
;
5000 unsigned int i
, j
, x
, y
;
5001 IDirectDrawSurface7
*rt
;
5002 D3DMATERIAL7 material
;
5003 struct vec3
*src_data
;
5004 struct vertex
*quad
;
5012 struct vec4 position
;
5017 window
= create_window();
5018 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5020 skip("Failed to create a 3D device, skipping test.\n");
5021 DestroyWindow(window
);
5024 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
5025 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5027 quad
= heap_alloc(vertices_side
* vertices_side
* sizeof(*quad
));
5028 indices
= heap_alloc(indices_count
* sizeof(*indices
));
5029 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
5031 for (x
= 0; x
< vertices_side
; ++x
)
5033 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
5034 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
5035 quad
[i
].position
.z
= 1.0f
;
5036 quad
[i
].normal
.x
= 0.0f
;
5037 quad
[i
].normal
.y
= 0.0f
;
5038 quad
[i
++].normal
.z
= -1.0f
;
5041 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
5043 for (x
= 0; x
< (vertices_side
- 1); ++x
)
5045 indices
[i
++] = y
* vertices_side
+ x
+ 1;
5046 indices
[i
++] = y
* vertices_side
+ x
;
5047 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
5048 indices
[i
++] = y
* vertices_side
+ x
+ 1;
5049 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
5050 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
5054 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5055 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5057 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
5058 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5059 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
5060 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5061 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
5062 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5063 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
5064 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5065 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
5066 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5067 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
5068 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5070 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
5071 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5072 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
5073 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5075 memset(&vb_desc
, 0, sizeof(vb_desc
));
5076 vb_desc
.dwSize
= sizeof(vb_desc
);
5077 vb_desc
.dwFVF
= fvf
;
5078 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
5079 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0);
5080 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5081 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
5082 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5083 memcpy(src_data
, vertices
, sizeof(vertices
));
5084 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
5085 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5087 memset(&vb_desc
, 0, sizeof(vb_desc
));
5088 vb_desc
.dwSize
= sizeof(vb_desc
);
5089 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
5090 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
5091 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
5092 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5094 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5096 hr
= IDirect3DDevice7_SetLight(device
, 0, tests
[i
].light
);
5097 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5099 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
5100 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5102 memset(&material
, 0, sizeof(material
));
5103 U1(U2(material
).specular
).r
= 1.0f
;
5104 U2(U2(material
).specular
).g
= 1.0f
;
5105 U3(U2(material
).specular
).b
= 1.0f
;
5106 U4(U2(material
).specular
).a
= 0.5f
;
5107 U4(material
).power
= tests
[i
].specular_power
;
5108 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
5109 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5111 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
5112 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5114 hr
= IDirect3DDevice7_BeginScene(device
);
5115 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5117 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5118 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5119 memset(dst_data
, 0, sizeof(*dst_data
) * ARRAY_SIZE(vertices
));
5120 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
5121 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5123 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
5124 ARRAY_SIZE(vertices
), src_vb
, 0, device
, 0);
5125 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5127 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
5128 vertices_side
* vertices_side
, indices
, indices_count
, 0);
5129 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5131 hr
= IDirect3DDevice7_EndScene(device
);
5132 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5134 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5135 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5137 ok(tests
[i
].expected_count
== ARRAY_SIZE(vertices
), "Array size mismatch.\n");
5138 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
5140 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
5141 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
5142 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
5143 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
5144 tests
[i
].expected
[j
].y
, color
, i
);
5145 ok(!dst_data
[j
].diffuse
, "Expected color 0x00000000 for vertex %u, got 0x%08x, case %u.\n",
5146 j
, dst_data
[j
].diffuse
, i
);
5147 expected_color
= tests
[i
].expected_process_vertices
[j
].color
| 0x80000000;
5148 todo_wine_if(tests
[i
].todo_process_vertices
&& dst_data
[j
].specular
!= expected_color
)
5149 ok(compare_color(dst_data
[j
].specular
, expected_color
, 1),
5150 "Expected color 0x%08x for vertex %u, got 0x%08x, case %u.\n",
5151 expected_color
, j
, dst_data
[j
].specular
, i
);
5153 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
5154 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5157 IDirect3DVertexBuffer7_Release(dst_vb
);
5158 IDirect3DVertexBuffer7_Release(src_vb
);
5159 IDirectDrawSurface7_Release(rt
);
5161 IDirect3D7_Release(d3d
);
5162 refcount
= IDirect3DDevice7_Release(device
);
5163 ok(!refcount
, "Device has %u references left.\n", refcount
);
5164 DestroyWindow(window
);
5169 static void test_clear_rect_count(void)
5171 IDirectDrawSurface7
*rt
;
5172 IDirect3DDevice7
*device
;
5176 D3DRECT rect
= {{0}, {0}, {640}, {480}};
5178 window
= create_window();
5179 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5181 skip("Failed to create a 3D device, skipping test.\n");
5182 DestroyWindow(window
);
5186 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5187 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5189 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
5190 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5191 hr
= IDirect3DDevice7_Clear(device
, 0, &rect
, D3DCLEAR_TARGET
, 0x00ff0000, 1.0f
, 0);
5192 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5194 color
= get_surface_color(rt
, 320, 240);
5195 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x00ff0000, 1)),
5196 "Clear with count = 0, rect != NULL has color %#08x.\n", color
);
5198 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
5199 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5200 hr
= IDirect3DDevice7_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
5201 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5203 color
= get_surface_color(rt
, 320, 240);
5204 ok(compare_color(color
, 0x0000ff00, 1),
5205 "Clear with count = 1, rect = NULL has color %#08x.\n", color
);
5207 IDirectDrawSurface7_Release(rt
);
5208 IDirect3DDevice7_Release(device
);
5209 DestroyWindow(window
);
5212 static BOOL
test_mode_restored(IDirectDraw7
*ddraw
, HWND window
)
5214 DDSURFACEDESC2 ddsd1
, ddsd2
;
5217 memset(&ddsd1
, 0, sizeof(ddsd1
));
5218 ddsd1
.dwSize
= sizeof(ddsd1
);
5219 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd1
);
5220 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
5222 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5223 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5224 hr
= set_display_mode(ddraw
, 640, 480);
5225 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
5226 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5227 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5229 memset(&ddsd2
, 0, sizeof(ddsd2
));
5230 ddsd2
.dwSize
= sizeof(ddsd2
);
5231 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd2
);
5232 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
5233 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
5234 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
5236 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
5239 static void test_coop_level_versions(void)
5245 IDirectDrawSurface
*surface
;
5246 IDirectDraw7
*ddraw7
;
5249 window
= create_window();
5250 ddraw7
= create_ddraw();
5251 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5252 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
5253 restored
= test_mode_restored(ddraw7
, window
);
5254 ok(restored
, "Display mode not restored in new ddraw object\n");
5256 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
5257 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5258 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5260 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5261 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
5262 restored
= test_mode_restored(ddraw7
, window
);
5263 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
5265 /* A successful one does */
5266 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5267 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5268 restored
= test_mode_restored(ddraw7
, window
);
5269 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
5271 IDirectDraw_Release(ddraw
);
5272 IDirectDraw7_Release(ddraw7
);
5274 ddraw7
= create_ddraw();
5275 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5276 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5277 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5279 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
5280 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5281 restored
= test_mode_restored(ddraw7
, window
);
5282 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
5284 IDirectDraw_Release(ddraw
);
5285 IDirectDraw7_Release(ddraw7
);
5287 /* A failing call does not restore the ddraw2+ behavior */
5288 ddraw7
= create_ddraw();
5289 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5290 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5291 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5293 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5294 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5295 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5296 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
5297 restored
= test_mode_restored(ddraw7
, window
);
5298 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
5300 IDirectDraw_Release(ddraw
);
5301 IDirectDraw7_Release(ddraw7
);
5303 /* Neither does a sequence of successful calls with the new interface */
5304 ddraw7
= create_ddraw();
5305 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5306 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5307 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5309 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5310 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5311 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5312 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5313 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
5314 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5316 restored
= test_mode_restored(ddraw7
, window
);
5317 ok(!restored
, "Display mode restored after ddraw1-ddraw7 SetCooperativeLevel() call sequence\n");
5318 IDirectDraw_Release(ddraw
);
5319 IDirectDraw7_Release(ddraw7
);
5321 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
5322 ddraw7
= create_ddraw();
5323 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5324 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5325 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5327 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
5328 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5330 memset(&ddsd
, 0, sizeof(ddsd
));
5331 ddsd
.dwSize
= sizeof(ddsd
);
5332 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5333 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5334 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
5335 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5336 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
5337 IDirectDrawSurface_Release(surface
);
5338 restored
= test_mode_restored(ddraw7
, window
);
5339 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
5341 IDirectDraw_Release(ddraw
);
5342 IDirectDraw7_Release(ddraw7
);
5343 DestroyWindow(window
);
5346 static void test_fog_special(void)
5350 struct vec3 position
;
5355 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
5356 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00},
5357 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
5358 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
5362 DWORD vertexmode
, tablemode
;
5363 D3DCOLOR color_left
, color_right
;
5367 {D3DFOG_LINEAR
, D3DFOG_NONE
, 0x00ff0000, 0x00ff0000},
5368 {D3DFOG_NONE
, D3DFOG_LINEAR
, 0x0000ff00, 0x00ff0000},
5379 IDirect3DDevice7
*device
;
5380 IDirectDrawSurface7
*rt
;
5382 window
= create_window();
5383 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5385 skip("Failed to create a 3D device, skipping test.\n");
5386 DestroyWindow(window
);
5390 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5391 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5393 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
5394 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
5395 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0xffff0000);
5396 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
5397 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
5398 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
5399 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5400 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
5403 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGSTART
, conv
.d
);
5404 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
5405 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGEND
, conv
.d
);
5406 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
5408 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5410 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 1.0f
, 0);
5411 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5413 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vertexmode
);
5414 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
5415 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tablemode
);
5416 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
5418 hr
= IDirect3DDevice7_BeginScene(device
);
5419 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5420 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
5421 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5422 hr
= IDirect3DDevice7_EndScene(device
);
5423 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5425 color
= get_surface_color(rt
, 310, 240);
5426 ok(compare_color(color
, tests
[i
].color_left
, 1),
5427 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
5428 color
= get_surface_color(rt
, 330, 240);
5429 ok(compare_color(color
, tests
[i
].color_right
, 1),
5430 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
5433 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
5434 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
5436 IDirectDrawSurface7_Release(rt
);
5437 IDirect3DDevice7_Release(device
);
5438 DestroyWindow(window
);
5441 static void test_lighting_interface_versions(void)
5443 IDirect3DDevice7
*device
;
5444 IDirectDrawSurface7
*rt
;
5451 D3DMATERIAL7 material
;
5452 static D3DVERTEX quad
[] =
5454 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5455 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5456 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5457 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5460 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
5463 struct vec3 position
;
5465 DWORD diffuse
, specular
;
5469 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5470 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5471 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5472 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5475 static D3DLVERTEX lquad
[] =
5477 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5478 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5479 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5480 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5483 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
5486 struct vec3 position
;
5487 DWORD diffuse
, specular
;
5488 struct vec2 texcoord
;
5492 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5493 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5494 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5495 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5498 static D3DTLVERTEX tlquad
[] =
5500 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5501 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5502 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5503 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5510 DWORD d3drs_lighting
, d3drs_specular
;
5516 /* Lighting is enabled when D3DFVF_XYZ is used and D3DRENDERSTATE_LIGHTING is
5517 * enabled. D3DDP_DONOTLIGHT is ignored. Lighting is also enabled when normals
5520 * Note that the specular result is 0x00000000 when lighting is on even if the
5521 * input vertex has specular color because D3DRENDERSTATE_COLORVERTEX is not
5525 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x00ffffff},
5526 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
5527 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5528 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5529 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x00ffffff},
5530 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
5531 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5532 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5535 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5536 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5537 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5538 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5539 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5540 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5541 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5542 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5545 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
5546 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x0000ff00},
5547 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5548 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5549 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
5550 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x0000ff00},
5551 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5552 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5555 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5556 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5557 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5558 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5559 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5560 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5561 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5562 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5565 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
5566 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
5567 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5568 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5569 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
5570 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
5571 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5572 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5575 window
= create_window();
5576 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5578 skip("Failed to create a 3D device, skipping test.\n");
5579 DestroyWindow(window
);
5583 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5584 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5586 memset(&material
, 0, sizeof(material
));
5587 U2(U3(material
).emissive
).g
= 1.0f
;
5588 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
5589 ok(SUCCEEDED(hr
), "Failed set material, hr %#x.\n", hr
);
5590 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5591 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
5593 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &rs
);
5594 ok(SUCCEEDED(hr
), "Failed to get lighting render state, hr %#x.\n", hr
);
5595 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_LIGHTING is %#x, expected TRUE.\n", rs
);
5596 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
5597 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
5598 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected FALSE.\n", rs
);
5600 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5602 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
5603 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5605 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
5606 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
5607 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
5608 tests
[i
].d3drs_specular
);
5609 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
5611 hr
= IDirect3DDevice7_BeginScene(device
);
5612 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5613 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
5614 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
5615 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5616 hr
= IDirect3DDevice7_EndScene(device
);
5617 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5619 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &rs
);
5620 ok(SUCCEEDED(hr
), "Failed to get lighting render state, hr %#x.\n", hr
);
5621 ok(rs
== tests
[i
].d3drs_lighting
, "D3DRENDERSTATE_LIGHTING is %#x, expected %#x.\n",
5622 rs
, tests
[i
].d3drs_lighting
);
5624 color
= get_surface_color(rt
, 320, 240);
5625 ok(compare_color(color
, tests
[i
].color
, 1),
5626 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
5627 color
, tests
[i
].color
, i
);
5630 IDirectDrawSurface7_Release(rt
);
5631 ref
= IDirect3DDevice7_Release(device
);
5632 ok(ref
== 0, "Device not properly released, refcount %u.\n", ref
);
5633 DestroyWindow(window
);
5639 IDirectDraw7
*ddraw
;
5642 } activateapp_testdata
;
5644 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
5646 if (message
== WM_ACTIVATEAPP
)
5648 if (activateapp_testdata
.ddraw
)
5651 activateapp_testdata
.received
= FALSE
;
5652 hr
= IDirectDraw7_SetCooperativeLevel(activateapp_testdata
.ddraw
,
5653 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
5654 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
5655 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
5657 activateapp_testdata
.received
= TRUE
;
5660 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
5663 static void test_coop_level_activateapp(void)
5665 IDirectDraw7
*ddraw
;
5669 DDSURFACEDESC2 ddsd
;
5670 IDirectDrawSurface7
*surface
;
5672 ddraw
= create_ddraw();
5673 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5675 wc
.lpfnWndProc
= activateapp_test_proc
;
5676 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
5677 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
5679 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
5680 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
5682 /* Exclusive with window already active. */
5683 SetForegroundWindow(window
);
5684 activateapp_testdata
.received
= FALSE
;
5685 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5686 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5687 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
5688 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5689 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5691 /* Exclusive with window not active. */
5692 SetForegroundWindow(GetDesktopWindow());
5693 activateapp_testdata
.received
= FALSE
;
5694 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5695 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5696 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5697 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5698 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5700 /* Normal with window not active, then exclusive with the same window. */
5701 SetForegroundWindow(GetDesktopWindow());
5702 activateapp_testdata
.received
= FALSE
;
5703 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5704 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5705 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
5706 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5707 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5708 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5709 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5710 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5712 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
5713 SetForegroundWindow(GetDesktopWindow());
5714 activateapp_testdata
.received
= FALSE
;
5715 activateapp_testdata
.ddraw
= ddraw
;
5716 activateapp_testdata
.window
= window
;
5717 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
5718 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5719 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5720 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5721 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5722 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5724 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
5725 * succeeding. Another switch to exclusive and back to normal is needed to release the
5726 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
5727 * WM_ACTIVATEAPP messages. */
5728 activateapp_testdata
.ddraw
= NULL
;
5729 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5730 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5731 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5732 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5734 /* Setting DDSCL_NORMAL with recursive invocation. */
5735 SetForegroundWindow(GetDesktopWindow());
5736 activateapp_testdata
.received
= FALSE
;
5737 activateapp_testdata
.ddraw
= ddraw
;
5738 activateapp_testdata
.window
= window
;
5739 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
5740 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5741 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5742 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5744 /* DDraw is in exclusive mode now. */
5745 memset(&ddsd
, 0, sizeof(ddsd
));
5746 ddsd
.dwSize
= sizeof(ddsd
);
5747 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5748 U5(ddsd
).dwBackBufferCount
= 1;
5749 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5750 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5751 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5752 IDirectDrawSurface7_Release(surface
);
5754 /* Recover again, just to be sure. */
5755 activateapp_testdata
.ddraw
= NULL
;
5756 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5757 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5758 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5759 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5761 DestroyWindow(window
);
5762 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
5763 IDirectDraw7_Release(ddraw
);
5766 static void test_texturemanage(void)
5768 IDirectDraw7
*ddraw
;
5770 DDSURFACEDESC2 ddsd
;
5771 IDirectDrawSurface7
*surface
;
5773 DDCAPS hal_caps
, hel_caps
;
5774 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
5777 DWORD caps_in
, caps2_in
;
5779 DWORD caps_out
, caps2_out
;
5783 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5785 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5787 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5789 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5791 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
5792 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
5793 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
5794 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
5795 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5796 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
5797 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5798 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
5800 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5802 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5804 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5806 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5808 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5810 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5812 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
5813 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
5814 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
5815 DDSCAPS_SYSTEMMEMORY
, 0},
5818 ddraw
= create_ddraw();
5819 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5820 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5821 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5823 memset(&hal_caps
, 0, sizeof(hal_caps
));
5824 hal_caps
.dwSize
= sizeof(hal_caps
);
5825 memset(&hel_caps
, 0, sizeof(hel_caps
));
5826 hel_caps
.dwSize
= sizeof(hel_caps
);
5827 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
5828 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5829 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
5831 skip("Managed textures not supported, skipping managed texture test.\n");
5832 IDirectDraw7_Release(ddraw
);
5836 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5838 memset(&ddsd
, 0, sizeof(ddsd
));
5839 ddsd
.dwSize
= sizeof(ddsd
);
5840 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5841 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
5842 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
5846 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5847 if (tests
[i
].hr
== DD_OK
&& is_ddraw64
&& (tests
[i
].caps_in
& DDSCAPS_TEXTURE
))
5848 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5850 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, tests
[i
].hr
);
5854 memset(&ddsd
, 0, sizeof(ddsd
));
5855 ddsd
.dwSize
= sizeof(ddsd
);
5856 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
5857 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5859 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
5860 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5861 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
5862 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
5863 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5864 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
5866 IDirectDrawSurface7_Release(surface
);
5869 IDirectDraw7_Release(ddraw
);
5872 #define SUPPORT_DXT1 0x01
5873 #define SUPPORT_DXT2 0x02
5874 #define SUPPORT_DXT3 0x04
5875 #define SUPPORT_DXT4 0x08
5876 #define SUPPORT_DXT5 0x10
5877 #define SUPPORT_YUY2 0x20
5878 #define SUPPORT_UYVY 0x40
5880 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5882 DWORD
*supported_fmts
= ctx
;
5884 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
5885 return DDENUMRET_OK
;
5887 switch (fmt
->dwFourCC
)
5889 case MAKEFOURCC('D','X','T','1'):
5890 *supported_fmts
|= SUPPORT_DXT1
;
5892 case MAKEFOURCC('D','X','T','2'):
5893 *supported_fmts
|= SUPPORT_DXT2
;
5895 case MAKEFOURCC('D','X','T','3'):
5896 *supported_fmts
|= SUPPORT_DXT3
;
5898 case MAKEFOURCC('D','X','T','4'):
5899 *supported_fmts
|= SUPPORT_DXT4
;
5901 case MAKEFOURCC('D','X','T','5'):
5902 *supported_fmts
|= SUPPORT_DXT5
;
5904 case MAKEFOURCC('Y','U','Y','2'):
5905 *supported_fmts
|= SUPPORT_YUY2
;
5907 case MAKEFOURCC('U','Y','V','Y'):
5908 *supported_fmts
|= SUPPORT_UYVY
;
5914 return DDENUMRET_OK
;
5917 static void test_block_formats_creation(void)
5919 HRESULT hr
, expect_hr
;
5920 unsigned int i
, j
, w
, h
;
5922 IDirectDraw7
*ddraw
;
5924 IDirect3DDevice7
*device
;
5925 IDirectDrawSurface7
*surface
;
5926 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
5927 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
5928 DDSURFACEDESC2 ddsd
;
5937 unsigned int block_width
;
5938 unsigned int block_height
;
5939 unsigned int block_size
;
5940 BOOL create_size_checked
, overlay
;
5944 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
5945 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
5946 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
5947 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
5948 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
5949 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
5950 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
5960 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
5961 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
5963 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
5964 * Other hw / drivers successfully create those surfaces. Ignore them, this
5965 * suggests that no game uses this, otherwise Nvidia would support it. */
5967 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
5968 "videomemory texture", FALSE
5971 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
5972 "videomemory overlay", TRUE
5975 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
5976 "systemmemory texture", FALSE
5979 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
5980 "managed texture", FALSE
5992 enum size_type size_type
;
5998 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5999 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6000 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
6001 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
6002 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
6003 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
6004 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
6005 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6006 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
6007 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
6008 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
6009 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
6010 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DDERR_INVALIDPARAMS
},
6011 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DDERR_INVALIDPARAMS
},
6014 window
= create_window();
6015 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6017 skip("Failed to create a 3D device, skipping test.\n");
6018 DestroyWindow(window
);
6022 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
6023 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6024 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **) &ddraw
);
6025 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6026 IDirect3D7_Release(d3d
);
6028 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
6030 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
6032 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
6033 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
6034 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
6035 num_fourcc_codes
* sizeof(*fourcc_codes
));
6038 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
6039 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
6040 for (i
= 0; i
< num_fourcc_codes
; i
++)
6042 for (j
= 0; j
< ARRAY_SIZE(formats
); ++j
)
6044 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
6045 supported_overlay_fmts
|= formats
[j
].support_flag
;
6048 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
6050 memset(&hal_caps
, 0, sizeof(hal_caps
));
6051 hal_caps
.dwSize
= sizeof(hal_caps
);
6052 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
6053 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
6055 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
6057 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
6059 for (j
= 0; j
< ARRAY_SIZE(types
); ++j
)
6063 if (formats
[i
].overlay
!= types
[j
].overlay
6064 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
6067 if (formats
[i
].overlay
)
6068 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
6070 support
= supported_fmts
& formats
[i
].support_flag
;
6072 for (w
= 1; w
<= 8; w
++)
6074 for (h
= 1; h
<= 8; h
++)
6076 BOOL block_aligned
= TRUE
;
6079 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
6080 block_aligned
= FALSE
;
6082 memset(&ddsd
, 0, sizeof(ddsd
));
6083 ddsd
.dwSize
= sizeof(ddsd
);
6084 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
6085 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
6086 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
6087 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6088 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
6089 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
6093 /* TODO: Handle power of two limitations. I cannot test the pow2
6094 * behavior on windows because I have no hardware that doesn't at
6095 * least support np2_conditional. There's probably no HW that
6096 * supports DXTN textures but no conditional np2 textures. */
6097 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
6098 expect_hr
= DDERR_INVALIDPARAMS
;
6099 else if (formats
[i
].create_size_checked
&& !block_aligned
)
6101 expect_hr
= DDERR_INVALIDPARAMS
;
6102 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
6108 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6111 "Got unexpected hr %#x for format %s, resource type %s, size %ux%u, expected %#x.\n",
6112 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
6115 IDirectDrawSurface7_Release(surface
);
6120 if (formats
[i
].overlay
)
6123 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
6125 memset(&ddsd
, 0, sizeof(ddsd
));
6126 ddsd
.dwSize
= sizeof(ddsd
);
6127 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
6128 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
6130 switch (user_mem_tests
[j
].size_type
)
6132 case SIZE_TYPE_ZERO
:
6133 U1(ddsd
).dwLinearSize
= 0;
6136 case SIZE_TYPE_PITCH
:
6137 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
6140 case SIZE_TYPE_SIZE
:
6141 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
6144 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
6146 ddsd
.lpSurface
= mem
;
6147 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6148 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
6149 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
6153 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6154 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#x, format %s.\n", j
, hr
, formats
[i
].name
);
6159 memset(&ddsd
, 0, sizeof(ddsd
));
6160 ddsd
.dwSize
= sizeof(ddsd
);
6161 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
6162 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", j
, hr
);
6163 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
6164 "Test %u: Got unexpected flags %#x.\n", j
, ddsd
.dwFlags
);
6165 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
6166 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#x.\n",
6167 j
, U1(ddsd
).dwLinearSize
);
6169 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
6170 "Test %u: Got unexpected linear size %#x, expected %#x.\n",
6171 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
6172 IDirectDrawSurface7_Release(surface
);
6176 HeapFree(GetProcessHeap(), 0, mem
);
6178 IDirectDraw7_Release(ddraw
);
6179 IDirect3DDevice7_Release(device
);
6180 DestroyWindow(window
);
6183 struct format_support_check
6185 const DDPIXELFORMAT
*format
;
6189 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
6191 struct format_support_check
*format
= ctx
;
6193 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
6195 format
->supported
= TRUE
;
6196 return DDENUMRET_CANCEL
;
6199 return DDENUMRET_OK
;
6202 static void test_unsupported_formats(void)
6205 BOOL expect_success
;
6207 IDirectDraw7
*ddraw
;
6209 IDirect3DDevice7
*device
;
6210 IDirectDrawSurface7
*surface
;
6211 DDSURFACEDESC2 ddsd
;
6213 DWORD expected_caps
;
6224 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
6225 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
6231 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6232 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
6236 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
6238 window
= create_window();
6239 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6241 skip("Failed to create a 3D device, skipping test.\n");
6242 DestroyWindow(window
);
6246 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
6247 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6248 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **) &ddraw
);
6249 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6250 IDirect3D7_Release(d3d
);
6252 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
6254 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
6255 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
6256 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
6258 for (j
= 0; j
< ARRAY_SIZE(caps
); ++j
)
6260 memset(&ddsd
, 0, sizeof(ddsd
));
6261 ddsd
.dwSize
= sizeof(ddsd
);
6262 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6263 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
6266 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
6268 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
6269 expect_success
= FALSE
;
6271 expect_success
= TRUE
;
6273 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6274 ok(SUCCEEDED(hr
) == expect_success
,
6275 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
6276 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
6280 memset(&ddsd
, 0, sizeof(ddsd
));
6281 ddsd
.dwSize
= sizeof(ddsd
);
6282 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
6283 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6285 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
6286 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6287 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
6288 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6289 else if (check
.supported
)
6290 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6292 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6294 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
6295 "Expected capability %#x, format %s, input cap %#x.\n",
6296 expected_caps
, formats
[i
].name
, caps
[j
]);
6298 IDirectDrawSurface7_Release(surface
);
6302 IDirectDraw7_Release(ddraw
);
6303 IDirect3DDevice7_Release(device
);
6304 DestroyWindow(window
);
6307 static void test_rt_caps(const GUID
*device_guid
)
6309 PALETTEENTRY palette_entries
[256];
6310 IDirectDrawPalette
*palette
;
6311 BOOL software_device
;
6312 IDirectDraw7
*ddraw
;
6313 DDPIXELFORMAT z_fmt
;
6321 static const DDPIXELFORMAT p8_fmt
=
6323 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6324 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
6329 const DDPIXELFORMAT
*pf
;
6332 HRESULT create_device_hr
;
6333 HRESULT set_rt_hr
, alternative_set_rt_hr
;
6339 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6347 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6355 DDSCAPS_OFFSCREENPLAIN
,
6363 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6365 D3DERR_SURFACENOTINVIDMEM
,
6366 DDERR_INVALIDPARAMS
,
6371 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6379 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6403 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6405 D3DERR_SURFACENOTINVIDMEM
,
6406 DDERR_INVALIDPARAMS
,
6411 DDSCAPS_SYSTEMMEMORY
,
6419 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6420 DDSCAPS2_TEXTUREMANAGE
,
6421 D3DERR_SURFACENOTINVIDMEM
,
6422 DDERR_INVALIDPARAMS
,
6427 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6428 DDSCAPS2_D3DTEXTUREMANAGE
,
6429 D3DERR_SURFACENOTINVIDMEM
,
6430 DDERR_INVALIDPARAMS
,
6443 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6445 DDERR_NOPALETTEATTACHED
,
6451 DDSCAPS_OFFSCREENPLAIN
,
6459 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6461 DDERR_NOPALETTEATTACHED
,
6467 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6475 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
6478 DDERR_INVALIDPIXELFORMAT
,
6479 DDERR_INVALIDPIXELFORMAT
,
6483 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6486 DDERR_INVALIDPIXELFORMAT
,
6487 DDERR_INVALIDPIXELFORMAT
,
6499 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6502 DDERR_INVALIDPARAMS
,
6503 DDERR_INVALIDPIXELFORMAT
,
6507 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
6515 software_device
= is_software_device_type(device_guid
);
6517 window
= create_window();
6518 ddraw
= create_ddraw();
6519 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6520 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6521 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6523 if (FAILED(IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
)))
6525 skip("D3D interface is not available, skipping test.\n");
6529 memset(&z_fmt
, 0, sizeof(z_fmt
));
6530 hr
= IDirect3D7_EnumZBufferFormats(d3d
, device_guid
, enum_z_fmt
, &z_fmt
);
6531 if (FAILED(hr
) || !z_fmt
.dwSize
)
6533 skip("No depth buffer formats available, software_device %u, skipping test.\n", software_device
);
6534 IDirect3D7_Release(d3d
);
6538 memset(palette_entries
, 0, sizeof(palette_entries
));
6539 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6540 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6542 memset(&hal_caps
, 0, sizeof(hal_caps
));
6543 hal_caps
.dwSize
= sizeof(hal_caps
);
6544 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
6545 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6547 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6549 IDirectDrawSurface7
*surface
, *rt
, *expected_rt
, *tmp
;
6550 DDSURFACEDESC2 surface_desc
;
6551 DWORD caps_in
, expected_caps
;
6552 IDirect3DDevice7
*device
;
6553 HRESULT expected_hr
;
6555 caps_in
= test_data
[i
].caps_in
;
6557 memset(&surface_desc
, 0, sizeof(surface_desc
));
6558 surface_desc
.dwSize
= sizeof(surface_desc
);
6559 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6560 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
6561 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6562 if (test_data
[i
].pf
)
6564 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6565 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6567 surface_desc
.dwWidth
= 640;
6568 surface_desc
.dwHeight
= 480;
6569 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6570 expected_hr
= DDERR_NODIRECTDRAWHW
;
6572 expected_hr
= DD_OK
;
6573 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6574 ok(hr
== expected_hr
|| (software_device
&& (surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
))
6575 == (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
) && hr
== DDERR_UNSUPPORTED
)
6576 || broken(software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
),
6577 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6581 memset(&surface_desc
, 0, sizeof(surface_desc
));
6582 surface_desc
.dwSize
= sizeof(surface_desc
);
6583 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
6584 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6586 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || (test_data
[i
].caps2_in
& (DDSCAPS2_D3DTEXTUREMANAGE
6587 | DDSCAPS2_TEXTUREMANAGE
)) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6588 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
6590 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
6592 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
6593 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
6594 || (software_device
&& test_data
[i
].pf
== &z_fmt
6595 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
6596 "Got unexpected caps %#x, expected %#x, test %u, software_device %u.\n",
6597 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
6599 ok(surface_desc
.ddsCaps
.dwCaps2
== test_data
[i
].caps2_in
,
6600 "Got unexpected caps2 %#x, expected %#x, test %u, software_device %u.\n",
6601 surface_desc
.ddsCaps
.dwCaps2
, test_data
[i
].caps2_in
, i
, software_device
);
6603 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6604 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
6605 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
6606 ? DD_OK
: test_data
[i
].create_device_hr
))),
6607 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6610 if (hr
== DDERR_NOPALETTEATTACHED
)
6612 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
6613 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6614 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6615 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6616 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6617 hr
, i
, software_device
);
6618 else if (software_device
)
6620 ok(hr
== E_FAIL
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6621 hr
, i
, software_device
);
6623 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6624 hr
, i
, software_device
);
6626 IDirectDrawSurface7_Release(surface
);
6628 memset(&surface_desc
, 0, sizeof(surface_desc
));
6629 surface_desc
.dwSize
= sizeof(surface_desc
);
6630 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6631 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6632 surface_desc
.dwWidth
= 640;
6633 surface_desc
.dwHeight
= 480;
6634 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6635 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6637 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6638 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6641 memset(&surface_desc
, 0, sizeof(surface_desc
));
6642 surface_desc
.dwSize
= sizeof(surface_desc
);
6643 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6644 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6645 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6646 if (test_data
[i
].pf
)
6648 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6649 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6651 surface_desc
.dwWidth
= 640;
6652 surface_desc
.dwHeight
= 480;
6653 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
6654 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6656 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
6657 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
6658 || hr
== test_data
[i
].alternative_set_rt_hr
,
6659 "Got unexpected hr %#x, test %u, software_device %u.\n",
6660 hr
, i
, software_device
);
6661 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
6664 expected_rt
= surface
;
6666 hr
= IDirect3DDevice7_GetRenderTarget(device
, &tmp
);
6667 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6668 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
6670 IDirectDrawSurface7_Release(tmp
);
6671 IDirectDrawSurface7_Release(rt
);
6672 refcount
= IDirect3DDevice7_Release(device
);
6673 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
6674 refcount
= IDirectDrawSurface7_Release(surface
);
6675 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
6678 refcount
= IDirectDrawPalette_Release(palette
);
6679 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6680 IDirect3D7_Release(d3d
);
6683 refcount
= IDirectDraw7_Release(ddraw
);
6684 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6685 DestroyWindow(window
);
6688 static void test_primary_caps(void)
6690 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6691 IDirectDrawSurface7
*surface
;
6692 DDSURFACEDESC2 surface_desc
;
6693 IDirectDraw7
*ddraw
;
6703 DWORD back_buffer_count
;
6711 DDSCAPS_PRIMARYSURFACE
,
6714 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
6718 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
6725 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
6732 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
6739 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
6746 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
6753 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6760 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6767 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6769 DDERR_NOEXCLUSIVEMODE
,
6773 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6774 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6780 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6781 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6784 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
6787 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6788 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
6794 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6795 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
6802 window
= create_window();
6803 ddraw
= create_ddraw();
6804 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6806 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6808 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
6809 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6811 memset(&surface_desc
, 0, sizeof(surface_desc
));
6812 surface_desc
.dwSize
= sizeof(surface_desc
);
6813 surface_desc
.dwFlags
= DDSD_CAPS
;
6814 if (test_data
[i
].back_buffer_count
!= ~0u)
6815 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6816 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6817 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
6818 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6819 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
6823 memset(&surface_desc
, 0, sizeof(surface_desc
));
6824 surface_desc
.dwSize
= sizeof(surface_desc
);
6825 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
6826 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6827 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
6828 "Test %u: Got unexpected caps %#x, expected %#x.\n",
6829 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
6831 IDirectDrawSurface7_Release(surface
);
6834 refcount
= IDirectDraw7_Release(ddraw
);
6835 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6836 DestroyWindow(window
);
6839 static void test_surface_lock(void)
6841 IDirectDraw7
*ddraw
;
6842 IDirect3D7
*d3d
= NULL
;
6843 IDirectDrawSurface7
*surface
;
6844 IDirect3DDevice7
*device
;
6845 HRESULT hr
, expected_hr
;
6848 DDSURFACEDESC2 ddsd
;
6850 DDPIXELFORMAT z_fmt
;
6851 BOOL hal_ok
= FALSE
;
6852 const GUID
*devtype
= &IID_IDirect3DHALDevice
;
6853 D3DDEVICEDESC7 device_desc
;
6854 BOOL cubemap_supported
;
6864 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
6866 "videomemory offscreenplain"
6869 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6871 "systemmemory offscreenplain"
6874 DDSCAPS_PRIMARYSURFACE
,
6879 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6881 "videomemory texture"
6884 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6886 "opaque videomemory texture"
6889 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
6891 "systemmemory texture"
6895 DDSCAPS2_TEXTUREMANAGE
,
6900 DDSCAPS2_D3DTEXTUREMANAGE
,
6905 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6906 "opaque managed texture"
6910 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6911 "opaque managed texture"
6914 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6924 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_VIDEOMEMORY
,
6925 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6929 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_VIDEOMEMORY
,
6930 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6931 "opaque videomemory cube"
6934 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_SYSTEMMEMORY
,
6935 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6939 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6940 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6944 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6945 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6949 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6950 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6951 "opaque managed cube"
6954 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6955 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6956 "opaque managed cube"
6960 window
= create_window();
6961 ddraw
= create_ddraw();
6962 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6963 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6964 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6966 if (FAILED(IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
)))
6968 skip("D3D interface is not available, skipping test.\n");
6972 hr
= IDirect3D7_EnumDevices(d3d
, enum_devtype_cb
, &hal_ok
);
6973 ok(SUCCEEDED(hr
), "Failed to enumerate devices, hr %#x.\n", hr
);
6975 devtype
= &IID_IDirect3DTnLHalDevice
;
6977 memset(&z_fmt
, 0, sizeof(z_fmt
));
6978 hr
= IDirect3D7_EnumZBufferFormats(d3d
, devtype
, enum_z_fmt
, &z_fmt
);
6979 if (FAILED(hr
) || !z_fmt
.dwSize
)
6981 skip("No depth buffer formats available, skipping test.\n");
6985 memset(&ddsd
, 0, sizeof(ddsd
));
6986 ddsd
.dwSize
= sizeof(ddsd
);
6987 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6990 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6991 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6992 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6994 hr
= IDirect3D7_CreateDevice(d3d
, devtype
, surface
, &device
);
6995 ok(SUCCEEDED(hr
), "Failed to create device, hr %#x.\n", hr
);
6996 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
6997 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6998 cubemap_supported
= !!(device_desc
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
);
6999 IDirect3DDevice7_Release(device
);
7001 IDirectDrawSurface7_Release(surface
);
7003 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7005 if (!cubemap_supported
&& tests
[i
].caps2
& DDSCAPS2_CUBEMAP
)
7008 memset(&ddsd
, 0, sizeof(ddsd
));
7009 ddsd
.dwSize
= sizeof(ddsd
);
7010 ddsd
.dwFlags
= DDSD_CAPS
;
7011 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7013 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
7017 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
7019 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
7020 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
7022 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7023 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
7025 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7026 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
7028 memset(&ddsd
, 0, sizeof(ddsd
));
7029 ddsd
.dwSize
= sizeof(ddsd
);
7030 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7031 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
7034 ok(ddsd
.dwSize
== sizeof(ddsd
), "Got unexpected dwSize %u, type %s.\n", ddsd
.dwSize
, tests
[i
].name
);
7035 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7036 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
7039 memset(&ddsd
, 0, sizeof(ddsd
));
7040 expected_hr
= tests
[i
].caps
& DDSCAPS_TEXTURE
&& !(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
7041 ? DD_OK
: DDERR_INVALIDPARAMS
;
7042 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7043 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, type %s.\n", hr
, expected_hr
, tests
[i
].name
);
7046 ok(!ddsd
.dwSize
, "Got unexpected dwSize %u, type %s.\n", ddsd
.dwSize
, tests
[i
].name
);
7047 ok(!!ddsd
.lpSurface
, "Got NULL lpSurface, type %s.\n", tests
[i
].name
);
7048 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7049 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
7052 IDirectDrawSurface7_Release(surface
);
7057 IDirect3D7_Release(d3d
);
7058 refcount
= IDirectDraw7_Release(ddraw
);
7059 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
7060 DestroyWindow(window
);
7063 static void test_surface_discard(void)
7065 IDirect3DDevice7
*device
;
7067 IDirectDraw7
*ddraw
;
7070 DDSURFACEDESC2 ddsd
;
7071 IDirectDrawSurface7
*surface
, *target
;
7080 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
7081 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
7082 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
7083 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
7084 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
7085 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
7086 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
7087 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
7091 window
= create_window();
7093 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7097 /* Sigh. Anything other than the first run of the loop randomly fails with
7098 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
7099 * the blit fails, but with sleeps added between surface creation and lock
7100 * the lock can fail too. Interestingly ddraw claims the render target has
7101 * been lost, not the test surface.
7103 * Recreating ddraw every iteration seems to fix this. */
7104 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
7106 skip("Failed to create a 3D device, skipping test.\n");
7107 DestroyWindow(window
);
7110 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
7111 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
7112 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
7113 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
7114 hr
= IDirect3DDevice7_GetRenderTarget(device
, &target
);
7115 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
7117 memset(&ddsd
, 0, sizeof(ddsd
));
7118 ddsd
.dwSize
= sizeof(ddsd
);
7119 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7120 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7121 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
7124 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7125 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#x, case %u.\n", hr
, i
);
7127 memset(&ddsd
, 0, sizeof(ddsd
));
7128 ddsd
.dwSize
= sizeof(ddsd
);
7129 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7130 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7131 addr
= ddsd
.lpSurface
;
7132 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7133 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7135 memset(&ddsd
, 0, sizeof(ddsd
));
7136 ddsd
.dwSize
= sizeof(ddsd
);
7137 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7138 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7139 discarded
= ddsd
.lpSurface
!= addr
;
7140 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7141 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7143 hr
= IDirectDrawSurface7_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
7144 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
7146 memset(&ddsd
, 0, sizeof(ddsd
));
7147 ddsd
.dwSize
= sizeof(ddsd
);
7148 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7149 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7150 discarded
|= ddsd
.lpSurface
!= addr
;
7151 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7152 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7154 IDirectDrawSurface7_Release(surface
);
7156 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
7157 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
7158 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
7160 IDirectDrawSurface7_Release(target
);
7161 IDirectDraw7_Release(ddraw
);
7162 IDirect3D7_Release(d3d
);
7163 IDirect3DDevice7_Release(device
);
7166 DestroyWindow(window
);
7169 static void test_flip(void)
7171 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
7172 IDirectDrawSurface7
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
7173 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
7174 DDSURFACEDESC2 surface_desc
;
7175 D3DDEVICEDESC7 device_desc
;
7176 IDirect3DDevice7
*device
;
7177 BOOL sysmem_primary
;
7178 IDirectDraw7
*ddraw
;
7179 DWORD expected_caps
;
7193 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
7194 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
7195 {"TEXTURE", DDSCAPS_TEXTURE
},
7198 window
= create_window();
7199 ddraw
= create_ddraw();
7200 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7202 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7203 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7205 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7207 /* Creating a flippable texture induces a BSoD on some versions of the
7208 * Intel graphics driver. At least Intel GMA 950 with driver version
7209 * 6.14.10.4926 on Windows XP SP3 is affected. */
7210 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
7212 win_skip("Skipping flippable texture test.\n");
7216 memset(&surface_desc
, 0, sizeof(surface_desc
));
7217 surface_desc
.dwSize
= sizeof(surface_desc
);
7218 surface_desc
.dwFlags
= DDSD_CAPS
;
7219 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7220 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
7221 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7222 surface_desc
.dwWidth
= 512;
7223 surface_desc
.dwHeight
= 512;
7224 U5(surface_desc
).dwBackBufferCount
= 3;
7225 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7226 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7228 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
7229 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7230 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7231 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7233 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
7234 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
7235 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7236 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7238 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
7239 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7240 if (is_ddraw64
&& test_data
[i
].caps
& DDSCAPS_TEXTURE
)
7241 todo_wine
ok(hr
== E_NOINTERFACE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7242 else todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
7243 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
7247 memset(&surface_desc
, 0, sizeof(surface_desc
));
7248 surface_desc
.dwSize
= sizeof(surface_desc
);
7249 hr
= IDirectDrawSurface7_GetSurfaceDesc(frontbuffer
, &surface_desc
);
7250 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7251 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7252 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7253 expected_caps
|= DDSCAPS_VISIBLE
;
7254 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7255 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7256 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
7258 hr
= IDirectDrawSurface7_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
7259 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7260 memset(&surface_desc
, 0, sizeof(surface_desc
));
7261 surface_desc
.dwSize
= sizeof(surface_desc
);
7262 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer1
, &surface_desc
);
7263 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7264 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7265 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7266 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
7267 expected_caps
|= DDSCAPS_BACKBUFFER
;
7268 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7269 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7271 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
7272 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7273 memset(&surface_desc
, 0, sizeof(surface_desc
));
7274 surface_desc
.dwSize
= sizeof(surface_desc
);
7275 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer2
, &surface_desc
);
7276 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7277 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7278 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7279 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
7280 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7281 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7283 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
7284 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7285 memset(&surface_desc
, 0, sizeof(surface_desc
));
7286 surface_desc
.dwSize
= sizeof(surface_desc
);
7287 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer3
, &surface_desc
);
7288 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7289 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7290 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7291 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7292 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7294 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
7295 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7296 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
7297 test_data
[i
].name
, surface
, frontbuffer
);
7298 IDirectDrawSurface7_Release(surface
);
7300 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
7301 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
7302 hr
= IDirectDrawSurface7_IsLost(frontbuffer
);
7303 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7304 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7305 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7306 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7308 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7309 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7310 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
7311 hr
= IDirectDrawSurface7_IsLost(frontbuffer
);
7312 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7313 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
7314 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
7316 memset(&surface_desc
, 0, sizeof(surface_desc
));
7317 surface_desc
.dwSize
= sizeof(surface_desc
);
7318 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7319 surface_desc
.ddsCaps
.dwCaps
= 0;
7320 surface_desc
.dwWidth
= 640;
7321 surface_desc
.dwHeight
= 480;
7322 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7323 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
7324 hr
= IDirectDrawSurface7_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
7325 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7326 IDirectDrawSurface7_Release(surface
);
7328 hr
= IDirectDrawSurface7_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
7329 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7330 hr
= IDirectDrawSurface7_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
7331 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7332 hr
= IDirectDrawSurface7_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
7333 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7334 hr
= IDirectDrawSurface7_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
7335 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7337 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
7338 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
7339 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
7340 fill_surface(backbuffer1
, 0xffff0000);
7341 fill_surface(backbuffer2
, 0xff00ff00);
7342 fill_surface(backbuffer3
, 0xff0000ff);
7344 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7345 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7346 color
= get_surface_color(backbuffer1
, 320, 240);
7347 /* The testbot seems to just copy the contents of one surface to all the
7348 * others, instead of properly flipping. */
7349 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7350 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7351 color
= get_surface_color(backbuffer2
, 320, 240);
7352 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7353 fill_surface(backbuffer3
, 0xffff0000);
7355 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7356 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7357 color
= get_surface_color(backbuffer1
, 320, 240);
7358 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7359 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7360 color
= get_surface_color(backbuffer2
, 320, 240);
7361 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7362 fill_surface(backbuffer3
, 0xff00ff00);
7364 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7365 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7366 color
= get_surface_color(backbuffer1
, 320, 240);
7367 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7368 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7369 color
= get_surface_color(backbuffer2
, 320, 240);
7370 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7371 fill_surface(backbuffer3
, 0xff0000ff);
7373 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
7374 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7375 color
= get_surface_color(backbuffer2
, 320, 240);
7376 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7377 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7378 color
= get_surface_color(backbuffer3
, 320, 240);
7379 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7380 fill_surface(backbuffer1
, 0xffff0000);
7382 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
7383 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7384 color
= get_surface_color(backbuffer1
, 320, 240);
7385 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7386 color
= get_surface_color(backbuffer3
, 320, 240);
7387 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7388 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7389 fill_surface(backbuffer2
, 0xff00ff00);
7391 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
7392 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7393 color
= get_surface_color(backbuffer1
, 320, 240);
7394 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7395 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7396 color
= get_surface_color(backbuffer2
, 320, 240);
7397 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7399 IDirectDrawSurface7_Release(backbuffer3
);
7400 IDirectDrawSurface7_Release(backbuffer2
);
7401 IDirectDrawSurface7_Release(backbuffer1
);
7402 IDirectDrawSurface7_Release(frontbuffer
);
7405 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
7407 skip("Failed to create 3D device.\n");
7410 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
7411 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
7412 IDirect3DDevice7_Release(device
);
7413 if (!(device_desc
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
))
7415 skip("Cubemaps are not supported.\n");
7419 memset(&surface_desc
, 0, sizeof(surface_desc
));
7420 surface_desc
.dwSize
= sizeof(surface_desc
);
7421 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7422 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_TEXTURE
;
7423 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
7424 surface_desc
.dwWidth
= 128;
7425 surface_desc
.dwHeight
= 128;
7426 U5(surface_desc
).dwBackBufferCount
= 3;
7427 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7428 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7430 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
7431 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7432 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7433 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7435 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
7436 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
7437 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7438 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7440 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
7441 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7442 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7444 U5(surface_desc
).dwBackBufferCount
= 1;
7445 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7446 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7448 U5(surface_desc
).dwBackBufferCount
= 0;
7449 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7450 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7453 refcount
= IDirectDraw7_Release(ddraw
);
7454 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
7455 DestroyWindow(window
);
7458 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
7460 memset(ddsd
, 0, sizeof(*ddsd
));
7461 ddsd
->dwSize
= sizeof(*ddsd
);
7464 static void test_set_surface_desc(void)
7466 IDirectDraw7
*ddraw
;
7469 DDSURFACEDESC2 ddsd
;
7470 IDirectDrawSurface7
*surface
;
7480 invalid_caps_tests
[] =
7482 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
7483 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
7484 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
7485 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
7486 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
7489 window
= create_window();
7490 ddraw
= create_ddraw();
7491 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7492 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7493 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7496 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7499 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7500 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7501 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7502 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7503 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7504 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7505 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7507 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7508 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7511 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7512 ddsd
.lpSurface
= data
;
7513 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7514 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7516 /* Redundantly setting the same lpSurface is not an error. */
7517 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7518 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7520 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7521 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7522 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7523 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
7525 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7526 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7527 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7528 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
7529 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7530 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7533 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7534 ddsd
.lpSurface
= data
;
7535 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 1);
7536 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
7538 ddsd
.lpSurface
= NULL
;
7539 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7540 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
7542 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, NULL
, 0);
7543 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
7545 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7546 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7547 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7548 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
7549 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
7551 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
7552 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7553 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
7555 ddsd
.dwFlags
= DDSD_CAPS
;
7556 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7557 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7559 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
7560 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
7561 ddsd
.lpSurface
= data
;
7562 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7563 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7564 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7565 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7566 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7567 ddsd
.ddsCaps
.dwCaps
= 0;
7568 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
7569 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7570 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7572 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7573 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7574 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7575 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
7576 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
7578 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
7580 ddsd
.dwFlags
= DDSD_HEIGHT
;
7582 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7583 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
7585 ddsd
.lpSurface
= data
;
7586 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
7587 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7588 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7591 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7592 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
7595 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7596 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
7597 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
7598 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
7600 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
7602 ddsd
.dwFlags
= DDSD_PITCH
;
7603 U1(ddsd
).lPitch
= 8 * 4;
7604 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7605 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
7607 ddsd
.dwFlags
= DDSD_WIDTH
;
7609 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7610 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
7612 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
7613 ddsd
.lpSurface
= data
;
7614 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7615 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
7617 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
7618 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7619 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
7621 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7622 U1(ddsd
).lPitch
= 16 * 4;
7624 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7625 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7628 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7629 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7630 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
7631 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
7632 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
7634 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
7636 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
7637 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7638 U1(ddsd
).lPitch
= 4 * 4;
7639 ddsd
.lpSurface
= data
;
7640 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7641 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
7643 U1(ddsd
).lPitch
= 4;
7644 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7645 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
7647 U1(ddsd
).lPitch
= 16 * 4 + 1;
7648 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7649 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
7651 U1(ddsd
).lPitch
= 16 * 4 + 3;
7652 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7653 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
7655 U1(ddsd
).lPitch
= -4;
7656 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7657 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
7659 U1(ddsd
).lPitch
= 16 * 4;
7660 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7661 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7664 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7665 U1(ddsd
).lPitch
= 0;
7667 ddsd
.lpSurface
= data
;
7668 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7669 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
7671 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7672 U1(ddsd
).lPitch
= 16 * 4;
7674 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7675 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
7677 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
7678 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
7679 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7680 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7681 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7682 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7683 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7684 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7685 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7686 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
7688 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
7689 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7690 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7692 /* Can't set color keys. */
7694 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
7695 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
7696 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
7697 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7698 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7700 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
7701 ddsd
.lpSurface
= data
;
7702 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7703 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7705 IDirectDrawSurface7_Release(surface
);
7707 /* Test mipmap texture. */
7709 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7712 U2(ddsd
).dwMipMapCount
= 3;
7713 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7715 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7716 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
7720 skip("Mipmaps are not supported.\n");
7724 /* Changing surface desc for mipmap fails even without changing any
7726 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7727 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
7730 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7731 ddsd
.lpSurface
= data
;
7732 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7733 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
7734 IDirectDrawSurface7_Release(surface
);
7738 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7741 U2(ddsd
).dwMipMapCount
= 3;
7742 ddsd
.lpSurface
= data
;
7743 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7745 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7746 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
7750 static DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7751 void *surface2_system_mem
;
7752 IDirectDrawSurface7
*surface2
;
7754 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
7755 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7757 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface2
, &ddsd
);
7758 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7759 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %u.\n", ddsd
.dwWidth
);
7761 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7762 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7763 surface2_system_mem
= ddsd
.lpSurface
;
7764 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7767 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7770 U1(ddsd
).lPitch
= 16 * 4;
7771 ddsd
.lpSurface
= data
;
7772 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7773 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7776 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7779 U1(ddsd
).lPitch
= 8 * 4;
7780 ddsd
.lpSurface
= data
;
7781 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7782 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7785 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7786 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7787 ok(ddsd
.lpSurface
== surface2_system_mem
, "Got unexpected lpSurface %p.\n", ddsd
.lpSurface
);
7788 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7791 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7794 U1(ddsd
).lPitch
= 4 * 4;
7795 ddsd
.lpSurface
= data
;
7796 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface2
, &ddsd
, 0);
7797 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7800 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7801 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7802 ok(ddsd
.lpSurface
== data
, "Got unexpected lpSurface %p.\n", ddsd
.lpSurface
);
7803 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7806 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7809 U1(ddsd
).lPitch
= 16 * 4;
7810 ddsd
.lpSurface
= data
;
7811 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface2
, &ddsd
, 0);
7812 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7814 IDirectDrawSurface7_Release(surface2
);
7815 IDirectDrawSurface7_Release(surface
);
7818 /* Test surface created with DDSD_LPSURFACE. */
7820 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
7823 ddsd
.lpSurface
= data
;
7824 U1(ddsd
).lPitch
= 8 * 4;
7825 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7826 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7827 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7829 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7830 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7833 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
7836 /* Cannot reset lpSurface. */
7837 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7838 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7841 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_LPSURFACE
| DDSD_PITCH
;
7844 ddsd
.lpSurface
= data
;
7845 U1(ddsd
).lPitch
= 8 * 4;
7846 /* Can change the parameters of surface created with DDSD_LPSURFACE. */
7847 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7848 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7850 IDirectDrawSurface7_Release(surface
);
7852 /* SetSurfaceDesc needs systemmemory surfaces.
7854 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing
7855 * DDSD_LINEARSIZE is moot. */
7856 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); ++i
)
7859 ddsd
.dwFlags
= DDSD_CAPS
;
7860 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
7861 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
7862 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7864 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7867 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7868 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7869 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7870 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7871 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7872 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7875 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7876 if (is_ddraw64
&& (invalid_caps_tests
[i
].caps
& DDSCAPS_TEXTURE
))
7877 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7879 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7884 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7885 ddsd
.lpSurface
= data
;
7886 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7887 if (invalid_caps_tests
[i
].supported
)
7889 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7893 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7894 invalid_caps_tests
[i
].name
, hr
);
7896 /* Check priority of error conditions. */
7897 ddsd
.dwFlags
= DDSD_WIDTH
;
7898 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7899 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7900 invalid_caps_tests
[i
].name
, hr
);
7903 IDirectDrawSurface7_Release(surface
);
7906 ref
= IDirectDraw7_Release(ddraw
);
7907 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7908 DestroyWindow(window
);
7911 static void test_user_memory_getdc(void)
7913 IDirectDraw7
*ddraw
;
7916 DDSURFACEDESC2 ddsd
;
7917 IDirectDrawSurface7
*surface
;
7926 window
= create_window();
7927 ddraw
= create_ddraw();
7928 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7929 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7930 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7933 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7936 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7937 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7938 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7939 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7940 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7941 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7942 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7943 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7944 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7946 memset(data
, 0xaa, sizeof(data
));
7948 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7949 ddsd
.lpSurface
= data
;
7950 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7951 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7953 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
7954 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7955 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
7956 ok(!!bitmap
, "Failed to get bitmap.\n");
7957 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
7958 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
7959 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
7960 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
7961 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
7962 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
7963 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7965 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
7966 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
7968 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
7969 ddsd
.lpSurface
= data
;
7972 U1(ddsd
).lPitch
= sizeof(*data
);
7973 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7974 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7976 memset(data
, 0xaa, sizeof(data
));
7977 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
7978 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7979 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
7980 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
7981 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
7982 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7984 for (y
= 0; y
< 4; y
++)
7986 for (x
= 0; x
< 4; x
++)
7988 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
7989 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
7992 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
7996 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
7998 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
8000 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
8002 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
8005 IDirectDrawSurface7_Release(surface
);
8006 ref
= IDirectDraw7_Release(ddraw
);
8007 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8008 DestroyWindow(window
);
8011 static void test_sysmem_overlay(void)
8013 IDirectDraw7
*ddraw
;
8016 DDSURFACEDESC2 ddsd
;
8017 IDirectDrawSurface7
*surface
;
8020 window
= create_window();
8021 ddraw
= create_ddraw();
8022 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8023 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8024 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8027 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
8030 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
8031 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
8032 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8033 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8034 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8035 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8036 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8037 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8038 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
8040 ref
= IDirectDraw7_Release(ddraw
);
8041 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
8042 DestroyWindow(window
);
8045 static void test_primary_palette(void)
8047 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
8048 IDirectDrawSurface7
*primary
, *backbuffer
;
8049 PALETTEENTRY palette_entries
[256];
8050 IDirectDrawPalette
*palette
, *tmp
;
8051 DDSURFACEDESC2 surface_desc
;
8052 IDirectDraw7
*ddraw
;
8058 window
= create_window();
8059 ddraw
= create_ddraw();
8060 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8061 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8063 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8064 IDirectDraw7_Release(ddraw
);
8065 DestroyWindow(window
);
8068 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8069 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8071 memset(&surface_desc
, 0, sizeof(surface_desc
));
8072 surface_desc
.dwSize
= sizeof(surface_desc
);
8073 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8074 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8075 U5(surface_desc
).dwBackBufferCount
= 1;
8076 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8077 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8078 hr
= IDirectDrawSurface7_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
8079 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
8081 memset(palette_entries
, 0, sizeof(palette_entries
));
8082 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
8083 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8084 refcount
= get_refcount((IUnknown
*)palette
);
8085 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8087 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8088 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
8089 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
8091 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
8092 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8094 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
8095 * and is generally somewhat broken with respect to 8 bpp / palette
8097 if (SUCCEEDED(IDirectDrawSurface7_GetPalette(backbuffer
, &tmp
)))
8099 win_skip("Broken palette handling detected, skipping tests.\n");
8100 IDirectDrawPalette_Release(tmp
);
8101 IDirectDrawPalette_Release(palette
);
8102 /* The Windows 8 testbot keeps extra references to the primary and
8103 * backbuffer while in 8 bpp mode. */
8104 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
8105 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8109 refcount
= get_refcount((IUnknown
*)palette
);
8110 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8112 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8113 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
8114 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
8115 "Got unexpected palette caps %#x.\n", palette_caps
);
8117 hr
= IDirectDrawSurface7_SetPalette(primary
, NULL
);
8118 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8119 refcount
= get_refcount((IUnknown
*)palette
);
8120 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8122 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8123 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
8124 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
8126 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
8127 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8128 refcount
= get_refcount((IUnknown
*)palette
);
8129 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8131 hr
= IDirectDrawSurface7_GetPalette(primary
, &tmp
);
8132 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
8133 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
8134 IDirectDrawPalette_Release(tmp
);
8135 hr
= IDirectDrawSurface7_GetPalette(backbuffer
, &tmp
);
8136 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
8138 refcount
= IDirectDrawPalette_Release(palette
);
8139 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8140 refcount
= IDirectDrawPalette_Release(palette
);
8141 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8143 /* Note that this only seems to work when the palette is attached to the
8144 * primary surface. When attached to a regular surface, attempting to get
8145 * the palette here will cause an access violation. */
8146 hr
= IDirectDrawSurface7_GetPalette(primary
, &tmp
);
8147 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
8149 hr
= IDirectDrawSurface7_IsLost(primary
);
8150 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8152 memset(&surface_desc
, 0, sizeof(surface_desc
));
8153 surface_desc
.dwSize
= sizeof(surface_desc
);
8154 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8155 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8156 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8157 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8158 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
8159 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8161 hr
= set_display_mode(ddraw
, 640, 480);
8162 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8164 memset(&surface_desc
, 0, sizeof(surface_desc
));
8165 surface_desc
.dwSize
= sizeof(surface_desc
);
8166 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8167 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8168 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8169 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8170 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8171 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8172 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8174 hr
= IDirectDrawSurface7_IsLost(primary
);
8175 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8176 hr
= IDirectDrawSurface7_Restore(primary
);
8177 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
8178 hr
= IDirectDrawSurface7_IsLost(primary
);
8179 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8181 memset(&surface_desc
, 0, sizeof(surface_desc
));
8182 surface_desc
.dwSize
= sizeof(surface_desc
);
8183 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8184 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8185 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8186 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8187 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8188 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8189 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8192 refcount
= IDirectDrawSurface7_Release(backbuffer
);
8193 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8194 refcount
= IDirectDrawSurface7_Release(primary
);
8195 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8196 refcount
= IDirectDraw7_Release(ddraw
);
8197 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8198 DestroyWindow(window
);
8201 static HRESULT WINAPI
surface_counter(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
8203 UINT
*surface_count
= context
;
8206 IDirectDrawSurface_Release(surface
);
8208 return DDENUMRET_OK
;
8211 static void test_surface_attachment(void)
8213 IDirectDrawSurface7
*surface1
, *surface2
, *surface3
, *surface4
;
8214 IDirectDrawSurface
*surface1v1
, *surface2v1
;
8215 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
8216 DDSURFACEDESC2 surface_desc
;
8217 IDirectDraw7
*ddraw
;
8223 window
= create_window();
8224 ddraw
= create_ddraw();
8225 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8226 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8227 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8229 memset(&surface_desc
, 0, sizeof(surface_desc
));
8230 surface_desc
.dwSize
= sizeof(surface_desc
);
8231 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
8232 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8233 U2(surface_desc
).dwMipMapCount
= 3;
8234 surface_desc
.dwWidth
= 128;
8235 surface_desc
.dwHeight
= 128;
8236 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
)))
8238 skip("Failed to create a texture, skipping tests.\n");
8239 IDirectDraw7_Release(ddraw
);
8240 DestroyWindow(window
);
8244 hr
= IDirectDrawSurface7_GetAttachedSurface(surface1
, &caps
, &surface2
);
8245 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
8246 hr
= IDirectDrawSurface7_GetAttachedSurface(surface2
, &caps
, &surface3
);
8247 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
8248 hr
= IDirectDrawSurface7_GetAttachedSurface(surface3
, &caps
, &surface4
);
8249 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8252 IDirectDrawSurface7_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
8253 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8255 IDirectDrawSurface7_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
8256 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8258 IDirectDrawSurface7_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
8259 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
8261 memset(&surface_desc
, 0, sizeof(surface_desc
));
8262 surface_desc
.dwSize
= sizeof(surface_desc
);
8263 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8264 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8265 surface_desc
.dwWidth
= 16;
8266 surface_desc
.dwHeight
= 16;
8267 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8268 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8270 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8271 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8272 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8273 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8274 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface4
);
8275 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8276 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface3
);
8277 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8278 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface4
);
8279 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8280 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface2
);
8281 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8283 IDirectDrawSurface7_Release(surface4
);
8285 memset(&surface_desc
, 0, sizeof(surface_desc
));
8286 surface_desc
.dwSize
= sizeof(surface_desc
);
8287 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8288 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8289 surface_desc
.dwWidth
= 16;
8290 surface_desc
.dwHeight
= 16;
8291 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8292 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8294 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8295 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8296 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8297 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8298 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface4
);
8299 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8300 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface3
);
8301 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8302 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface4
);
8303 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8304 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface2
);
8305 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8307 IDirectDrawSurface7_Release(surface4
);
8308 IDirectDrawSurface7_Release(surface3
);
8309 IDirectDrawSurface7_Release(surface2
);
8310 IDirectDrawSurface7_Release(surface1
);
8312 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8313 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8315 /* Try a single primary and two offscreen plain surfaces. */
8316 memset(&surface_desc
, 0, sizeof(surface_desc
));
8317 surface_desc
.dwSize
= sizeof(surface_desc
);
8318 surface_desc
.dwFlags
= DDSD_CAPS
;
8319 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8320 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8321 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8323 memset(&surface_desc
, 0, sizeof(surface_desc
));
8324 surface_desc
.dwSize
= sizeof(surface_desc
);
8325 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8326 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8327 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8328 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8329 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8330 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8332 memset(&surface_desc
, 0, sizeof(surface_desc
));
8333 surface_desc
.dwSize
= sizeof(surface_desc
);
8334 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8335 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8336 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8337 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8338 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8339 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8341 /* This one has a different size. */
8342 memset(&surface_desc
, 0, sizeof(surface_desc
));
8343 surface_desc
.dwSize
= sizeof(surface_desc
);
8344 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8345 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8346 surface_desc
.dwWidth
= 128;
8347 surface_desc
.dwHeight
= 128;
8348 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8349 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8351 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8352 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8353 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface1
);
8354 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8355 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface3
);
8356 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8357 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8358 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8359 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8360 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8362 IDirectDrawSurface7_Release(surface4
);
8363 IDirectDrawSurface7_Release(surface3
);
8364 IDirectDrawSurface7_Release(surface2
);
8365 IDirectDrawSurface7_Release(surface1
);
8367 /* Test depth surfaces of different sizes. */
8368 memset(&surface_desc
, 0, sizeof(surface_desc
));
8369 surface_desc
.dwSize
= sizeof(surface_desc
);
8370 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8371 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8372 surface_desc
.dwWidth
= 64;
8373 surface_desc
.dwHeight
= 64;
8374 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8375 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8377 memset(&surface_desc
, 0, sizeof(surface_desc
));
8378 surface_desc
.dwSize
= sizeof(surface_desc
);
8379 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
8380 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8381 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8382 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8383 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8384 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8385 surface_desc
.dwWidth
= 32;
8386 surface_desc
.dwHeight
= 32;
8387 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8388 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8389 surface_desc
.dwWidth
= 64;
8390 surface_desc
.dwHeight
= 64;
8391 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8392 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8393 surface_desc
.dwWidth
= 128;
8394 surface_desc
.dwHeight
= 128;
8395 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8396 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8398 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
8399 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8401 IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8402 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
8403 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#x.\n", hr
);
8404 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface3
);
8405 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#x.\n", hr
);
8406 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
8407 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8409 IDirectDrawSurface7_Release(surface4
);
8410 IDirectDrawSurface7_Release(surface3
);
8411 IDirectDrawSurface7_Release(surface2
);
8412 IDirectDrawSurface7_Release(surface1
);
8414 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
8415 memset(&surface_desc
, 0, sizeof(surface_desc
));
8416 surface_desc
.dwSize
= sizeof(surface_desc
);
8417 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8418 surface_desc
.dwWidth
= 64;
8419 surface_desc
.dwHeight
= 64;
8420 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8421 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8422 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
8423 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
8424 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
8425 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8426 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
8427 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8428 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8429 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8430 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8432 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8433 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8434 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8435 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8436 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8437 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8439 hr
= IDirectDrawSurface7_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
8440 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
8441 hr
= IDirectDrawSurface7_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
8442 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
8444 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8445 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8446 refcount
= get_refcount((IUnknown
*)surface2
);
8447 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8448 refcount
= get_refcount((IUnknown
*)surface2v1
);
8449 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8450 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8451 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
8452 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8453 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8454 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8455 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
8457 /* Attaching while already attached to other surface. */
8458 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface2
);
8459 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8460 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface3
, 0, surface2
);
8461 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8462 IDirectDrawSurface7_Release(surface3
);
8464 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8465 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8466 refcount
= get_refcount((IUnknown
*)surface2
);
8467 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8468 refcount
= get_refcount((IUnknown
*)surface2v1
);
8469 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8471 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
8472 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8473 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8474 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8475 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
8476 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8477 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8478 refcount
= IDirectDrawSurface7_Release(surface2
);
8479 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8480 refcount
= IDirectDrawSurface7_Release(surface1
);
8481 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8483 /* Automatic detachment on release. */
8484 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8485 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8486 refcount
= get_refcount((IUnknown
*)surface2v1
);
8487 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8488 refcount
= IDirectDrawSurface_Release(surface1v1
);
8489 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8490 refcount
= IDirectDrawSurface_Release(surface2v1
);
8491 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8492 refcount
= IDirectDraw7_Release(ddraw
);
8493 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8494 DestroyWindow(window
);
8497 static void test_private_data(void)
8499 IDirectDraw7
*ddraw
;
8500 IDirectDrawSurface7
*surface
, *surface2
;
8501 DDSURFACEDESC2 surface_desc
;
8502 ULONG refcount
, refcount2
, refcount3
;
8504 DWORD size
= sizeof(ptr
);
8507 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8508 DWORD data
[] = {1, 2, 3, 4};
8510 static const GUID ddraw_private_data_test_guid
=
8515 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
8517 static const GUID ddraw_private_data_test_guid2
=
8522 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
8525 window
= create_window();
8526 ddraw
= create_ddraw();
8527 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8528 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8529 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8531 reset_ddsd(&surface_desc
);
8532 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
8533 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
8534 surface_desc
.dwHeight
= 4;
8535 surface_desc
.dwWidth
= 4;
8536 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8537 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8539 /* NULL pointers are not valid, but don't cause a crash. */
8540 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
8541 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
8542 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8543 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
8544 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8545 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
8546 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8548 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
8549 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8550 0, DDSPD_IUNKNOWNPOINTER
);
8551 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8552 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8553 5, DDSPD_IUNKNOWNPOINTER
);
8554 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8555 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8556 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
8557 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8559 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
8560 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
8561 * erases the old content and returns an error. This behavior has
8562 * been fixed in d3d8 and d3d9. Unless an application is found
8563 * that depends on this we don't care about this behavior. */
8564 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8565 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8566 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8567 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8568 0, DDSPD_IUNKNOWNPOINTER
);
8569 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8571 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8572 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
8573 hr
= IDirectDrawSurface7_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8574 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
8576 refcount
= get_refcount((IUnknown
*)ddraw
);
8577 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8578 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8579 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8580 refcount2
= get_refcount((IUnknown
*)ddraw
);
8581 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
8583 hr
= IDirectDrawSurface7_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8584 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
8585 refcount2
= get_refcount((IUnknown
*)ddraw
);
8586 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
8588 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8589 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8590 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8591 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
8592 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
8593 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8594 refcount2
= get_refcount((IUnknown
*)ddraw
);
8595 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
8597 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8598 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8599 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8600 size
= 2 * sizeof(ptr
);
8601 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8602 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
8603 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8604 refcount2
= get_refcount(ptr
);
8605 /* Object is NOT addref'ed by the getter. */
8606 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
8607 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
8609 ptr
= (IUnknown
*)0xdeadbeef;
8611 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8612 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
8613 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8614 size
= 2 * sizeof(ptr
);
8615 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8616 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8617 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %u.\n", size
);
8619 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8620 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
8621 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8622 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8623 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
8624 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8626 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
8627 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8628 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8629 ok(size
== 0xdeadbabe, "Got unexpected size %u.\n", size
);
8630 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8631 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8633 refcount3
= IDirectDrawSurface7_Release(surface
);
8634 ok(!refcount3
, "Got unexpected refcount %u.\n", refcount3
);
8636 /* Destroying the surface frees the reference held on the private data. It also frees
8637 * the reference the surface is holding on its creating object. */
8638 refcount2
= get_refcount((IUnknown
*)ddraw
);
8639 ok(refcount2
== refcount
- 1, "Got unexpected refcount %u.\n", refcount2
);
8641 memset(&hal_caps
, 0, sizeof(hal_caps
));
8642 hal_caps
.dwSize
= sizeof(hal_caps
);
8643 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
8644 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8645 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
8648 reset_ddsd(&surface_desc
);
8649 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
8650 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8651 surface_desc
.dwHeight
= 4;
8652 surface_desc
.dwWidth
= 4;
8653 U2(surface_desc
).dwMipMapCount
= 2;
8654 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8655 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8656 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
8657 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
8659 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
8660 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8661 hr
= IDirectDrawSurface7_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8662 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8664 IDirectDrawSurface7_Release(surface2
);
8665 IDirectDrawSurface7_Release(surface
);
8668 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
8670 refcount
= IDirectDraw7_Release(ddraw
);
8671 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8672 DestroyWindow(window
);
8675 static void test_pixel_format(void)
8677 HWND window
, window2
= NULL
;
8678 HDC hdc
, hdc2
= NULL
;
8680 int format
, test_format
;
8681 PIXELFORMATDESCRIPTOR pfd
;
8682 IDirectDraw7
*ddraw
= NULL
;
8683 IDirectDrawClipper
*clipper
= NULL
;
8684 DDSURFACEDESC2 ddsd
;
8685 IDirectDrawSurface7
*primary
= NULL
, *offscreen
;
8689 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8690 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8693 skip("Failed to create window\n");
8697 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8698 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8700 hdc
= GetDC(window
);
8703 skip("Failed to get DC\n");
8708 hdc2
= GetDC(window2
);
8710 gl
= LoadLibraryA("opengl32.dll");
8711 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8713 format
= GetPixelFormat(hdc
);
8714 ok(format
== 0, "new window has pixel format %d\n", format
);
8716 ZeroMemory(&pfd
, sizeof(pfd
));
8717 pfd
.nSize
= sizeof(pfd
);
8719 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
8720 pfd
.iPixelType
= PFD_TYPE_RGBA
;
8721 pfd
.iLayerType
= PFD_MAIN_PLANE
;
8722 format
= ChoosePixelFormat(hdc
, &pfd
);
8725 skip("no pixel format available\n");
8729 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
8731 skip("failed to set pixel format\n");
8735 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
8737 skip("failed to set pixel format on second window\n");
8740 ReleaseDC(window2
, hdc2
);
8745 ddraw
= create_ddraw();
8746 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8748 test_format
= GetPixelFormat(hdc
);
8749 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8751 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8754 skip("Failed to set cooperative level, hr %#x.\n", hr
);
8758 test_format
= GetPixelFormat(hdc
);
8759 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8763 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
8764 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
8765 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
8766 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
8768 test_format
= GetPixelFormat(hdc
);
8769 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8771 test_format
= GetPixelFormat(hdc2
);
8772 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8775 memset(&ddsd
, 0, sizeof(ddsd
));
8776 ddsd
.dwSize
= sizeof(ddsd
);
8777 ddsd
.dwFlags
= DDSD_CAPS
;
8778 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8780 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
8781 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8783 test_format
= GetPixelFormat(hdc
);
8784 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8788 test_format
= GetPixelFormat(hdc2
);
8789 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8794 hr
= IDirectDrawSurface7_SetClipper(primary
, clipper
);
8795 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
8797 test_format
= GetPixelFormat(hdc
);
8798 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8800 test_format
= GetPixelFormat(hdc2
);
8801 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8804 memset(&ddsd
, 0, sizeof(ddsd
));
8805 ddsd
.dwSize
= sizeof(ddsd
);
8806 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8807 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8808 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
8809 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
8810 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8812 memset(&fx
, 0, sizeof(fx
));
8813 fx
.dwSize
= sizeof(fx
);
8814 hr
= IDirectDrawSurface7_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
8815 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
8817 test_format
= GetPixelFormat(hdc
);
8818 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8820 hr
= IDirectDrawSurface7_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
8821 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#x.\n", hr
);
8823 test_format
= GetPixelFormat(hdc
);
8824 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8828 test_format
= GetPixelFormat(hdc2
);
8829 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8832 IDirectDrawSurface7_Release(offscreen
);
8835 if (primary
) IDirectDrawSurface7_Release(primary
);
8836 if (clipper
) IDirectDrawClipper_Release(clipper
);
8837 if (ddraw
) IDirectDraw7_Release(ddraw
);
8838 if (gl
) FreeLibrary(gl
);
8839 if (hdc
) ReleaseDC(window
, hdc
);
8840 if (hdc2
) ReleaseDC(window2
, hdc2
);
8841 DestroyWindow(window
);
8842 if (window2
) DestroyWindow(window2
);
8845 static void test_create_surface_pitch(void)
8847 IDirectDrawSurface7
*surface
;
8848 DDSURFACEDESC2 surface_desc
;
8849 IDirectDraw7
*ddraw
;
8869 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8871 DDSD_PITCH
, 0x100, 0x100},
8872 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8873 DDSD_PITCH
, 0x104, DD_OK
,
8874 DDSD_PITCH
, 0x100, 0x100},
8875 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8876 DDSD_PITCH
, 0x0f8, DD_OK
,
8877 DDSD_PITCH
, 0x100, 0x100},
8878 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8879 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8881 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8883 DDSD_PITCH
, 0x100, 0x0fc},
8885 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8886 DDSD_PITCH
, 0x104, DD_OK
,
8887 DDSD_PITCH
, 0x100, 0x0fc},
8888 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8889 DDSD_PITCH
, 0x0f8, DD_OK
,
8890 DDSD_PITCH
, 0x100, 0x0fc},
8891 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8892 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
8893 DDSD_PITCH
, 0x100, 0x0fc},
8894 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8895 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
8897 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8898 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8899 DDSD_PITCH
, 0x100, 0x100},
8901 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8902 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
8904 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8905 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
8906 DDSD_PITCH
, 0x0fc, 0x0fc},
8907 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8908 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
8910 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8911 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
8913 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8914 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
8917 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8918 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
8919 DDSD_PITCH
, 0x100, 0x100},
8920 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8921 0, 0, DDERR_INVALIDCAPS
,
8923 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8925 DDSD_PITCH
, 0x100, 0 },
8926 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8927 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8929 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8930 0, 0, DDERR_INVALIDCAPS
,
8933 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8935 DDSD_PITCH
, 0x100, 0 },
8936 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8937 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8938 DDSD_PITCH
, 0x100, 0 },
8940 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
8942 window
= create_window();
8943 ddraw
= create_ddraw();
8944 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8945 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8946 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8948 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
8950 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8952 memset(&surface_desc
, 0, sizeof(surface_desc
));
8953 surface_desc
.dwSize
= sizeof(surface_desc
);
8954 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
8955 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8956 surface_desc
.dwWidth
= 63;
8957 surface_desc
.dwHeight
= 63;
8958 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
8959 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8960 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8961 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8962 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8963 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8964 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8965 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8966 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
8968 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
8969 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
8970 surface_desc
.lpSurface
= mem
;
8971 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8973 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
8975 if (is_ddraw64
&& (test_data
[i
].caps
& DDSCAPS_TEXTURE
) && SUCCEEDED(test_data
[i
].hr
))
8976 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
8978 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
8982 memset(&surface_desc
, 0, sizeof(surface_desc
));
8983 surface_desc
.dwSize
= sizeof(surface_desc
);
8984 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
8985 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
8986 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
8987 "Test %u: Got unexpected flags %#x, expected %#x.\n",
8988 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
8989 /* The pitch for textures seems to be implementation specific. */
8990 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
8992 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
8993 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
8994 "Test %u: Got unexpected pitch %u, expected %u.\n",
8995 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
8997 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
8998 "Test %u: Got unexpected pitch %u, expected %u.\n",
8999 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
9001 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
9003 IDirectDrawSurface7_Release(surface
);
9006 HeapFree(GetProcessHeap(), 0, mem
);
9007 refcount
= IDirectDraw7_Release(ddraw
);
9008 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9009 DestroyWindow(window
);
9012 static void test_mipmap(void)
9014 IDirectDrawSurface7
*surface
, *surface_base
, *surface_mip
;
9015 unsigned int i
, mipmap_count
;
9016 DDSURFACEDESC2 surface_desc
;
9017 IDirectDraw7
*ddraw
;
9021 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
9030 DWORD mipmap_count_in
;
9032 DWORD mipmap_count_out
;
9036 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
9037 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
9038 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
9039 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
9040 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 8},
9041 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 7},
9044 window
= create_window();
9045 ddraw
= create_ddraw();
9046 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9047 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9048 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9050 memset(&hal_caps
, 0, sizeof(hal_caps
));
9051 hal_caps
.dwSize
= sizeof(hal_caps
);
9052 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
9053 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9054 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
9057 skip("Mipmapped textures not supported, skipping tests.\n");
9058 IDirectDraw7_Release(ddraw
);
9059 DestroyWindow(window
);
9063 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9065 memset(&surface_desc
, 0, sizeof(surface_desc
));
9066 surface_desc
.dwSize
= sizeof(surface_desc
);
9067 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
9068 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9069 surface_desc
.dwWidth
= tests
[i
].width
;
9070 surface_desc
.dwHeight
= tests
[i
].height
;
9071 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
9072 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
9073 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9074 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
9078 memset(&surface_desc
, 0, sizeof(surface_desc
));
9079 surface_desc
.dwSize
= sizeof(surface_desc
);
9080 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
9081 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
9082 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
9083 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
9084 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
9085 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
9087 surface_base
= surface
;
9088 IDirectDrawSurface7_AddRef(surface_base
);
9089 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
9090 while (mipmap_count
> 1)
9092 hr
= IDirectDrawSurface7_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
9093 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#x.\n", i
, mipmap_count
, hr
);
9095 memset(&surface_desc
, 0, sizeof(surface_desc
));
9096 surface_desc
.dwSize
= sizeof(surface_desc
);
9097 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface_base
, &surface_desc
);
9098 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#x.\n", i
, mipmap_count
, hr
);
9099 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
9100 "Test %u, %u: Got unexpected flags %#x.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
9101 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
9102 "Test %u, %u: Got unexpected mipmap count %u.\n",
9103 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
9105 memset(&surface_desc
, 0, sizeof(surface_desc
));
9106 surface_desc
.dwSize
= sizeof(surface_desc
);
9107 hr
= IDirectDrawSurface7_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
9108 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
9109 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
9110 "Test %u, %u: unexpected change of mipmap count %u.\n",
9111 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
9112 memset(&surface_desc
, 0, sizeof(surface_desc
));
9113 surface_desc
.dwSize
= sizeof(surface_desc
);
9114 hr
= IDirectDrawSurface7_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
9115 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
9116 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
9117 "Test %u, %u: Child mipmap count unexpected %u\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
9118 IDirectDrawSurface7_Unlock(surface_mip
, NULL
);
9119 IDirectDrawSurface7_Unlock(surface_base
, NULL
);
9121 IDirectDrawSurface7_Release(surface_base
);
9122 surface_base
= surface_mip
;
9125 IDirectDrawSurface7_Release(surface_base
);
9127 IDirectDrawSurface7_Release(surface
);
9130 refcount
= IDirectDraw7_Release(ddraw
);
9131 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9132 DestroyWindow(window
);
9135 static void test_palette_complex(void)
9137 IDirectDrawSurface7
*surface
, *mipmap
, *tmp
;
9138 DDSURFACEDESC2 surface_desc
;
9139 IDirectDraw7
*ddraw
;
9140 IDirectDrawPalette
*palette
, *palette2
;
9144 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
9146 PALETTEENTRY palette_entries
[256];
9149 window
= create_window();
9150 ddraw
= create_ddraw();
9151 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9152 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9153 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9155 memset(&hal_caps
, 0, sizeof(hal_caps
));
9156 hal_caps
.dwSize
= sizeof(hal_caps
);
9157 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
9158 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9159 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
9162 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
9163 IDirectDraw7_Release(ddraw
);
9164 DestroyWindow(window
);
9168 memset(&surface_desc
, 0, sizeof(surface_desc
));
9169 surface_desc
.dwSize
= sizeof(surface_desc
);
9170 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9171 surface_desc
.dwWidth
= 128;
9172 surface_desc
.dwHeight
= 128;
9173 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9174 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9175 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9176 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9177 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9178 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9180 memset(palette_entries
, 0, sizeof(palette_entries
));
9181 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9182 palette_entries
, &palette
, NULL
);
9183 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9185 palette2
= (void *)0xdeadbeef;
9186 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette2
);
9187 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
9188 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
9189 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9190 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9191 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette2
);
9192 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
9193 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
9194 IDirectDrawPalette_Release(palette2
);
9197 IDirectDrawSurface7_AddRef(mipmap
);
9198 for (i
= 0; i
< 7; ++i
)
9200 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9201 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
9202 palette2
= (void *)0xdeadbeef;
9203 hr
= IDirectDrawSurface7_GetPalette(tmp
, &palette2
);
9204 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9205 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
9207 hr
= IDirectDrawSurface7_SetPalette(tmp
, palette
);
9208 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9210 hr
= IDirectDrawSurface7_GetPalette(tmp
, &palette2
);
9211 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9212 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
9214 /* Ddraw7 uses the palette of the mipmap for GetDC, just like previous
9215 * ddraw versions. Combined with the test results above this means no
9216 * palette is available. So depending on the driver either GetDC fails
9217 * or the DIB color table contains random data. */
9219 IDirectDrawSurface7_Release(mipmap
);
9223 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9224 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
9225 IDirectDrawSurface7_Release(mipmap
);
9226 refcount
= IDirectDrawSurface7_Release(surface
);
9227 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9229 /* Test DDERR_INVALIDPIXELFORMAT vs DDERR_NOTONMIPMAPSUBLEVEL. */
9230 memset(&surface_desc
, 0, sizeof(surface_desc
));
9231 surface_desc
.dwSize
= sizeof(surface_desc
);
9232 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9233 surface_desc
.dwWidth
= 128;
9234 surface_desc
.dwHeight
= 128;
9235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9236 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9237 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9238 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9239 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9240 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9241 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9242 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9243 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9245 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
9246 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
9247 hr
= IDirectDrawSurface7_SetPalette(mipmap
, palette
);
9248 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
9250 IDirectDrawSurface7_Release(mipmap
);
9251 refcount
= IDirectDrawSurface7_Release(surface
);
9252 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9253 refcount
= IDirectDrawPalette_Release(palette
);
9254 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9256 refcount
= IDirectDraw7_Release(ddraw
);
9257 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9258 DestroyWindow(window
);
9261 static void test_p8_blit(void)
9263 IDirectDrawSurface7
*src
, *dst
, *dst_p8
;
9264 DDSURFACEDESC2 surface_desc
;
9265 IDirectDraw7
*ddraw
;
9266 IDirectDrawPalette
*palette
, *palette2
;
9270 PALETTEENTRY palette_entries
[256];
9274 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
9275 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
9276 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
9277 static const D3DCOLOR expected
[] =
9279 0x00101010, 0x00010101, 0x00020202, 0x00030303,
9280 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
9284 window
= create_window();
9285 ddraw
= create_ddraw();
9286 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9287 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9288 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9289 is_warp
= ddraw_is_warp(ddraw
);
9291 memset(palette_entries
, 0, sizeof(palette_entries
));
9292 palette_entries
[1].peGreen
= 0xff;
9293 palette_entries
[2].peBlue
= 0xff;
9294 palette_entries
[3].peFlags
= 0xff;
9295 palette_entries
[4].peRed
= 0xff;
9296 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9297 palette_entries
, &palette
, NULL
);
9298 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9299 palette_entries
[1].peBlue
= 0xff;
9300 palette_entries
[2].peGreen
= 0xff;
9301 palette_entries
[3].peRed
= 0xff;
9302 palette_entries
[4].peFlags
= 0x0;
9303 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9304 palette_entries
, &palette2
, NULL
);
9305 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9307 memset(&surface_desc
, 0, sizeof(surface_desc
));
9308 surface_desc
.dwSize
= sizeof(surface_desc
);
9309 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9310 surface_desc
.dwWidth
= 8;
9311 surface_desc
.dwHeight
= 1;
9312 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9313 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9314 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9315 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9316 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9317 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9318 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
9319 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9320 hr
= IDirectDrawSurface7_SetPalette(dst_p8
, palette2
);
9321 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9323 memset(&surface_desc
, 0, sizeof(surface_desc
));
9324 surface_desc
.dwSize
= sizeof(surface_desc
);
9325 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9326 surface_desc
.dwWidth
= 8;
9327 surface_desc
.dwHeight
= 1;
9328 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9329 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9330 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9331 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9332 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9333 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9334 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9335 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9336 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9337 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9339 memset(&surface_desc
, 0, sizeof(surface_desc
));
9340 surface_desc
.dwSize
= sizeof(surface_desc
);
9341 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9342 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
9343 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
9344 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
9345 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
9347 hr
= IDirectDrawSurface7_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9348 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
9349 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
9350 hr
= IDirectDrawSurface7_Unlock(dst_p8
, NULL
);
9351 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
9353 fx
.dwSize
= sizeof(fx
);
9354 fx
.dwFillColor
= 0xdeadbeef;
9355 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
9356 ok(SUCCEEDED(hr
), "Failed to color fill %#x.\n", hr
);
9358 hr
= IDirectDrawSurface7_SetPalette(src
, palette
);
9359 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9360 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9361 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
9362 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
9363 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
9364 "Failed to blit, hr %#x.\n", hr
);
9368 for (x
= 0; x
< ARRAY_SIZE(expected
); ++x
)
9370 color
= get_surface_color(dst
, x
, 0);
9371 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
9372 * blits see below. */
9373 todo_wine
ok(compare_color(color
, expected
[x
], 0)
9374 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
9375 "Pixel %u: Got color %#x, expected %#x.\n",
9376 x
, color
, expected
[x
]);
9380 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
9381 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
9382 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
9383 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9385 hr
= IDirectDrawSurface7_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9386 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
9387 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
9388 * surface untouched. Error checking (DDBLT_KEYSRC without a key
9389 * for example) also works as expected.
9391 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
9392 * the display mode set to P8 doesn't help either. */
9393 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
9394 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
9395 "Got unexpected P8 color key blit result.\n");
9396 hr
= IDirectDrawSurface7_Unlock(dst_p8
, NULL
);
9397 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
9399 IDirectDrawSurface7_Release(src
);
9400 IDirectDrawSurface7_Release(dst
);
9401 IDirectDrawSurface7_Release(dst_p8
);
9402 IDirectDrawPalette_Release(palette
);
9403 IDirectDrawPalette_Release(palette2
);
9405 refcount
= IDirectDraw7_Release(ddraw
);
9406 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9407 DestroyWindow(window
);
9410 static void test_material(void)
9412 static const D3DCOLORVALUE null_color
;
9413 IDirect3DDevice7
*device
;
9414 D3DMATERIAL7 material
;
9419 window
= create_window();
9420 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9422 skip("Failed to create a 3D device, skipping test.\n");
9423 DestroyWindow(window
);
9427 hr
= IDirect3DDevice7_GetMaterial(device
, &material
);
9428 ok(SUCCEEDED(hr
), "Failed to get material, hr %#x.\n", hr
);
9429 ok(!memcmp(&U(material
).diffuse
, &null_color
, sizeof(null_color
)),
9430 "Got unexpected diffuse color {%.8e, %.8e, %.8e, %.8e}.\n",
9431 U1(U(material
).diffuse
).r
, U2(U(material
).diffuse
).g
,
9432 U3(U(material
).diffuse
).b
, U4(U(material
).diffuse
).a
);
9433 ok(!memcmp(&U1(material
).ambient
, &null_color
, sizeof(null_color
)),
9434 "Got unexpected ambient color {%.8e, %.8e, %.8e, %.8e}.\n",
9435 U1(U1(material
).ambient
).r
, U2(U1(material
).ambient
).g
,
9436 U3(U1(material
).ambient
).b
, U4(U1(material
).ambient
).a
);
9437 ok(!memcmp(&U2(material
).specular
, &null_color
, sizeof(null_color
)),
9438 "Got unexpected specular color {%.8e, %.8e, %.8e, %.8e}.\n",
9439 U1(U2(material
).specular
).r
, U2(U2(material
).specular
).g
,
9440 U3(U2(material
).specular
).b
, U4(U2(material
).specular
).a
);
9441 ok(!memcmp(&U3(material
).emissive
, &null_color
, sizeof(null_color
)),
9442 "Got unexpected emissive color {%.8e, %.8e, %.8e, %.8e}.\n",
9443 U1(U3(material
).emissive
).r
, U2(U3(material
).emissive
).g
,
9444 U3(U3(material
).emissive
).b
, U4(U3(material
).emissive
).a
);
9445 ok(U4(material
).power
== 0.0f
, "Got unexpected power %.8e.\n", U4(material
).power
);
9447 refcount
= IDirect3DDevice7_Release(device
);
9448 ok(!refcount
, "Device has %u references left.\n", refcount
);
9449 DestroyWindow(window
);
9452 static void test_palette_gdi(void)
9454 IDirectDrawSurface7
*surface
, *primary
;
9455 DDSURFACEDESC2 surface_desc
;
9456 IDirectDraw7
*ddraw
;
9457 IDirectDrawPalette
*palette
, *palette2
;
9461 PALETTEENTRY palette_entries
[256];
9467 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
9468 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
9469 * not the point of this test. */
9470 static const RGBQUAD expected1
[] =
9472 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9473 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
9475 static const RGBQUAD expected2
[] =
9477 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9478 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
9480 static const RGBQUAD expected3
[] =
9482 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
9483 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
9485 HPALETTE ddraw_palette_handle
;
9486 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
9487 RGBQUAD rgbquad
[255];
9488 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
9490 window
= create_window();
9491 ddraw
= create_ddraw();
9492 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9493 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9494 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9496 memset(&surface_desc
, 0, sizeof(surface_desc
));
9497 surface_desc
.dwSize
= sizeof(surface_desc
);
9498 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9499 surface_desc
.dwWidth
= 16;
9500 surface_desc
.dwHeight
= 16;
9501 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9502 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9503 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9504 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9505 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9508 /* Avoid colors from the Windows default palette. */
9509 memset(palette_entries
, 0, sizeof(palette_entries
));
9510 palette_entries
[1].peRed
= 0x01;
9511 palette_entries
[2].peGreen
= 0x02;
9512 palette_entries
[3].peBlue
= 0x03;
9513 palette_entries
[4].peRed
= 0x13;
9514 palette_entries
[4].peGreen
= 0x14;
9515 palette_entries
[4].peBlue
= 0x15;
9516 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9517 palette_entries
, &palette
, NULL
);
9518 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9520 /* If there is no palette assigned and the display mode is not 8 bpp, some
9521 * drivers refuse to create a DC while others allow it. If a DC is created,
9522 * the DIB color table is uninitialized and contains random colors. No error
9523 * is generated when trying to read pixels and random garbage is returned.
9525 * The most likely explanation is that if the driver creates a DC, it (or
9526 * the higher-level runtime) uses GetSystemPaletteEntries to find the
9527 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
9528 * contains uninitialized garbage. See comments below for the P8 case. */
9530 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9531 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9532 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9533 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9534 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9535 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9536 "Got unexpected palette %p, expected %p.\n",
9537 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9539 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9540 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9541 for (i
= 0; i
< ARRAY_SIZE(expected1
); ++i
)
9543 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
9544 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9545 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9546 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
9548 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9550 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9551 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9552 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9555 /* Update the palette while the DC is in use. This does not modify the DC. */
9556 palette_entries
[4].peRed
= 0x23;
9557 palette_entries
[4].peGreen
= 0x24;
9558 palette_entries
[4].peBlue
= 0x25;
9559 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
9560 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
9562 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9563 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9564 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9565 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9566 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9567 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9569 /* Neither does re-setting the palette. */
9570 hr
= IDirectDrawSurface7_SetPalette(surface
, NULL
);
9571 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9572 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9573 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9575 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9576 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9577 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9578 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9579 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9580 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9582 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9583 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9585 /* Refresh the DC. This updates the palette. */
9586 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9587 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9588 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9589 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9590 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9592 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9593 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9594 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9595 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9597 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9599 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9600 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9601 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9603 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9604 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9606 refcount
= IDirectDrawSurface7_Release(surface
);
9607 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9609 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
9610 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9611 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9613 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9614 IDirectDrawPalette_Release(palette
);
9615 IDirectDraw7_Release(ddraw
);
9616 DestroyWindow(window
);
9619 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
9621 memset(&surface_desc
, 0, sizeof(surface_desc
));
9622 surface_desc
.dwSize
= sizeof(surface_desc
);
9623 surface_desc
.dwFlags
= DDSD_CAPS
;
9624 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9625 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9626 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9628 memset(&fx
, 0, sizeof(fx
));
9629 fx
.dwSize
= sizeof(fx
);
9630 U5(fx
).dwFillColor
= 3;
9631 SetRect(&r
, 0, 0, 319, 479);
9632 hr
= IDirectDrawSurface7_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9633 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
9634 SetRect(&r
, 320, 0, 639, 479);
9635 U5(fx
).dwFillColor
= 4;
9636 hr
= IDirectDrawSurface7_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9637 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
9639 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
9640 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9641 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
9642 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9644 color
= GetPixel(dc
, 160, 240);
9645 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
9646 color
= GetPixel(dc
, 480, 240);
9647 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
9649 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9650 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9651 "Got unexpected palette %p, expected %p.\n",
9652 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9653 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
9655 /* The primary uses the system palette. In exclusive mode, the system palette matches
9656 * the ddraw palette attached to the primary, so the result is what you would expect
9657 * from a regular surface. Tests for the interaction between the ddraw palette and
9658 * the system palette are not included pending an application that depends on this.
9659 * The relation between those causes problems on Windows Vista and newer for games
9660 * like Age of Empires or StarcCaft. Don't emulate it without a real need. */
9661 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9662 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9663 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9665 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9666 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9667 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9668 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9670 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9672 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9673 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9674 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9676 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
9677 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9679 memset(&surface_desc
, 0, sizeof(surface_desc
));
9680 surface_desc
.dwSize
= sizeof(surface_desc
);
9681 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9682 surface_desc
.dwWidth
= 16;
9683 surface_desc
.dwHeight
= 16;
9684 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9685 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9686 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9688 /* Here the offscreen surface appears to use the primary's palette,
9689 * but in all likelihood it is actually the system palette. */
9690 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9691 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9692 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9693 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9694 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9696 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9697 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9698 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9699 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9701 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9703 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9704 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9705 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9707 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9708 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9710 /* On real hardware a change to the primary surface's palette applies immediately,
9711 * even on device contexts from offscreen surfaces that do not have their own
9712 * palette. On the testbot VMs this is not the case. Don't test this until we
9713 * know of an application that depends on this. */
9715 memset(palette_entries
, 0, sizeof(palette_entries
));
9716 palette_entries
[1].peBlue
= 0x40;
9717 palette_entries
[2].peRed
= 0x40;
9718 palette_entries
[3].peGreen
= 0x40;
9719 palette_entries
[4].peRed
= 0x12;
9720 palette_entries
[4].peGreen
= 0x34;
9721 palette_entries
[4].peBlue
= 0x56;
9722 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9723 palette_entries
, &palette2
, NULL
);
9724 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9725 hr
= IDirectDrawSurface7_SetPalette(surface
, palette2
);
9726 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9728 /* A palette assigned to the offscreen surface overrides the primary / system
9730 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9731 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9732 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9733 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9734 for (i
= 0; i
< ARRAY_SIZE(expected3
); ++i
)
9736 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
9737 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9738 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9739 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
9741 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9743 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9744 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9745 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9747 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9748 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9750 refcount
= IDirectDrawSurface7_Release(surface
);
9751 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9753 /* The Windows 8 testbot keeps extra references to the primary and
9754 * backbuffer while in 8 bpp mode. */
9755 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
9756 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9758 refcount
= IDirectDrawSurface7_Release(primary
);
9759 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9760 refcount
= IDirectDrawPalette_Release(palette2
);
9761 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9762 refcount
= IDirectDrawPalette_Release(palette
);
9763 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9764 refcount
= IDirectDraw7_Release(ddraw
);
9765 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9766 DestroyWindow(window
);
9769 static void test_palette_alpha(void)
9771 IDirectDrawSurface7
*surface
;
9772 DDSURFACEDESC2 surface_desc
;
9773 IDirectDraw7
*ddraw
;
9774 IDirectDrawPalette
*palette
;
9778 PALETTEENTRY palette_entries
[256];
9783 BOOL attach_allowed
;
9788 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
9789 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
9790 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
9793 window
= create_window();
9794 ddraw
= create_ddraw();
9795 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9796 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9798 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9799 IDirectDraw7_Release(ddraw
);
9800 DestroyWindow(window
);
9803 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9804 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9806 memset(palette_entries
, 0, sizeof(palette_entries
));
9807 palette_entries
[1].peFlags
= 0x42;
9808 palette_entries
[2].peFlags
= 0xff;
9809 palette_entries
[3].peFlags
= 0x80;
9810 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
9811 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9813 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9814 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9815 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9816 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9817 palette_entries
[0].peFlags
);
9818 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9819 palette_entries
[1].peFlags
);
9820 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9821 palette_entries
[2].peFlags
);
9822 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9823 palette_entries
[3].peFlags
);
9825 IDirectDrawPalette_Release(palette
);
9827 memset(palette_entries
, 0, sizeof(palette_entries
));
9828 palette_entries
[1].peFlags
= 0x42;
9829 palette_entries
[1].peRed
= 0xff;
9830 palette_entries
[2].peFlags
= 0xff;
9831 palette_entries
[3].peFlags
= 0x80;
9832 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
9833 palette_entries
, &palette
, NULL
);
9834 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9836 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9837 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9838 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9839 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9840 palette_entries
[0].peFlags
);
9841 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9842 palette_entries
[1].peFlags
);
9843 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9844 palette_entries
[2].peFlags
);
9845 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9846 palette_entries
[3].peFlags
);
9848 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
9850 memset(&surface_desc
, 0, sizeof(surface_desc
));
9851 surface_desc
.dwSize
= sizeof(surface_desc
);
9852 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
9853 surface_desc
.dwWidth
= 128;
9854 surface_desc
.dwHeight
= 128;
9855 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
9856 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9857 if (is_ddraw64
&& test_data
[i
].caps
& DDSCAPS_TEXTURE
)
9858 todo_wine
ok(hr
== E_NOINTERFACE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
9860 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
9864 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9865 if (test_data
[i
].attach_allowed
)
9866 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
9868 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9876 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9877 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9878 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
9879 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
9880 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
9881 rgbquad
.rgbRed
, test_data
[i
].name
);
9882 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
9883 rgbquad
.rgbGreen
, test_data
[i
].name
);
9884 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
9885 rgbquad
.rgbBlue
, test_data
[i
].name
);
9886 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
9887 rgbquad
.rgbReserved
, test_data
[i
].name
);
9888 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9889 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9891 IDirectDrawSurface7_Release(surface
);
9894 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
9895 memset(&surface_desc
, 0, sizeof(surface_desc
));
9896 surface_desc
.dwSize
= sizeof(surface_desc
);
9897 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9898 surface_desc
.dwWidth
= 128;
9899 surface_desc
.dwHeight
= 128;
9900 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9901 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9902 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9903 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9904 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9905 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9906 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9907 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9908 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9909 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9910 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
9911 IDirectDrawSurface7_Release(surface
);
9913 /* The Windows 8 testbot keeps extra references to the primary
9914 * while in 8 bpp mode. */
9915 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
9916 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9918 refcount
= IDirectDrawPalette_Release(palette
);
9919 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9920 refcount
= IDirectDraw7_Release(ddraw
);
9921 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9922 DestroyWindow(window
);
9925 static void test_vb_writeonly(void)
9927 IDirect3DDevice7
*device
;
9929 IDirect3DVertexBuffer7
*buffer
;
9932 D3DVERTEXBUFFERDESC desc
;
9934 static const struct vec4 quad
[] =
9936 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
9937 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
9938 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
9939 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
9942 window
= create_window();
9943 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9945 skip("Failed to create a 3D device, skipping test.\n");
9946 DestroyWindow(window
);
9950 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
9951 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9953 memset(&desc
, 0, sizeof(desc
));
9954 desc
.dwSize
= sizeof(desc
);
9955 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
9956 desc
.dwFVF
= D3DFVF_XYZRHW
;
9957 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
9958 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0);
9959 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
9961 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
9962 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9963 memcpy(ptr
, quad
, sizeof(quad
));
9964 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9965 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9967 hr
= IDirect3DDevice7_BeginScene(device
);
9968 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9969 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
9970 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9971 hr
= IDirect3DDevice7_EndScene(device
);
9972 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9974 hr
= IDirect3DVertexBuffer7_Lock(buffer
, 0, &ptr
, NULL
);
9975 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9976 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9977 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9978 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9980 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
9981 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9982 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9983 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9984 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9986 IDirect3DVertexBuffer7_Release(buffer
);
9987 IDirect3D7_Release(d3d
);
9988 IDirect3DDevice7_Release(device
);
9989 DestroyWindow(window
);
9992 static void test_lost_device(void)
9994 IDirectDrawSurface7
*sysmem_surface
, *vidmem_surface
;
9995 IDirectDrawSurface7
*surface
, *back_buffer
;
9996 DDSURFACEDESC2 surface_desc
;
9997 HWND window1
, window2
;
9998 IDirectDraw7
*ddraw
;
10004 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10005 0, 0, 640, 480, 0, 0, 0, 0);
10006 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10007 0, 0, 640, 480, 0, 0, 0, 0);
10008 ddraw
= create_ddraw();
10009 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10010 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10011 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10013 memset(&surface_desc
, 0, sizeof(surface_desc
));
10014 surface_desc
.dwSize
= sizeof(surface_desc
);
10015 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10016 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
10017 U5(surface_desc
).dwBackBufferCount
= 1;
10018 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10019 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10021 memset(&surface_desc
, 0, sizeof(surface_desc
));
10022 surface_desc
.dwSize
= sizeof(surface_desc
);
10023 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
10024 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10025 surface_desc
.dwWidth
= 100;
10026 surface_desc
.dwHeight
= 100;
10027 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
10028 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10030 memset(&surface_desc
, 0, sizeof(surface_desc
));
10031 surface_desc
.dwSize
= sizeof(surface_desc
);
10032 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10033 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
10034 surface_desc
.dwWidth
= 64;
10035 surface_desc
.dwHeight
= 64;
10036 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10037 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10038 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10039 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10040 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10041 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10042 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
10044 skip("Failed to create video memory surface, skipping related tests.\n");
10045 vidmem_surface
= NULL
;
10048 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10049 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10050 hr
= IDirectDrawSurface7_IsLost(surface
);
10051 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10052 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10053 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10054 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10055 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10056 if (vidmem_surface
)
10058 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10059 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10062 ret
= SetForegroundWindow(GetDesktopWindow());
10063 ok(ret
, "Failed to set foreground window.\n");
10064 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10065 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10066 hr
= IDirectDrawSurface7_IsLost(surface
);
10067 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10068 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10069 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10070 hr
= IDirectDrawSurface7_Restore(surface
);
10071 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
10072 hr
= IDirectDrawSurface7_IsLost(surface
);
10073 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10074 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10075 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10076 hr
= IDirectDrawSurface7_Restore(sysmem_surface
);
10077 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10078 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10079 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10080 if (vidmem_surface
)
10082 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10083 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10084 hr
= IDirectDrawSurface7_Restore(vidmem_surface
);
10085 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
10086 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10087 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10090 ret
= SetForegroundWindow(window1
);
10091 ok(ret
, "Failed to set foreground window.\n");
10092 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10093 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10094 hr
= IDirectDrawSurface7_IsLost(surface
);
10095 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10096 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10097 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10098 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10099 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10100 if (vidmem_surface
)
10102 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10103 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10106 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
10107 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10108 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10109 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10110 hr
= IDirectDrawSurface7_IsLost(surface
);
10111 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10112 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10113 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10114 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10115 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10116 if (vidmem_surface
)
10118 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10119 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10122 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
10123 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10124 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10125 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10126 hr
= IDirectDrawSurface7_IsLost(surface
);
10127 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10128 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10129 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10130 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10131 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10132 if (vidmem_surface
)
10134 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10135 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10138 /* Trying to restore the primary will crash, probably because flippable
10139 * surfaces can't exist in DDSCL_NORMAL. */
10140 IDirectDrawSurface7_Release(surface
);
10141 memset(&surface_desc
, 0, sizeof(surface_desc
));
10142 surface_desc
.dwSize
= sizeof(surface_desc
);
10143 surface_desc
.dwFlags
= DDSD_CAPS
;
10144 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10145 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10146 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10147 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10148 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10149 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
10150 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10152 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10153 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10154 hr
= IDirectDrawSurface7_IsLost(surface
);
10155 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10156 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10157 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10158 if (vidmem_surface
)
10160 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10161 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10164 ret
= SetForegroundWindow(GetDesktopWindow());
10165 ok(ret
, "Failed to set foreground window.\n");
10166 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10167 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10168 hr
= IDirectDrawSurface7_IsLost(surface
);
10169 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10170 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10171 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10172 if (vidmem_surface
)
10174 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10175 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10178 ret
= SetForegroundWindow(window1
);
10179 ok(ret
, "Failed to set foreground window.\n");
10180 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10181 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10182 hr
= IDirectDrawSurface7_IsLost(surface
);
10183 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10184 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10185 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10186 if (vidmem_surface
)
10188 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10189 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10192 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10193 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10194 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10195 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10196 hr
= IDirectDrawSurface7_IsLost(surface
);
10197 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10198 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10199 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10200 if (vidmem_surface
)
10202 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10203 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10206 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
10207 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10208 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10209 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10210 hr
= IDirectDrawSurface7_IsLost(surface
);
10211 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10212 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10213 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10214 if (vidmem_surface
)
10216 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10217 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10220 IDirectDrawSurface7_Release(surface
);
10221 memset(&surface_desc
, 0, sizeof(surface_desc
));
10222 surface_desc
.dwSize
= sizeof(surface_desc
);
10223 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10224 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
10225 U5(surface_desc
).dwBackBufferCount
= 1;
10226 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10227 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10229 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10230 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10231 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10232 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10233 hr
= IDirectDrawSurface7_IsLost(surface
);
10234 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10235 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10236 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10237 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10238 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10239 if (vidmem_surface
)
10241 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10242 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10245 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10246 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10247 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10248 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10249 hr
= IDirectDrawSurface7_IsLost(surface
);
10250 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10251 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10252 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10253 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10254 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10255 if (vidmem_surface
)
10257 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10258 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10261 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
10262 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10263 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10264 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10265 hr
= IDirectDrawSurface7_IsLost(surface
);
10266 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10267 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10268 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10269 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10270 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10271 if (vidmem_surface
)
10273 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10274 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10277 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
10278 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10279 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10280 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10281 hr
= IDirectDrawSurface7_IsLost(surface
);
10282 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10283 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10284 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10285 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10286 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10287 if (vidmem_surface
)
10289 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10290 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10293 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10294 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10295 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10296 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10297 hr
= IDirectDrawSurface7_IsLost(surface
);
10298 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10299 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10300 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10301 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10302 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10303 if (vidmem_surface
)
10305 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10306 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10309 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10310 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10311 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10312 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10313 hr
= IDirectDrawSurface7_IsLost(surface
);
10314 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10315 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10316 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10317 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10318 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10319 if (vidmem_surface
)
10321 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10322 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10325 memset(&caps
, 0, sizeof(caps
));
10326 caps
.dwCaps
= DDSCAPS_FLIP
;
10328 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10329 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10330 hr
= IDirectDrawSurface7_Restore(surface
);
10331 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10332 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10333 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10334 hr
= IDirectDrawSurface7_IsLost(back_buffer
);
10335 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10337 IDirectDrawSurface7_Release(back_buffer
);
10339 if (vidmem_surface
)
10340 IDirectDrawSurface7_Release(vidmem_surface
);
10341 IDirectDrawSurface7_Release(sysmem_surface
);
10342 IDirectDrawSurface7_Release(surface
);
10343 refcount
= IDirectDraw7_Release(ddraw
);
10344 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10345 DestroyWindow(window2
);
10346 DestroyWindow(window1
);
10349 static void test_resource_priority(void)
10351 IDirectDrawSurface7
*surface
, *mipmap
;
10352 DDSURFACEDESC2 surface_desc
;
10353 IDirectDraw7
*ddraw
;
10357 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
10359 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_MIPMAP
;
10362 static const struct
10367 /* SetPriority on offscreenplain surfaces crashes on AMD GPUs on Win7. */
10372 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", DDERR_INVALIDPARAMS
, FALSE
},
10373 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", DDERR_INVALIDPARAMS
, FALSE
},
10374 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", DD_OK
, FALSE
},
10375 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, "managed texture", DD_OK
, FALSE
},
10376 {DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
,
10377 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_TEXTUREMANAGE
,
10378 "cubemap", DD_OK
, FALSE
},
10379 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", DDERR_INVALIDOBJECT
, TRUE
},
10380 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", DDERR_INVALIDOBJECT
, TRUE
},
10383 window
= create_window();
10384 ddraw
= create_ddraw();
10385 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10386 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10387 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10389 memset(&hal_caps
, 0, sizeof(hal_caps
));
10390 hal_caps
.dwSize
= sizeof(hal_caps
);
10391 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
10392 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
10393 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
10394 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
10396 skip("Required surface types not supported, skipping test.\n");
10400 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10402 memset(&surface_desc
, 0, sizeof(surface_desc
));
10403 surface_desc
.dwSize
= sizeof(surface_desc
);
10404 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10405 surface_desc
.dwWidth
= 32;
10406 surface_desc
.dwHeight
= 32;
10407 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
10408 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2
;
10409 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10410 if (is_ddraw64
&& (test_data
[i
].caps
& DDSCAPS_TEXTURE
))
10412 todo_wine
ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10414 IDirectDrawSurface7_Release(surface
);
10417 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10419 /* Priority == NULL segfaults. */
10420 priority
= 0xdeadbeef;
10421 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10422 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10423 if (SUCCEEDED(test_data
[i
].hr
))
10424 ok(priority
== 0, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10426 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10428 if (!test_data
[i
].crash
)
10430 hr
= IDirectDrawSurface7_SetPriority(surface
, 1);
10431 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10432 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10433 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10434 if (SUCCEEDED(test_data
[i
].hr
))
10436 ok(priority
== 1, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10437 hr
= IDirectDrawSurface7_SetPriority(surface
, 2);
10438 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10441 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10444 if (test_data
[i
].caps2
& DDSCAPS2_CUBEMAP
)
10446 caps
.dwCaps2
= DDSCAPS2_CUBEMAP_NEGATIVEZ
;
10447 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
10448 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
10449 /* IDirectDrawSurface7_SetPriority crashes when called on non-positive X surfaces on Windows */
10450 priority
= 0xdeadbeef;
10451 hr
= IDirectDrawSurface7_GetPriority(mipmap
, &priority
);
10452 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10453 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10455 IDirectDrawSurface7_Release(mipmap
);
10458 IDirectDrawSurface7_Release(surface
);
10464 memset(&surface_desc
, 0, sizeof(surface_desc
));
10465 surface_desc
.dwSize
= sizeof(surface_desc
);
10466 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
10467 surface_desc
.dwWidth
= 32;
10468 surface_desc
.dwHeight
= 32;
10469 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
10470 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
10471 U2(surface_desc
).dwMipMapCount
= 2;
10472 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10473 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10475 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
10476 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
10478 priority
= 0xdeadbeef;
10479 hr
= IDirectDrawSurface7_GetPriority(mipmap
, &priority
);
10480 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type managed mipmap.\n", hr
);
10481 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type managed mipmap.\n", priority
);
10482 /* SetPriority on the mipmap surface crashes. */
10483 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10484 ok(SUCCEEDED(hr
), "Failed to get priority, hr %#x.\n", hr
);
10485 ok(priority
== 0, "Got unexpected priority %u, type managed mipmap.\n", priority
);
10487 IDirectDrawSurface7_Release(mipmap
);
10488 refcount
= IDirectDrawSurface7_Release(surface
);
10489 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10492 refcount
= IDirectDraw7_Release(ddraw
);
10493 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10494 DestroyWindow(window
);
10497 static void test_surface_desc_lock(void)
10499 IDirectDrawSurface7
*surface
;
10500 DDSURFACEDESC2 surface_desc
;
10501 IDirectDraw7
*ddraw
;
10506 window
= create_window();
10507 ddraw
= create_ddraw();
10508 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10509 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10510 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10512 memset(&surface_desc
, 0, sizeof(surface_desc
));
10513 surface_desc
.dwSize
= sizeof(surface_desc
);
10514 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
10515 surface_desc
.dwWidth
= 16;
10516 surface_desc
.dwHeight
= 16;
10517 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10518 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10519 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10521 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10522 surface_desc
.dwSize
= sizeof(surface_desc
);
10523 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10524 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10525 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10527 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10528 surface_desc
.dwSize
= sizeof(surface_desc
);
10529 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
10530 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10531 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10532 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10533 surface_desc
.dwSize
= sizeof(surface_desc
);
10534 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10535 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10536 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10537 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
10538 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10540 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10541 surface_desc
.dwSize
= sizeof(surface_desc
);
10542 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10543 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10544 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10546 IDirectDrawSurface7_Release(surface
);
10547 refcount
= IDirectDraw7_Release(ddraw
);
10548 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10549 DestroyWindow(window
);
10552 static void test_fog_interpolation(void)
10555 IDirect3DDevice7
*device
;
10556 IDirectDrawSurface7
*rt
;
10562 struct vec3 position
;
10568 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
10569 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
10570 {{ 1.0f
, -1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
10571 {{ 1.0f
, 1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
10579 static const struct
10581 D3DFOGMODE vfog
, tfog
;
10582 D3DSHADEMODE shade
;
10583 D3DCOLOR middle_color
;
10588 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, FALSE
},
10589 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, FALSE
},
10590 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, TRUE
},
10591 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, TRUE
},
10592 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
10593 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
10594 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
10595 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
10597 D3DDEVICEDESC7 caps
;
10599 window
= create_window();
10600 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10602 skip("Failed to create a 3D device, skipping test.\n");
10603 DestroyWindow(window
);
10607 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
10608 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10609 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
10610 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10611 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
10612 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
10614 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10615 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10616 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10617 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10618 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10619 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10620 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
10621 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10623 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGDENSITY
, conv
.d
);
10624 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10626 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10627 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10628 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
10629 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10630 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x000000ff);
10631 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10633 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10635 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
10638 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00808080, 0.0f
, 0);
10639 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10641 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shade
);
10642 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10643 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vfog
);
10644 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10645 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tfog
);
10646 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10647 hr
= IDirect3DDevice7_BeginScene(device
);
10648 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10649 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10650 D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, quad
, 4, 0);
10651 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10652 hr
= IDirect3DDevice7_EndScene(device
);
10653 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10655 color
= get_surface_color(rt
, 0, 240);
10656 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10657 color
= get_surface_color(rt
, 320, 240);
10658 todo_wine_if (tests
[i
].todo
)
10659 ok(compare_color(color
, tests
[i
].middle_color
, 2),
10660 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10661 color
= get_surface_color(rt
, 639, 240);
10662 ok(compare_color(color
, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10665 IDirectDrawSurface7_Release(rt
);
10666 refcount
= IDirect3DDevice7_Release(device
);
10667 ok(!refcount
, "Device has %u references left.\n", refcount
);
10668 DestroyWindow(window
);
10671 static void test_fog_process_vertices(void)
10673 static D3DMATRIX view_matrix
=
10675 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10676 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10677 0.0f
, 0.0f
, 0.5f
, 0.0f
,
10678 0.0f
, 0.0f
, 0.0f
, 1.0f
10680 static D3DMATRIX model_matrix
=
10682 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10683 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10684 0.0f
, 0.0f
, 0.75f
, 0.0f
,
10685 0.0f
, 0.0f
, 0.0f
, 1.0f
10687 static D3DMATRIX identity_matrix
=
10689 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10690 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10691 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10692 0.0f
, 0.0f
, 0.0f
, 1.0f
10695 static D3DLIGHT7 directional_light
=
10697 D3DLIGHT_DIRECTIONAL
,
10698 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
10699 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
10700 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
10701 {{0.0f
}, {0.0f
}, {0.0f
}},
10702 {{0.0f
}, {0.0f
}, {1.0f
}},
10707 struct vec3 position
;
10708 struct vec3 normal
;
10710 static const struct
10712 struct vertex vertex
;
10713 D3DFOGMODE fog_vertex_mode
, fog_table_mode
;
10715 D3DCOLOR expected_color
, expected_broken
;
10719 /* Some drivers ignore ranged fog state without an obvious reason, even with D3DPRASTERCAPS_FOGRANGE
10720 * set, while some others (including WARP driver on Windows 10) favour it.
10721 * Vertex fog result does not depend on table fog settings. */
10722 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_NONE
, FALSE
, 0x8000ff00},
10723 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, 0x8000ff00},
10724 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_NONE
, FALSE
, 0xaf00ff00},
10725 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP2
, D3DFOG_NONE
, FALSE
, 0xde00ff00},
10726 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, 0x9f00ff00},
10727 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_LINEAR
, FALSE
, 0x9f00ff00},
10728 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_NONE
, TRUE
, 0x8000ff00},
10729 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_NONE
, TRUE
, 0x8800ff00, 0xaf00ff00},
10730 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP2
, D3DFOG_NONE
, TRUE
, 0xad00ff00, 0xde00ff00},
10731 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, 0x6000ff00, 0x9f00ff00},
10732 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_EXP
, TRUE
, 0x6000ff00, 0x9f00ff00},
10733 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_LINEAR
, TRUE
, 0x8800ff00, 0xaf00ff00},
10738 struct vec4 position
;
10739 D3DCOLOR diffuse
, specular
;
10743 IDirect3DVertexBuffer7
*src_vb
, *dst_vb
;
10744 D3DVERTEXBUFFERDESC vb_desc
;
10745 IDirect3DDevice7
*device
;
10746 struct vertex
*src_data
;
10747 D3DMATERIAL7 material
;
10754 window
= create_window();
10755 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10757 skip("Failed to create a 3D device, skipping test.\n");
10758 DestroyWindow(window
);
10761 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
10762 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10764 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &model_matrix
);
10765 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10766 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view_matrix
);
10767 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10768 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity_matrix
);
10769 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10771 memset(&vb_desc
, 0, sizeof(vb_desc
));
10772 vb_desc
.dwSize
= sizeof(vb_desc
);
10773 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
10774 vb_desc
.dwNumVertices
= 1;
10775 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0);
10776 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10778 memset(&vb_desc
, 0, sizeof(vb_desc
));
10779 vb_desc
.dwSize
= sizeof(vb_desc
);
10780 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
10781 vb_desc
.dwNumVertices
= 1;
10782 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
10783 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10785 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
10786 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10787 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
10788 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10789 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
10790 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10791 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10792 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10793 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10794 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10796 hr
= IDirect3DDevice7_SetLight(device
, 0, &directional_light
);
10797 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10799 memset(&material
, 0, sizeof(material
));
10800 U1(U2(material
).specular
).r
= 0.0f
;
10801 U2(U2(material
).specular
).g
= 1.0f
;
10802 U3(U2(material
).specular
).b
= 0.0f
;
10803 U4(U2(material
).specular
).a
= 0.5f
;
10804 U4(material
).power
= 5.0f
;
10805 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
10806 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10808 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10810 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
,
10811 tests
[i
].fog_vertex_mode
);
10812 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
,
10813 tests
[i
].fog_table_mode
);
10814 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10815 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_RANGEFOGENABLE
, tests
[i
].range_fog
);
10816 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10818 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
10819 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10820 *src_data
= tests
[i
].vertex
;
10821 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
10822 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10824 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
10825 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10826 memset(dst_data
, 0, sizeof(*dst_data
));
10827 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
10828 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10829 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
10830 1, src_vb
, 0, device
, 0);
10831 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10833 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
10834 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10836 ok(compare_color(dst_data
->specular
, tests
[i
].expected_color
, 1)
10837 || broken(tests
[i
].expected_broken
10838 && compare_color(dst_data
->specular
, tests
[i
].expected_broken
, 1)),
10839 "Expected color 0x%08x, got 0x%08x, test %u.\n",
10840 tests
[i
].expected_color
, dst_data
->specular
, i
);
10842 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
10843 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10846 IDirect3DVertexBuffer7_Release(dst_vb
);
10847 IDirect3DVertexBuffer7_Release(src_vb
);
10848 IDirect3D7_Release(d3d
);
10849 refcount
= IDirect3DDevice7_Release(device
);
10850 ok(!refcount
, "Device has %u references left.\n", refcount
);
10851 DestroyWindow(window
);
10854 static void test_negative_fixedfunction_fog(void)
10857 IDirect3DDevice7
*device
;
10858 IDirectDrawSurface7
*rt
;
10864 struct vec3 position
;
10869 {{-1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
10870 {{-1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
10871 {{ 1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
10872 {{ 1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
10876 struct vec4 position
;
10881 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10882 {{640.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10883 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10884 {{640.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10887 static D3DMATRIX zero
=
10889 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10890 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10891 0.0f
, 0.0f
, 0.0f
, 0.0f
,
10892 0.0f
, 0.0f
, 0.0f
, 1.0f
10894 static D3DMATRIX identity
=
10896 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10897 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10898 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10899 0.0f
, 0.0f
, 0.0f
, 1.0f
10901 static const struct
10911 D3DFOGMODE vfog
, tfog
;
10912 DWORD color
, color_broken
, color_broken2
;
10916 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
10918 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
10919 {D3DFVF_XYZRHW
, tquad
, &identity
, { 0.0f
}, {1.0f
}, D3DFOG_NONE
, D3DFOG_LINEAR
,
10920 0x00ff0000, 0x00808000, 0x00808000},
10921 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
10922 * parameters to 0.0 and 1.0 in the table fog case. */
10923 {D3DFVF_XYZRHW
, tquad
, &identity
, {-1.0f
}, {0.0f
}, D3DFOG_NONE
, D3DFOG_LINEAR
,
10924 0x00808000, 0x00ff0000, 0x0000ff00},
10925 /* test_fog_interpolation shows that vertex fog evaluates the fog
10926 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
10927 * that the abs happens before the fog equation is evaluated.
10929 * Vertex fog abs() behavior is the same on all GPUs. */
10930 {D3DFVF_XYZ
, quad
, &zero
, { 0.0f
}, {1.0f
}, D3DFOG_LINEAR
, D3DFOG_NONE
,
10931 0x00808000, 0x00808000, 0x00808000},
10932 {D3DFVF_XYZ
, quad
, &zero
, {-1.0f
}, {0.0f
}, D3DFOG_LINEAR
, D3DFOG_NONE
,
10933 0x0000ff00, 0x0000ff00, 0x0000ff00},
10934 {D3DFVF_XYZ
, quad
, &zero
, { 0.0f
}, {1.0f
}, D3DFOG_EXP
, D3DFOG_NONE
,
10935 0x009b6400, 0x009b6400, 0x009b6400},
10937 D3DDEVICEDESC7 caps
;
10939 window
= create_window();
10940 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10942 skip("Failed to create a 3D device, skipping test.\n");
10943 DestroyWindow(window
);
10947 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
10948 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10949 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
10950 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10951 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
10952 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
10954 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10955 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10956 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10957 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10958 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10959 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10960 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
10961 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10962 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10963 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
10965 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10967 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
10970 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
10971 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10973 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].matrix
);
10974 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
10975 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGSTART
, tests
[i
].start
.d
);
10976 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10977 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGEND
, tests
[i
].end
.d
);
10978 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10979 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vfog
);
10980 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10981 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tfog
);
10982 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10984 hr
= IDirect3DDevice7_BeginScene(device
);
10985 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10986 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10987 tests
[i
].pos_type
| D3DFVF_DIFFUSE
, tests
[i
].quad
, 4, 0);
10988 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10989 hr
= IDirect3DDevice7_EndScene(device
);
10990 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10992 color
= get_surface_color(rt
, 0, 240);
10993 ok(compare_color(color
, tests
[i
].color
, 2) || broken(compare_color(color
, tests
[i
].color_broken
, 2))
10994 || broken(compare_color(color
, tests
[i
].color_broken2
, 2)),
10995 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10998 IDirectDrawSurface7_Release(rt
);
10999 refcount
= IDirect3DDevice7_Release(device
);
11000 ok(!refcount
, "Device has %u references left.\n", refcount
);
11001 DestroyWindow(window
);
11004 static void test_table_fog_zw(void)
11007 IDirect3DDevice7
*device
;
11008 IDirectDrawSurface7
*rt
;
11014 struct vec4 position
;
11019 {{ 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
11020 {{640.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
11021 {{ 0.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
11022 {{640.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
11024 static D3DMATRIX identity
=
11026 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11027 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11028 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11029 0.0f
, 0.0f
, 0.0f
, 1.0f
11031 D3DDEVICEDESC7 caps
;
11032 static const struct
11035 D3DZBUFFERTYPE z_test
;
11040 {0.7f
, 0.0f
, D3DZB_TRUE
, 0x004cb200},
11041 {0.7f
, 0.0f
, D3DZB_FALSE
, 0x004cb200},
11042 {0.7f
, 0.3f
, D3DZB_TRUE
, 0x004cb200},
11043 {0.7f
, 0.3f
, D3DZB_FALSE
, 0x004cb200},
11044 {0.7f
, 3.0f
, D3DZB_TRUE
, 0x004cb200},
11045 {0.7f
, 3.0f
, D3DZB_FALSE
, 0x004cb200},
11046 {0.3f
, 0.0f
, D3DZB_TRUE
, 0x00b24c00},
11047 {0.3f
, 0.0f
, D3DZB_FALSE
, 0x00b24c00},
11051 window
= create_window();
11052 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11054 skip("Failed to create a 3D device, skipping test.\n");
11055 DestroyWindow(window
);
11059 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
11060 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
11061 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
11063 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
11066 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
11067 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11069 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
11070 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11071 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
11072 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11073 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
11074 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11075 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
11076 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
11077 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
11078 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
11079 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
11080 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, D3DFOG_LINEAR
);
11081 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11083 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
11085 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x000000ff, 1.0f
, 0);
11086 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11088 quad
[0].position
.z
= tests
[i
].z
;
11089 quad
[1].position
.z
= tests
[i
].z
;
11090 quad
[2].position
.z
= tests
[i
].z
;
11091 quad
[3].position
.z
= tests
[i
].z
;
11092 quad
[0].position
.w
= tests
[i
].w
;
11093 quad
[1].position
.w
= tests
[i
].w
;
11094 quad
[2].position
.w
= tests
[i
].w
;
11095 quad
[3].position
.w
= tests
[i
].w
;
11096 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, tests
[i
].z_test
);
11097 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11099 hr
= IDirect3DDevice7_BeginScene(device
);
11100 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11101 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11102 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, quad
, 4, 0);
11103 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11104 hr
= IDirect3DDevice7_EndScene(device
);
11105 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11107 color
= get_surface_color(rt
, 0, 240);
11108 ok(compare_color(color
, tests
[i
].color
, 2),
11109 "Got unexpected color 0x%08x, expected 0x%8x, case %u.\n", color
, tests
[i
].color
, i
);
11112 IDirectDrawSurface7_Release(rt
);
11114 refcount
= IDirect3DDevice7_Release(device
);
11115 ok(!refcount
, "Device has %u references left.\n", refcount
);
11116 DestroyWindow(window
);
11119 static void test_signed_formats(void)
11122 IDirect3DDevice7
*device
;
11124 IDirectDraw7
*ddraw
;
11125 IDirectDrawSurface7
*surface
, *rt
;
11126 DDSURFACEDESC2 surface_desc
;
11129 D3DCOLOR color
, expected_color
;
11132 struct vec3 position
;
11133 struct vec2 texcoord
;
11137 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11138 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
11139 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11140 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
11142 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
11143 * of these values. */
11144 static const USHORT content_v8u8
[4][4] =
11146 {0x0000, 0x7f7f, 0x8880, 0x0000},
11147 {0x0080, 0x8000, 0x7f00, 0x007f},
11148 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
11149 {0x4444, 0xc0c0, 0xa066, 0x22e0},
11151 static const DWORD content_x8l8v8u8
[4][4] =
11153 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
11154 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
11155 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
11156 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
11158 static const USHORT content_l6v5u5
[4][4] =
11160 {0x0000, 0xfdef, 0x0230, 0xfc00},
11161 {0x0010, 0x0200, 0x01e0, 0x000f},
11162 {0x4067, 0x53b9, 0x0421, 0xffff},
11163 {0x8108, 0x0318, 0xc28c, 0x909c},
11165 static const struct
11168 const void *content
;
11171 unsigned int slop
, slop_broken
;
11172 DDPIXELFORMAT format
;
11177 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
11179 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
11180 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
11184 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
11186 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11187 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
11191 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
11193 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11194 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
11198 /* No V16U16 or Q8W8V8U8 support in ddraw. */
11200 static const D3DCOLOR expected_colors
[4][4] =
11202 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
11203 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
11204 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
11205 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
11207 unsigned int i
, width
, x
, y
;
11208 D3DDEVICEDESC7 device_desc
;
11210 window
= create_window();
11211 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11213 skip("Failed to create a 3D device, skipping test.\n");
11214 DestroyWindow(window
);
11218 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
11219 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
11220 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
11222 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
11226 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11227 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
11228 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11229 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
11230 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
11231 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11233 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
11234 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11236 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
11237 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
11238 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11239 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
11240 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11241 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11242 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11243 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
11244 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11246 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
11248 for (width
= 1; width
< 5; width
+= 3)
11250 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
11251 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11253 memset(&surface_desc
, 0, sizeof(surface_desc
));
11254 surface_desc
.dwSize
= sizeof(surface_desc
);
11255 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
11256 surface_desc
.dwWidth
= width
;
11257 surface_desc
.dwHeight
= 4;
11258 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
11259 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
11260 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11263 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
11266 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11267 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
11268 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11270 memset(&surface_desc
, 0, sizeof(surface_desc
));
11271 surface_desc
.dwSize
= sizeof(surface_desc
);
11272 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
11273 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11274 for (y
= 0; y
< 4; y
++)
11276 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
11277 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
11278 width
* formats
[i
].pixel_size
);
11280 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11281 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11283 hr
= IDirect3DDevice7_BeginScene(device
);
11284 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11285 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11286 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
11287 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11288 hr
= IDirect3DDevice7_EndScene(device
);
11289 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11291 for (y
= 0; y
< 4; y
++)
11293 for (x
= 0; x
< width
; x
++)
11295 expected_color
= expected_colors
[y
][x
];
11296 if (!formats
[i
].blue
)
11297 expected_color
|= 0x000000ff;
11299 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
11300 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
11301 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
11302 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
11303 expected_color
, color
, formats
[i
].name
, x
, y
);
11307 IDirectDrawSurface7_Release(surface
);
11312 IDirectDrawSurface7_Release(rt
);
11313 IDirectDraw7_Release(ddraw
);
11314 IDirect3D7_Release(d3d
);
11317 refcount
= IDirect3DDevice7_Release(device
);
11318 ok(!refcount
, "Device has %u references left.\n", refcount
);
11319 DestroyWindow(window
);
11322 static void test_color_fill(void)
11325 IDirect3DDevice7
*device
;
11327 IDirectDraw7
*ddraw
;
11328 IDirectDrawSurface7
*surface
, *surface2
;
11329 DDSURFACEDESC2 surface_desc
;
11330 DDPIXELFORMAT z_fmt
;
11335 RECT rect
= {5, 5, 7, 7};
11337 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
11339 static const struct
11342 HRESULT colorfill_hr
, depthfill_hr
;
11347 DDPIXELFORMAT format
;
11352 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11353 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11355 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11356 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11360 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11361 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11363 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11364 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11368 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11369 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
11371 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11372 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11376 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11377 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
11379 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11380 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11384 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
11385 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
11387 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11388 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11392 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
11393 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
11394 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11397 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
11398 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
11399 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11402 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
11403 * different afterwards. DX9+ GPUs set one of the two luminance values
11404 * in each block, but AMD and Nvidia GPUs disagree on which luminance
11405 * value they set. r200 (dx8) just sets the entire block to the clear
11407 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11408 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
11410 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11411 {0}, {0}, {0}, {0}, {0}
11415 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11416 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
11418 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11419 {0}, {0}, {0}, {0}, {0}
11423 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11424 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
11426 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11427 {0}, {0}, {0}, {0}, {0}
11431 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11432 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
11434 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11435 {0}, {0}, {0}, {0}, {0}
11439 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11440 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
11442 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11443 {0}, {0}, {0}, {0}, {0}
11447 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11448 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
11450 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11451 {0}, {0}, {0}, {0}, {0}
11455 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
11456 * surface works, presumably because it is handled by the runtime instead of
11458 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11459 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
11461 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11462 {8}, {0}, {0}, {0}, {0}
11466 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11467 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
11469 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11470 {8}, {0}, {0}, {0}, {0}
11474 static const struct
11482 {SRCCOPY
, "SRCCOPY", DD_OK
},
11483 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
11484 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
11485 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
11486 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
11487 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
11488 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
11489 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
11490 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
11491 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
11492 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
11493 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
11494 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
11495 {BLACKNESS
, "BLACKNESS", DD_OK
},
11496 {WHITENESS
, "WHITENESS", DD_OK
},
11497 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
11500 window
= create_window();
11501 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11503 skip("Failed to create a 3D device, skipping test.\n");
11504 DestroyWindow(window
);
11508 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11509 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
11510 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11511 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
11513 memset(&z_fmt
, 0, sizeof(z_fmt
));
11514 IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
11516 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
11518 IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
11519 if (!(supported_fmts
& SUPPORT_DXT1
))
11520 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
11522 IDirect3D7_Release(d3d
);
11524 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
11525 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
11526 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
11527 num_fourcc_codes
* sizeof(*fourcc_codes
));
11530 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
11531 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
11532 for (i
= 0; i
< num_fourcc_codes
; i
++)
11534 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
11535 supported_fmts
|= SUPPORT_YUY2
;
11536 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
11537 supported_fmts
|= SUPPORT_UYVY
;
11539 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
11541 memset(&hal_caps
, 0, sizeof(hal_caps
));
11542 hal_caps
.dwSize
= sizeof(hal_caps
);
11543 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
11544 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
11546 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11547 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
11549 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
11551 DWORD expected_broken
= tests
[i
].result
;
11553 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
11554 memset(&fx
, 0, sizeof(fx
));
11555 fx
.dwSize
= sizeof(fx
);
11556 U5(fx
).dwFillColor
= 0xdeadbeef;
11558 memset(&surface_desc
, 0, sizeof(surface_desc
));
11559 surface_desc
.dwSize
= sizeof(surface_desc
);
11560 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11561 surface_desc
.dwWidth
= 64;
11562 surface_desc
.dwHeight
= 64;
11563 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
11564 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
11565 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
11567 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
11569 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
11571 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
11573 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11576 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
11581 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11582 /* Some drivers seem to convert depth values incorrectly or not at
11583 * all. Affects at least AMD PALM, 8.17.10.1247. */
11584 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
11589 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
11590 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
11591 g
= (f
+ 1.0f
) / 2.0f
;
11593 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
11594 expected_broken
*= 0x01010101;
11598 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11599 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11601 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11602 todo_wine_if (tests
[i
].format
.dwFourCC
)
11603 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11604 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11606 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11607 todo_wine_if (tests
[i
].format
.dwFourCC
)
11608 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11609 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11611 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11613 memset(&surface_desc
, 0, sizeof(surface_desc
));
11614 surface_desc
.dwSize
= sizeof(surface_desc
);
11615 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11616 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11617 color
= surface_desc
.lpSurface
;
11618 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
11619 *color
, tests
[i
].result
, tests
[i
].name
);
11620 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11621 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11624 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11625 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11626 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11627 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11628 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11629 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11631 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11633 memset(&surface_desc
, 0, sizeof(surface_desc
));
11634 surface_desc
.dwSize
= sizeof(surface_desc
);
11635 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11636 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11637 color
= surface_desc
.lpSurface
;
11638 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
11639 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
11640 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
11641 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
11642 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11643 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11646 U5(fx
).dwFillColor
= 0xdeadbeef;
11647 fx
.dwROP
= BLACKNESS
;
11648 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11649 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
11650 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11651 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
11652 U5(fx
).dwFillColor
, tests
[i
].name
);
11654 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11656 memset(&surface_desc
, 0, sizeof(surface_desc
));
11657 surface_desc
.dwSize
= sizeof(surface_desc
);
11658 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11659 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11660 color
= surface_desc
.lpSurface
;
11661 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
11662 *color
, tests
[i
].name
);
11663 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11664 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11667 fx
.dwROP
= WHITENESS
;
11668 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11669 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
11670 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11671 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
11672 U5(fx
).dwFillColor
, tests
[i
].name
);
11674 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11676 memset(&surface_desc
, 0, sizeof(surface_desc
));
11677 surface_desc
.dwSize
= sizeof(surface_desc
);
11678 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11679 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11680 color
= surface_desc
.lpSurface
;
11681 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
11682 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
11683 *color
, tests
[i
].name
);
11684 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11685 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11688 IDirectDrawSurface7_Release(surface
);
11691 memset(&fx
, 0, sizeof(fx
));
11692 fx
.dwSize
= sizeof(fx
);
11693 U5(fx
).dwFillColor
= 0xdeadbeef;
11694 fx
.dwROP
= WHITENESS
;
11696 memset(&surface_desc
, 0, sizeof(surface_desc
));
11697 surface_desc
.dwSize
= sizeof(surface_desc
);
11698 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11699 surface_desc
.dwWidth
= 64;
11700 surface_desc
.dwHeight
= 64;
11701 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11702 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11703 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11704 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11705 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11706 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11707 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11708 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11709 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11710 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11711 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11714 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
11715 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11716 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
11717 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11719 /* Unused source rectangle. */
11720 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11721 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11722 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11723 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11725 /* Unused source surface. */
11726 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11727 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11728 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11729 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11730 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11731 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11732 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11733 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11735 /* Inverted destination or source rectangle. */
11736 SetRect(&rect
, 5, 7, 7, 5);
11737 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11738 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11739 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11740 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11741 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11742 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11743 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11744 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11745 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11746 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11748 /* Negative rectangle. */
11749 SetRect(&rect
, -1, -1, 5, 5);
11750 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11751 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11752 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11753 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11754 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11755 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11756 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11757 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11758 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11759 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11761 /* Out of bounds rectangle. */
11762 SetRect(&rect
, 0, 0, 65, 65);
11763 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11764 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11765 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11766 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11768 /* Combine multiple flags. */
11769 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11770 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11771 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11772 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11773 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11774 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11776 for (i
= 0; i
< ARRAY_SIZE(rops
); ++i
)
11778 fx
.dwROP
= rops
[i
].rop
;
11779 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11780 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
11783 IDirectDrawSurface7_Release(surface2
);
11784 IDirectDrawSurface7_Release(surface
);
11789 memset(&surface_desc
, 0, sizeof(surface_desc
));
11790 surface_desc
.dwSize
= sizeof(surface_desc
);
11791 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11792 surface_desc
.dwWidth
= 64;
11793 surface_desc
.dwHeight
= 64;
11794 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11795 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
11796 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11797 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11798 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11799 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11802 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
11803 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11805 /* Unused source rectangle. */
11806 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11807 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11809 /* Unused source surface. */
11810 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11811 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11812 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11813 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11815 /* Inverted destination or source rectangle. */
11816 SetRect(&rect
, 5, 7, 7, 5);
11817 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11818 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11819 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11820 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11821 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11822 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11823 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11824 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11826 /* Negative rectangle. */
11827 SetRect(&rect
, -1, -1, 5, 5);
11828 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11829 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11830 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11831 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11832 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11833 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11834 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11835 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11837 /* Out of bounds rectangle. */
11838 SetRect(&rect
, 0, 0, 65, 65);
11839 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11840 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11842 /* Combine multiple flags. */
11843 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11844 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11846 IDirectDrawSurface7_Release(surface2
);
11847 IDirectDrawSurface7_Release(surface
);
11850 IDirectDraw7_Release(ddraw
);
11851 refcount
= IDirect3DDevice7_Release(device
);
11852 ok(!refcount
, "Device has %u references left.\n", refcount
);
11853 DestroyWindow(window
);
11856 static void test_texcoordindex(void)
11858 static D3DMATRIX mat
=
11860 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11861 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11862 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11863 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11868 struct vec2 texcoord1
;
11869 struct vec2 texcoord2
;
11870 struct vec2 texcoord3
;
11874 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11875 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
11876 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11877 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
11879 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
11880 IDirect3DDevice7
*device
;
11882 IDirectDraw7
*ddraw
;
11883 IDirectDrawSurface7
*rt
;
11886 IDirectDrawSurface7
*texture1
, *texture2
;
11887 DDSURFACEDESC2 surface_desc
;
11892 window
= create_window();
11893 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11895 skip("Failed to create a 3D device, skipping test.\n");
11896 DestroyWindow(window
);
11900 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11901 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
11902 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11903 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
11904 IDirect3D7_Release(d3d
);
11906 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
11907 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11909 memset(&surface_desc
, 0, sizeof(surface_desc
));
11910 surface_desc
.dwSize
= sizeof(surface_desc
);
11911 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11912 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11913 surface_desc
.dwWidth
= 2;
11914 surface_desc
.dwHeight
= 2;
11915 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11916 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11917 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11918 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11919 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11920 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11921 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
11922 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture1
, NULL
);
11923 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11924 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture2
, NULL
);
11925 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11927 memset(&surface_desc
, 0, sizeof(surface_desc
));
11928 surface_desc
.dwSize
= sizeof(surface_desc
);
11929 hr
= IDirectDrawSurface7_Lock(texture1
, 0, &surface_desc
, 0, NULL
);
11930 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11931 ptr
= surface_desc
.lpSurface
;
11932 ptr
[0] = 0xff000000;
11933 ptr
[1] = 0xff00ff00;
11934 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
11935 ptr
[0] = 0xff0000ff;
11936 ptr
[1] = 0xff00ffff;
11937 hr
= IDirectDrawSurface7_Unlock(texture1
, NULL
);
11938 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11940 memset(&surface_desc
, 0, sizeof(surface_desc
));
11941 surface_desc
.dwSize
= sizeof(surface_desc
);
11942 hr
= IDirectDrawSurface7_Lock(texture2
, 0, &surface_desc
, 0, NULL
);
11943 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11944 ptr
= surface_desc
.lpSurface
;
11945 ptr
[0] = 0xff000000;
11946 ptr
[1] = 0xff0000ff;
11947 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
11948 ptr
[0] = 0xffff0000;
11949 ptr
[1] = 0xffff00ff;
11950 hr
= IDirectDrawSurface7_Unlock(texture2
, 0);
11951 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11953 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture1
);
11954 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
11955 hr
= IDirect3DDevice7_SetTexture(device
, 1, texture2
);
11956 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
11957 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
11958 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
11959 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
11960 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11961 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11962 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11963 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
11964 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11965 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11966 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11967 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
11968 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11969 hr
= IDirect3DDevice7_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
11970 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11972 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
11973 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
11974 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
11975 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
11977 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
11978 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
11980 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
11981 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11983 hr
= IDirect3DDevice7_BeginScene(device
);
11984 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11985 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
11986 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11987 hr
= IDirect3DDevice7_EndScene(device
);
11988 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11990 color
= get_surface_color(rt
, 160, 120);
11991 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11992 color
= get_surface_color(rt
, 480, 120);
11993 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
11994 color
= get_surface_color(rt
, 160, 360);
11995 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
11996 color
= get_surface_color(rt
, 480, 360);
11997 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
11999 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT2
);
12000 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
12001 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_TEXTURE1
, &mat
);
12002 ok(SUCCEEDED(hr
), "Failed to set transformation matrix, hr %#x.\n", hr
);
12004 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
12005 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12007 hr
= IDirect3DDevice7_BeginScene(device
);
12008 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12009 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
12010 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12011 hr
= IDirect3DDevice7_EndScene(device
);
12012 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12014 color
= get_surface_color(rt
, 160, 120);
12015 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
12016 color
= get_surface_color(rt
, 480, 120);
12017 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
12018 color
= get_surface_color(rt
, 160, 360);
12019 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
12020 color
= get_surface_color(rt
, 480, 360);
12021 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
12023 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_DISABLE
);
12024 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
12025 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
12026 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
12028 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
12029 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
12031 hr
= IDirect3DDevice7_BeginScene(device
);
12032 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12033 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
12034 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12035 hr
= IDirect3DDevice7_EndScene(device
);
12036 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12038 color
= get_surface_color(rt
, 160, 120);
12039 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
12040 color
= get_surface_color(rt
, 480, 120);
12041 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
12042 color
= get_surface_color(rt
, 160, 360);
12043 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
12044 color
= get_surface_color(rt
, 480, 360);
12045 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
12047 IDirectDrawSurface7_Release(texture1
);
12048 IDirectDrawSurface7_Release(texture2
);
12050 IDirectDrawSurface7_Release(rt
);
12051 IDirectDraw7_Release(ddraw
);
12052 refcount
= IDirect3DDevice7_Release(device
);
12053 ok(!refcount
, "Device has %u references left.\n", refcount
);
12054 DestroyWindow(window
);
12057 static void test_colorkey_precision(void)
12062 struct vec2 texcoord
;
12066 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
12067 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
12068 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
12069 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
12072 static const struct
12074 unsigned int max
, shift
, bpp
, clear
;
12082 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
12084 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12085 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
12090 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
12092 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12093 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
12098 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
12100 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12101 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
12106 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
12108 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
12109 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
12114 IDirectDrawSurface7
*src
, *dst
, *texture
;
12115 DDSURFACEDESC2 surface_desc
, lock_desc
;
12116 DWORD data
[4] = {0}, color_mask
;
12117 IDirect3DDevice7
*device
;
12118 IDirectDrawSurface7
*rt
;
12119 IDirectDraw7
*ddraw
;
12130 window
= create_window();
12131 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12133 skip("Failed to create a 3D device, skipping test.\n");
12134 DestroyWindow(window
);
12138 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
12139 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12140 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
12141 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12142 IDirect3D7_Release(d3d
);
12143 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
12144 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12146 is_nvidia
= ddraw_is_nvidia(ddraw
);
12147 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
12148 * (color key doesn't match although the values are equal), and a false
12149 * positive when the color key is 0 and the texture contains the value 1.
12150 * Also on random occasions 254 == 255 and 255 != 255.
12151 * Crashes on Windows 10 WARP. */
12152 if (ddraw_is_warp(ddraw
))
12154 win_skip("Skipping test on WARP driver.\n");
12158 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12159 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12160 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
12161 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12162 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
12163 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12164 /* Multiply the texture read result with 0, that way the result color if the key doesn't
12165 * match is constant. In theory color keying works without reading the texture result
12166 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
12168 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
12169 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12170 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
12171 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12172 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
12173 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12174 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
12175 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12177 memset(&fx
, 0, sizeof(fx
));
12178 fx
.dwSize
= sizeof(fx
);
12179 memset(&lock_desc
, 0, sizeof(lock_desc
));
12180 lock_desc
.dwSize
= sizeof(lock_desc
);
12182 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
12184 if (is_nvidia
&& tests
[t
].skip_nv
)
12186 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
12190 memset(&surface_desc
, 0, sizeof(surface_desc
));
12191 surface_desc
.dwSize
= sizeof(surface_desc
);
12192 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12193 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12194 surface_desc
.dwWidth
= 4;
12195 surface_desc
.dwHeight
= 1;
12196 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
12197 /* Windows XP (at least with the r200 driver, other drivers untested) produces
12198 * garbage when doing color keyed texture->texture blits. */
12199 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12200 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12201 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12202 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12204 U5(fx
).dwFillColor
= tests
[t
].clear
;
12205 /* On the w8 testbot (WARP driver) the blit result has different values in the
12207 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
12208 | U3(tests
[t
].fmt
).dwGBitMask
12209 | U4(tests
[t
].fmt
).dwBBitMask
;
12211 for (c
= 0; c
<= tests
[t
].max
; ++c
)
12213 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
12214 * texture after it has been set once... */
12215 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12216 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12217 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12218 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12219 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
12220 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12221 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
12222 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12224 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12225 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12227 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12228 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12229 switch (tests
[t
].bpp
)
12232 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12233 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12234 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12235 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
12239 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12240 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12241 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12242 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
12245 hr
= IDirectDrawSurface7_Unlock(src
, 0);
12246 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12247 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
12248 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12250 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12251 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12252 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12253 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12255 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
12256 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12258 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
12259 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12260 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12261 switch (tests
[t
].bpp
)
12264 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12265 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12266 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12267 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12271 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12272 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12273 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12274 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12277 hr
= IDirectDrawSurface7_Unlock(dst
, 0);
12278 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12282 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12283 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
12285 if (data
[3] == tests
[t
].clear
)
12287 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
12288 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
12289 * even when a different surface is used. The blit itself doesn't draw anything,
12290 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
12291 * never be masked out by the key.
12293 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
12294 * test is disabled on Nvidia.
12296 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
12297 * terrible on WARP. */
12298 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
12299 IDirectDrawSurface7_Release(texture
);
12300 IDirectDrawSurface7_Release(src
);
12301 IDirectDrawSurface7_Release(dst
);
12306 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12307 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
12309 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12310 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
12312 if (c
== tests
[t
].max
)
12313 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12314 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
12316 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12317 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
12319 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
12320 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12322 hr
= IDirect3DDevice7_BeginScene(device
);
12323 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12324 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
12325 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12326 hr
= IDirect3DDevice7_EndScene(device
);
12327 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12329 color
= get_surface_color(rt
, 80, 240);
12332 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12333 color
, tests
[t
].name
, c
);
12335 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12336 color
, tests
[t
].name
, c
);
12338 color
= get_surface_color(rt
, 240, 240);
12339 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12340 color
, tests
[t
].name
, c
);
12342 color
= get_surface_color(rt
, 400, 240);
12343 if (c
== tests
[t
].max
)
12344 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12345 color
, tests
[t
].name
, c
);
12347 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12348 color
, tests
[t
].name
, c
);
12350 IDirectDrawSurface7_Release(texture
);
12352 IDirectDrawSurface7_Release(src
);
12353 IDirectDrawSurface7_Release(dst
);
12357 IDirectDrawSurface7_Release(rt
);
12358 IDirectDraw7_Release(ddraw
);
12359 refcount
= IDirect3DDevice7_Release(device
);
12360 ok(!refcount
, "Device has %u references left.\n", refcount
);
12361 DestroyWindow(window
);
12364 static void test_range_colorkey(void)
12366 IDirectDraw7
*ddraw
;
12369 IDirectDrawSurface7
*surface
;
12370 DDSURFACEDESC2 surface_desc
;
12374 window
= create_window();
12375 ddraw
= create_ddraw();
12376 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12377 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12378 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12380 memset(&surface_desc
, 0, sizeof(surface_desc
));
12381 surface_desc
.dwSize
= sizeof(surface_desc
);
12382 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
12383 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12384 surface_desc
.dwWidth
= 1;
12385 surface_desc
.dwHeight
= 1;
12386 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12387 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12388 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12389 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12390 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12391 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
12393 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
12394 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12395 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12396 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12397 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12399 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12400 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12401 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12402 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12404 /* Same for DDSCAPS_OFFSCREENPLAIN. */
12405 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12406 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12407 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12408 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12409 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12411 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12412 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12413 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12414 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12416 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12417 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12418 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12419 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12421 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
12422 ckey
.dwColorSpaceLowValue
= 0x00000000;
12423 ckey
.dwColorSpaceHighValue
= 0x00000001;
12424 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12425 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12427 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12428 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12429 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12430 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12432 ckey
.dwColorSpaceLowValue
= 0x00000001;
12433 ckey
.dwColorSpaceHighValue
= 0x00000000;
12434 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12435 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12437 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12438 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12439 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12440 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12442 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
12443 ckey
.dwColorSpaceLowValue
= 0x00000000;
12444 ckey
.dwColorSpaceHighValue
= 0x00000000;
12445 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12446 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12448 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
12449 ckey
.dwColorSpaceLowValue
= 0x00000001;
12450 ckey
.dwColorSpaceHighValue
= 0x00000000;
12451 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12452 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12453 ckey
.dwColorSpaceLowValue
= 0x00000000;
12454 ckey
.dwColorSpaceHighValue
= 0x00000001;
12455 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12456 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12457 /* Range destination keys don't work either. */
12458 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
12459 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12461 /* Just to show it's not because of A, R, and G having equal values. */
12462 ckey
.dwColorSpaceLowValue
= 0x00000000;
12463 ckey
.dwColorSpaceHighValue
= 0x01010101;
12464 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12465 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12467 /* None of these operations modified the key. */
12468 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12469 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12470 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12471 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12473 IDirectDrawSurface7_Release(surface
);
12474 refcount
= IDirectDraw7_Release(ddraw
);
12475 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
12476 DestroyWindow(window
);
12479 static void test_shademode(void)
12481 IDirect3DVertexBuffer7
*vb_strip
, *vb_list
, *buffer
;
12482 IDirect3DDevice7
*device
;
12483 D3DVERTEXBUFFERDESC desc
;
12484 IDirectDrawSurface7
*rt
;
12485 DWORD color0
, color1
;
12492 static const struct
12494 struct vec3 position
;
12499 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12500 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12501 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12502 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12506 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12507 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12508 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12510 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12511 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12512 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12514 static const struct
12518 DWORD color0
, color1
;
12522 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
12523 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12524 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12525 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12526 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
12527 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12530 window
= create_window();
12531 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12533 skip("Failed to create a 3D device, skipping test.\n");
12534 DestroyWindow(window
);
12538 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
12539 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
12540 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
12541 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12543 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12544 ok(hr
== D3D_OK
, "Failed to disable lighting, hr %#x.\n", hr
);
12545 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12546 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12548 memset(&desc
, 0, sizeof(desc
));
12549 desc
.dwSize
= sizeof(desc
);
12550 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
12551 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
12552 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
12553 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0);
12554 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
12555 hr
= IDirect3DVertexBuffer7_Lock(vb_strip
, 0, &data
, NULL
);
12556 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
12557 memcpy(data
, quad_strip
, sizeof(quad_strip
));
12558 hr
= IDirect3DVertexBuffer7_Unlock(vb_strip
);
12559 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12561 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
12562 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0);
12563 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
12564 hr
= IDirect3DVertexBuffer7_Lock(vb_list
, 0, &data
, NULL
);
12565 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
12566 memcpy(data
, quad_list
, sizeof(quad_list
));
12567 hr
= IDirect3DVertexBuffer7_Unlock(vb_list
);
12568 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12570 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
12571 * the color fixups we have to do for FLAT shading will be dependent on that. */
12573 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
12575 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
12576 ok(hr
== D3D_OK
, "Failed to clear, hr %#x.\n", hr
);
12578 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
12579 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
12581 hr
= IDirect3DDevice7_BeginScene(device
);
12582 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12583 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
12584 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
12585 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
12586 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12587 hr
= IDirect3DDevice7_EndScene(device
);
12588 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12590 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
12591 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
12593 /* For D3DSHADE_FLAT it should take the color of the first vertex of
12594 * each triangle. This requires EXT_provoking_vertex or similar
12595 * functionality being available. */
12596 /* PHONG should be the same as GOURAUD, since no hardware implements
12598 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
12599 i
, color0
, tests
[i
].color0
);
12600 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
12601 i
, color1
, tests
[i
].color1
);
12604 IDirect3DVertexBuffer7_Release(vb_strip
);
12605 IDirect3DVertexBuffer7_Release(vb_list
);
12606 IDirectDrawSurface7_Release(rt
);
12607 IDirect3D7_Release(d3d
);
12608 refcount
= IDirect3DDevice7_Release(device
);
12609 ok(!refcount
, "Device has %u references left.\n", refcount
);
12610 DestroyWindow(window
);
12613 static void test_lockrect_invalid(void)
12616 IDirectDraw7
*ddraw
;
12617 IDirectDrawSurface7
*surface
;
12620 DDSURFACEDESC2 surface_desc
;
12621 DDSURFACEDESC2 locked_desc
;
12623 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
12624 static RECT valid
[] =
12629 {120, 60, 128, 68},
12630 {60, 120, 68, 128},
12632 static RECT invalid
[] =
12634 {68, 60, 60, 68}, /* left > right */
12635 {60, 68, 68, 60}, /* top > bottom */
12636 {-8, 60, 0, 68}, /* left < surface */
12637 {60, -8, 68, 0}, /* top < surface */
12638 {-16, 60, -8, 68}, /* right < surface */
12639 {60, -16, 68, -8}, /* bottom < surface */
12640 {60, 60, 136, 68}, /* right > surface */
12641 {60, 60, 68, 136}, /* bottom > surface */
12642 {136, 60, 144, 68}, /* left > surface */
12643 {60, 136, 68, 144}, /* top > surface */
12645 static const struct
12654 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12655 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12656 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", TRUE
, DD_OK
},
12657 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", TRUE
, DDERR_INVALIDPARAMS
},
12658 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", TRUE
, DD_OK
},
12660 /* FWIW the SDK header mentions DDSCAPS_WRITEONLY as being a "READ
12662 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12663 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12664 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem texture writeonly", FALSE
, DD_OK
},
12665 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12666 {DDSCAPS_TEXTURE
| DDSCAPS_WRITEONLY
, DDSCAPS2_TEXTUREMANAGE
, "managed texture writeonly", TRUE
, DD_OK
},
12669 window
= create_window();
12670 ddraw
= create_ddraw();
12671 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12672 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12673 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12675 memset(&hal_caps
, 0, sizeof(hal_caps
));
12676 hal_caps
.dwSize
= sizeof(hal_caps
);
12677 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
12678 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
12679 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
12680 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
12682 skip("Required surface types not supported, skipping test.\n");
12686 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
12688 memset(&surface_desc
, 0, sizeof(surface_desc
));
12689 surface_desc
.dwSize
= sizeof(surface_desc
);
12690 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12691 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
12692 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
12693 surface_desc
.dwWidth
= 128;
12694 surface_desc
.dwHeight
= 128;
12695 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12696 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12697 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12698 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
12699 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
12700 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
12702 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12703 if (!resources
[r
].allowed
)
12705 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
12708 if (is_ddraw64
&& (resources
[r
].caps
& DDSCAPS_TEXTURE
))
12710 todo_wine
ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
12712 IDirectDrawSurface7_Release(surface
);
12715 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12717 /* Crashes in ddraw7
12718 hr = IDirectDrawSurface7_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL);
12719 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
12722 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
12724 RECT
*rect
= &valid
[i
];
12726 memset(&locked_desc
, 0, sizeof(locked_desc
));
12727 locked_desc
.dwSize
= sizeof(locked_desc
);
12729 hr
= IDirectDrawSurface7_Lock(surface
, rect
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12730 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
12731 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12733 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12734 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12737 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
12739 RECT
*rect
= &invalid
[i
];
12741 memset(&locked_desc
, 1, sizeof(locked_desc
));
12742 locked_desc
.dwSize
= sizeof(locked_desc
);
12744 hr
= IDirectDrawSurface7_Lock(surface
, rect
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12745 todo_wine_if (SUCCEEDED(resources
[r
].hr
))
12746 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
12747 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12750 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12751 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12754 ok(!locked_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", locked_desc
.lpSurface
);
12757 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12758 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
12759 hr
, resources
[r
].name
);
12760 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12761 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
12762 hr
, resources
[r
].name
);
12763 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12764 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12766 hr
= IDirectDrawSurface7_Lock(surface
, &valid
[0], &locked_desc
, DDLOCK_WAIT
, NULL
);
12767 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
12768 hr
= IDirectDrawSurface7_Lock(surface
, &valid
[0], &locked_desc
, DDLOCK_WAIT
, NULL
);
12769 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
12770 wine_dbgstr_rect(&valid
[0]), hr
);
12772 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
12773 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
12775 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12776 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12778 IDirectDrawSurface7_Release(surface
);
12782 IDirectDraw7_Release(ddraw
);
12783 DestroyWindow(window
);
12786 static void test_yv12_overlay(void)
12788 IDirectDrawSurface7
*src_surface
, *dst_surface
;
12789 RECT rect
= {13, 17, 14, 18};
12790 unsigned int offset
, y
;
12791 DDSURFACEDESC2 desc
;
12792 unsigned char *base
;
12793 IDirectDraw7
*ddraw
;
12797 window
= create_window();
12798 ddraw
= create_ddraw();
12799 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12800 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12801 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12803 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12805 skip("Failed to create a YV12 overlay, skipping test.\n");
12809 memset(&desc
, 0, sizeof(desc
));
12810 desc
.dwSize
= sizeof(desc
);
12811 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12812 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12814 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
12815 "Got unexpected flags %#x.\n", desc
.dwFlags
);
12816 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
12817 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
12818 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
12819 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
12820 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
12821 /* The overlay pitch seems to have 256 byte alignment. */
12822 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
12824 /* Fill the surface with some data for the blit test. */
12825 base
= desc
.lpSurface
;
12827 for (y
= 0; y
< desc
.dwHeight
; ++y
)
12829 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
12832 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
12834 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
12837 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
12839 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
12842 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
12843 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12845 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
12846 * other block-based formats like DXT the entire Y channel is stored in
12847 * one big chunk of memory, followed by the chroma channels. So partial
12848 * locks do not really make sense. Show that they are allowed nevertheless
12849 * and the offset points into the luminance data. */
12850 hr
= IDirectDrawSurface7_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
12851 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12852 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
12853 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
12854 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
12855 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
12856 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12858 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12860 /* Windows XP with a Radeon X1600 GPU refuses to create a second
12861 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
12862 skip("Failed to create a second YV12 surface, skipping blit test.\n");
12863 IDirectDrawSurface7_Release(src_surface
);
12867 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
12868 /* VMware rejects YV12 blits. This behavior has not been seen on real
12869 * hardware yet, so mark it broken. */
12870 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
12874 memset(&desc
, 0, sizeof(desc
));
12875 desc
.dwSize
= sizeof(desc
);
12876 hr
= IDirectDrawSurface7_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12877 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12879 base
= desc
.lpSurface
;
12880 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
12881 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
12882 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
12883 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
12884 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
12886 hr
= IDirectDrawSurface7_Unlock(dst_surface
, NULL
);
12887 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12890 IDirectDrawSurface7_Release(dst_surface
);
12891 IDirectDrawSurface7_Release(src_surface
);
12893 IDirectDraw7_Release(ddraw
);
12894 DestroyWindow(window
);
12897 static BOOL
dwm_enabled(void)
12901 if (!strcmp(winetest_platform
, "wine"))
12903 if (!pDwmIsCompositionEnabled
)
12905 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
12910 static void test_offscreen_overlay(void)
12912 IDirectDrawSurface7
*overlay
, *offscreen
, *primary
;
12913 DDSURFACEDESC2 surface_desc
;
12914 IDirectDraw7
*ddraw
;
12919 window
= create_window();
12920 ddraw
= create_ddraw();
12921 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12922 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12923 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12925 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
12927 skip("Failed to create a UYVY overlay, skipping test.\n");
12931 memset(&surface_desc
, 0, sizeof(surface_desc
));
12932 surface_desc
.dwSize
= sizeof(surface_desc
);
12933 surface_desc
.dwFlags
= DDSD_CAPS
;
12934 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
12935 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
12936 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
12938 /* On Windows 7, and probably Vista, UpdateOverlay() will return
12939 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
12940 * surface prevents this by disabling the dwm. */
12941 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
12942 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
12943 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
12944 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
12946 /* Try to overlay a NULL surface. */
12947 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
12948 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12949 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
12950 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12952 /* Try to overlay an offscreen surface. */
12953 memset(&surface_desc
, 0, sizeof(surface_desc
));
12954 surface_desc
.dwSize
= sizeof(surface_desc
);
12955 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
12956 surface_desc
.dwWidth
= 64;
12957 surface_desc
.dwHeight
= 64;
12958 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12959 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12960 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12961 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
12962 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
12963 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
12964 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
12965 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
12966 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12967 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
12969 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
12970 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
12971 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
12972 "Failed to update overlay, hr %#x.\n", hr
);
12974 /* Try to overlay the primary with a non-overlay surface. */
12975 hr
= IDirectDrawSurface7_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
12976 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
12977 hr
= IDirectDrawSurface7_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
12978 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
12980 IDirectDrawSurface7_Release(offscreen
);
12981 IDirectDrawSurface7_Release(primary
);
12982 IDirectDrawSurface7_Release(overlay
);
12984 IDirectDraw7_Release(ddraw
);
12985 DestroyWindow(window
);
12988 static void test_overlay_rect(void)
12990 IDirectDrawSurface7
*overlay
, *primary
= NULL
;
12991 DDSURFACEDESC2 surface_desc
;
12992 RECT rect
= {0, 0, 64, 64};
12993 IDirectDraw7
*ddraw
;
12999 window
= create_window();
13000 ddraw
= create_ddraw();
13001 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13002 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13003 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13005 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
13007 skip("Failed to create a UYVY overlay, skipping test.\n");
13011 memset(&surface_desc
, 0, sizeof(surface_desc
));
13012 surface_desc
.dwSize
= sizeof(surface_desc
);
13013 surface_desc
.dwFlags
= DDSD_CAPS
;
13014 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13015 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13016 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
13018 /* On Windows 7, and probably Vista, UpdateOverlay() will return
13019 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
13020 * surface prevents this by disabling the dwm. */
13021 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
13022 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
13023 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
13024 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
13026 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
13029 win_skip("Cannot disable DWM, skipping overlay test.\n");
13033 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
13034 * used. This is not true in Windows Vista and earlier, but changed in
13036 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
13037 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
13038 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
13039 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
13040 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
13041 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13043 /* Show that the overlay position is the (top, left) coordinate of the
13044 * destination rectangle. */
13045 OffsetRect(&rect
, 32, 16);
13046 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
13047 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
13048 pos_x
= -1; pos_y
= -1;
13049 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13050 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
13051 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
13052 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
13054 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
13055 * seen that the overlay overlays the whole primary(==screen). */
13056 hr2
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
13057 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
13058 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13059 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
13060 if (SUCCEEDED(hr2
))
13062 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
13063 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
13067 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
13068 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
13071 /* The position cannot be retrieved when the overlay is not shown. */
13072 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
13073 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
13074 pos_x
= -1; pos_y
= -1;
13075 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13076 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
13077 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
13078 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
13082 IDirectDrawSurface7_Release(primary
);
13084 IDirectDrawSurface7_Release(overlay
);
13085 IDirectDraw7_Release(ddraw
);
13086 DestroyWindow(window
);
13089 static void test_blt(void)
13091 IDirectDrawSurface7
*surface
, *rt
;
13092 DDSURFACEDESC2 surface_desc
;
13093 IDirect3DDevice7
*device
;
13094 IDirectDraw7
*ddraw
;
13109 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
13110 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
13111 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
13112 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
13113 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
13114 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
13115 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
13116 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
13117 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
13118 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
13121 window
= create_window();
13122 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13124 skip("Failed to create a 3D device, skipping test.\n");
13125 DestroyWindow(window
);
13129 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13130 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13131 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13132 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13133 IDirect3D7_Release(d3d
);
13134 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
13135 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13137 memset(&surface_desc
, 0, sizeof(surface_desc
));
13138 surface_desc
.dwSize
= sizeof(surface_desc
);
13139 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13140 surface_desc
.dwWidth
= 640;
13141 surface_desc
.dwHeight
= 480;
13142 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13143 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13144 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13146 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
13147 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13149 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
13150 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13152 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13154 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13155 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13156 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
13158 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13159 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13160 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
13162 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13163 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13164 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13166 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
13167 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13170 IDirectDrawSurface7_Release(surface
);
13171 IDirectDrawSurface7_Release(rt
);
13172 IDirectDraw7_Release(ddraw
);
13173 refcount
= IDirect3DDevice7_Release(device
);
13174 ok(!refcount
, "Device has %u references left.\n", refcount
);
13175 DestroyWindow(window
);
13178 static void test_blt_z_alpha(void)
13180 DWORD blt_flags
[] =
13184 DDBLT_ALPHADESTCONSTOVERRIDE
,
13185 DDBLT_ALPHADESTNEG
,
13186 DDBLT_ALPHADESTSURFACEOVERRIDE
,
13187 DDBLT_ALPHAEDGEBLEND
,
13190 DDBLT_ALPHASRCCONSTOVERRIDE
,
13192 DDBLT_ALPHASRCSURFACEOVERRIDE
,
13195 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
13196 DDBLT_ZBUFFERDESTOVERRIDE
,
13197 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
13198 DDBLT_ZBUFFERSRCOVERRIDE
,
13200 IDirectDrawSurface7
*src_surface
, *dst_surface
;
13201 DDSURFACEDESC2 surface_desc
;
13202 IDirectDraw7
*ddraw
;
13211 window
= create_window();
13212 ddraw
= create_ddraw();
13213 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13214 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13215 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13217 memset(&pf
, 0, sizeof(pf
));
13218 pf
.dwSize
= sizeof(pf
);
13219 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13220 U1(pf
).dwRGBBitCount
= 32;
13221 U2(pf
).dwRBitMask
= 0x00ff0000;
13222 U3(pf
).dwGBitMask
= 0x0000ff00;
13223 U4(pf
).dwBBitMask
= 0x000000ff;
13224 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
13226 memset(&surface_desc
, 0, sizeof(surface_desc
));
13227 surface_desc
.dwSize
= sizeof(surface_desc
);
13228 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13229 surface_desc
.dwWidth
= 64;
13230 surface_desc
.dwHeight
= 64;
13231 U4(surface_desc
).ddpfPixelFormat
= pf
;
13232 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13234 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
13235 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
13236 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
13237 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
13239 memset(&fx
, 0, sizeof(fx
));
13240 fx
.dwSize
= sizeof(fx
);
13241 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
13242 fx
.dwZDestConstBitDepth
= 32;
13243 U1(fx
).dwZDestConst
= 0x11111111;
13244 fx
.dwZSrcConstBitDepth
= 32;
13245 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
13246 fx
.dwAlphaEdgeBlendBitDepth
= 8;
13247 fx
.dwAlphaEdgeBlend
= 0x7f;
13248 fx
.dwAlphaDestConstBitDepth
= 8;
13249 U3(fx
).dwAlphaDestConst
= 0xdd;
13250 fx
.dwAlphaSrcConstBitDepth
= 8;
13251 U4(fx
).dwAlphaSrcConst
= 0x22;
13253 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
13255 U5(fx
).dwFillColor
= 0x3300ff00;
13256 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13257 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13259 U5(fx
).dwFillColor
= 0xccff0000;
13260 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13261 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13263 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
13264 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13266 color
= get_surface_color(dst_surface
, 32, 32);
13267 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
13270 IDirectDrawSurface7_Release(dst_surface
);
13271 IDirectDrawSurface7_Release(src_surface
);
13272 refcount
= IDirectDraw7_Release(ddraw
);
13273 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13274 DestroyWindow(window
);
13277 static void test_cross_device_blt(void)
13279 IDirectDrawSurface7
*surface
, *surface2
, *sysmem_surface
;
13280 IDirect3DDevice7
*device
, *device2
;
13281 IDirectDraw7
*ddraw
, *ddraw2
;
13282 DDSURFACEDESC2 surface_desc
;
13283 HWND window
, window2
;
13290 window
= create_window();
13291 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
13293 skip("Failed to create a 3D device.\n");
13294 DestroyWindow(window
);
13298 window2
= create_window();
13299 if (!(device2
= create_device(window2
, DDSCL_NORMAL
)))
13301 skip("Failed to create a 3D device.\n");
13302 IDirect3DDevice7_Release(device
);
13303 DestroyWindow(window
);
13304 DestroyWindow(window2
);
13308 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13309 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13310 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13311 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13312 IDirect3D7_Release(d3d
);
13314 hr
= IDirect3DDevice7_GetDirect3D(device2
, &d3d
);
13315 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13316 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw2
);
13317 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13318 IDirect3D7_Release(d3d
);
13320 memset(&surface_desc
, 0, sizeof(surface_desc
));
13321 surface_desc
.dwSize
= sizeof(surface_desc
);
13322 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13323 surface_desc
.dwWidth
= 640;
13324 surface_desc
.dwHeight
= 480;
13325 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13326 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
13327 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13329 memset(&surface_desc
, 0, sizeof(surface_desc
));
13330 surface_desc
.dwSize
= sizeof(surface_desc
);
13331 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13332 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
13333 U5(surface_desc
).dwBackBufferCount
= 2;
13334 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13335 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13337 memset(&surface_desc
, 0, sizeof(surface_desc
));
13338 surface_desc
.dwSize
= sizeof(surface_desc
);
13339 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13340 surface_desc
.dwWidth
= 640;
13341 surface_desc
.dwHeight
= 480;
13342 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13343 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
13344 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13345 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
13346 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
13347 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
13348 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
13349 hr
= IDirectDraw7_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13350 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13352 memset(&fx
, 0, sizeof(fx
));
13353 fx
.dwSize
= sizeof(fx
);
13354 U5(fx
).dwFillColor
= 0xff0000ff;
13355 hr
= IDirectDrawSurface7_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13356 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
13358 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13359 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13360 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
13361 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13362 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13363 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13364 color
= get_surface_color(surface
, 320, 240);
13365 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13367 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13368 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13369 color
= get_surface_color(sysmem_surface
, 320, 240);
13370 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13372 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13373 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13374 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
13375 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13377 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13378 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13379 color
= get_surface_color(sysmem_surface
, 320, 240);
13380 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13382 IDirectDrawSurface7_Release(surface2
);
13383 memset(&surface_desc
, 0, sizeof(surface_desc
));
13384 surface_desc
.dwSize
= sizeof(surface_desc
);
13385 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13386 surface_desc
.dwWidth
= 640;
13387 surface_desc
.dwHeight
= 480;
13388 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13389 hr
= IDirectDraw7_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13390 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13391 hr
= IDirectDrawSurface7_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13392 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
13394 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13395 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#x.\n", hr
);
13396 color
= get_surface_color(sysmem_surface
, 320, 240);
13397 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13399 IDirectDrawSurface7_Release(surface
);
13400 IDirectDrawSurface7_Release(surface2
);
13401 IDirectDrawSurface7_Release(sysmem_surface
);
13402 IDirectDraw7_Release(ddraw
);
13403 IDirectDraw7_Release(ddraw2
);
13404 refcount
= IDirect3DDevice7_Release(device
);
13405 ok(!refcount
, "Device has %u references left.\n", refcount
);
13406 refcount
= IDirect3DDevice7_Release(device2
);
13407 ok(!refcount
, "Device has %u references left.\n", refcount
);
13408 DestroyWindow(window
);
13409 DestroyWindow(window2
);
13412 static void test_color_clamping(void)
13414 static D3DMATRIX mat
=
13416 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13417 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13418 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13419 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13421 static struct vec3 quad
[] =
13423 {-1.0f
, -1.0f
, 0.1f
},
13424 {-1.0f
, 1.0f
, 0.1f
},
13425 { 1.0f
, -1.0f
, 0.1f
},
13426 { 1.0f
, 1.0f
, 0.1f
},
13428 IDirect3DDevice7
*device
;
13429 IDirectDrawSurface7
*rt
;
13435 window
= create_window();
13436 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13438 skip("Failed to create a 3D device, skipping test.\n");
13439 DestroyWindow(window
);
13443 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
13444 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13446 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
13447 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13448 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
13449 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
13450 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
13451 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
13452 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
13453 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
13454 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13455 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
13456 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13457 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
13458 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
13459 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
13460 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13461 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
13462 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13463 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
13465 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
13466 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
13467 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
13468 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
13469 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
13470 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13471 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
13472 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13473 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
13474 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
13475 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
13476 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13477 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
13478 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13480 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
13481 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13483 hr
= IDirect3DDevice7_BeginScene(device
);
13484 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13486 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
13487 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13489 hr
= IDirect3DDevice7_EndScene(device
);
13490 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13492 color
= get_surface_color(rt
, 320, 240);
13493 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
13495 IDirectDrawSurface7_Release(rt
);
13496 refcount
= IDirect3DDevice7_Release(device
);
13497 ok(!refcount
, "Device has %u references left.\n", refcount
);
13498 DestroyWindow(window
);
13501 static void test_getdc(void)
13503 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, DDSCAPS2_CUBEMAP_NEGATIVEZ
, 0, {0}};
13504 IDirectDrawSurface7
*surface
, *surface2
, *tmp
;
13505 DDSURFACEDESC2 surface_desc
, map_desc
;
13506 IDirectDraw7
*ddraw
;
13507 unsigned int i
, screen_bpp
;
13512 static const struct
13515 DDPIXELFORMAT format
;
13516 BOOL getdc_supported
;
13517 HRESULT alt_result
;
13521 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13522 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
13523 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13524 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
13525 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13526 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13527 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13528 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13529 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13530 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
13531 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13532 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13533 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13534 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13535 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13536 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
13537 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13538 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13539 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13540 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13541 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
13542 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
13543 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
13544 * This is not implemented in wine yet, so disable the test for now.
13545 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
13546 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
13547 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
13549 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
13550 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13551 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
13552 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
13553 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
13554 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13555 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
13556 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13557 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
13558 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13559 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
13560 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13561 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
13562 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13565 window
= create_window();
13566 ddraw
= create_ddraw();
13567 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13568 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13569 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13571 surface_desc
.dwSize
= sizeof(surface_desc
);
13572 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
13573 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13574 screen_bpp
= U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
;
13576 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13578 memset(&surface_desc
, 0, sizeof(surface_desc
));
13579 surface_desc
.dwSize
= sizeof(surface_desc
);
13580 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13581 surface_desc
.dwWidth
= 64;
13582 surface_desc
.dwHeight
= 64;
13583 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
13584 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13586 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13588 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13589 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
13590 if (FAILED(hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13592 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
13597 dc
= (void *)0x1234;
13598 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13599 if (test_data
[i
].getdc_supported
)
13600 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
13601 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13603 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13607 unsigned int width_bytes
;
13613 type
= GetObjectType(dc
);
13614 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
13615 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
13616 type
= GetObjectType(bitmap
);
13617 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
13619 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
13620 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
13621 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
13622 dib
.dsBm
.bmType
, test_data
[i
].name
);
13623 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
13624 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
13625 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
13626 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
13627 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
13628 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
13629 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
13630 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
13631 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
13632 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
13633 "Got unexpected bit count %d for format %s.\n",
13634 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
13635 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
13636 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
13637 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
13638 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
13639 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
13641 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
13642 dib
.dsBmih
.biSize
, test_data
[i
].name
);
13643 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
13644 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13645 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
13646 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13647 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
13648 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
13649 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
13650 "Got unexpected bit count %u for format %s.\n",
13651 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
13652 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
13653 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
13654 "Got unexpected compression %#x for format %s.\n",
13655 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
13656 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
13657 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
13658 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
13659 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
13660 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
13661 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
13662 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
13663 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
13664 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
13665 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
13667 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
13669 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
13670 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
13671 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
13672 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
13673 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
13674 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13678 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
13679 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
13680 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13682 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
13683 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
13685 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13686 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13690 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13693 IDirectDrawSurface7_Release(surface
);
13698 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
13699 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_TEXTUREMANAGE
;
13700 if (FAILED(hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13702 skip("Failed to create cube texture for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
13706 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
13707 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13708 hr
= IDirectDrawSurface7_GetAttachedSurface(surface2
, &caps
, &tmp
);
13709 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13710 IDirectDrawSurface7_Release(surface2
);
13711 hr
= IDirectDrawSurface7_GetAttachedSurface(tmp
, &caps
, &surface2
);
13712 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13713 IDirectDrawSurface7_Release(tmp
);
13715 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13716 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13717 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13718 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13719 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13720 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13721 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13722 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13724 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13725 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13726 dc2
= (void *)0x1234;
13727 hr
= IDirectDrawSurface7_GetDC(surface
, &dc2
);
13728 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13729 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13730 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13731 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13732 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13733 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13735 map_desc
.dwSize
= sizeof(map_desc
);
13736 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13737 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13738 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13739 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13740 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13741 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13742 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13743 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13745 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13746 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13747 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13748 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13749 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13750 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13752 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13753 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13754 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13755 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13756 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13757 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13758 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13759 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13761 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13762 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13763 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc2
);
13764 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13765 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc2
);
13766 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13767 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13768 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13770 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13771 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13772 hr
= IDirectDrawSurface7_GetDC(surface
, &dc2
);
13773 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13774 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc2
);
13775 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13776 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13777 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13779 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13780 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13781 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13782 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13783 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13784 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13785 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13786 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13788 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13789 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13790 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13791 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13792 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13793 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13794 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13795 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13797 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13798 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13799 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13800 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13801 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13802 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13803 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13804 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13806 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13807 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13808 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13809 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13810 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13811 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13812 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13813 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13815 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13816 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13817 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13818 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13819 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13820 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13821 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13822 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13824 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13825 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13826 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13827 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13828 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13829 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13830 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13831 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13832 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13833 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13835 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13836 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13837 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13838 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13839 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13840 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13841 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13842 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13843 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13844 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13846 IDirectDrawSurface7_Release(surface2
);
13847 IDirectDrawSurface7_Release(surface
);
13850 IDirectDraw7_Release(ddraw
);
13851 DestroyWindow(window
);
13854 static void test_draw_primitive(void)
13856 static WORD indices
[] = {0, 1, 2, 3};
13857 static struct vec3 quad
[] =
13859 {-1.0f
, -1.0f
, 0.0f
},
13860 {-1.0f
, 1.0f
, 0.0f
},
13861 { 1.0f
, -1.0f
, 0.0f
},
13862 { 1.0f
, 1.0f
, 0.0f
},
13864 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
13865 D3DVERTEXBUFFERDESC vb_desc
;
13866 IDirect3DVertexBuffer7
*vb
;
13867 IDirect3DDevice7
*device
;
13869 IDirectDraw7
*ddraw
;
13875 window
= create_window();
13876 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13878 skip("Failed to create a 3D device, skipping test.\n");
13879 DestroyWindow(window
);
13883 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13884 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
13885 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13886 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13888 memset(&vb_desc
, 0, sizeof(vb_desc
));
13889 vb_desc
.dwSize
= sizeof(vb_desc
);
13890 vb_desc
.dwFVF
= D3DFVF_XYZ
;
13891 vb_desc
.dwNumVertices
= 4;
13892 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
13893 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
13895 IDirect3D7_Release(d3d
);
13897 memset(&strided
, 0, sizeof(strided
));
13899 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
13900 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13901 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13902 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
13903 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13904 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, NULL
, 0, 0);
13905 todo_wine
ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
13906 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, NULL
, 0, 0);
13907 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13908 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
13909 /* r200 rejects 0 vertices */
13910 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13911 hr
= IDirect3DDevice7_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
13912 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13913 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
13914 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13916 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
13917 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13918 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13919 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
13920 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13921 /* Interestingly r200 rejects this, but not the call with a NULL index buffer and 0 indices. */
13922 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, indices
, 4, 0);
13923 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13925 strided
.position
.lpvData
= quad
;
13926 strided
.position
.dwStride
= sizeof(*quad
);
13927 hr
= IDirect3DVertexBuffer7_Lock(vb
, 0, &data
, NULL
);
13928 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
13929 memcpy(data
, quad
, sizeof(quad
));
13930 hr
= IDirect3DVertexBuffer7_Unlock(vb
);
13931 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
13933 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
13934 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13935 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13936 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
13937 /* r200 again fails this, this time with E_OUTOFMEMORY. */
13938 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_OUTOFMEMORY
), "Failed to draw, hr %#x.\n", hr
);
13939 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, NULL
, 0, 0);
13940 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13941 /* Now this draw should work, but r200 rejects it too - presumably earlier tests broke
13942 * driver internal state. */
13943 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
13944 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13945 hr
= IDirect3DDevice7_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
13946 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13947 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
13948 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13950 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
13951 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13952 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13953 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
13954 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13955 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, indices
, 4, 0);
13956 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13958 IDirect3DVertexBuffer7_Release(vb
);
13959 IDirectDraw7_Release(ddraw
);
13960 refcount
= IDirect3DDevice7_Release(device
);
13961 ok(!refcount
, "Device has %u references left.\n", refcount
);
13962 DestroyWindow(window
);
13965 static void test_edge_antialiasing_blending(void)
13967 IDirectDrawSurface7
*offscreen
;
13968 DDSURFACEDESC2 surface_desc
;
13969 D3DDEVICEDESC7 device_desc
;
13970 IDirect3DDevice7
*device
;
13971 IDirectDraw7
*ddraw
;
13978 static D3DMATRIX mat
=
13980 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13981 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13982 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13983 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13987 struct vec3 position
;
13992 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
13993 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
13994 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
13995 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
13999 struct vec3 position
;
14004 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
14005 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
14006 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
14007 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
14010 window
= create_window();
14011 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14013 skip("Failed to create a 3D device.\n");
14014 DestroyWindow(window
);
14018 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
14019 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
14020 trace("Line edge antialiasing support: %#x.\n",
14021 device_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14022 trace("Triangle edge antialiasing support: %#x.\n",
14023 device_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14025 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
14026 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
14027 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
14028 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
14029 IDirect3D7_Release(d3d
);
14031 memset(&surface_desc
, 0, sizeof(surface_desc
));
14032 surface_desc
.dwSize
= sizeof(surface_desc
);
14033 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
14034 surface_desc
.dwWidth
= 640;
14035 surface_desc
.dwHeight
= 480;
14036 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
14037 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
14038 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14039 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14040 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14041 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14042 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
14043 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
14044 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
14046 hr
= IDirect3DDevice7_SetRenderTarget(device
, offscreen
, 0);
14047 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
14049 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
14050 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
14051 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
14052 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
14053 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
14054 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
14055 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
14056 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
14057 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
14058 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
14059 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
14060 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
14061 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
14062 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
14063 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
14064 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
14065 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14066 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
14068 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
14069 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
14070 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
14071 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
14072 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
14073 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
14075 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
14076 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
14077 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
14078 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
14079 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
14080 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
14081 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
14082 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
14084 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14085 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14086 hr
= IDirect3DDevice7_BeginScene(device
);
14087 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14088 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14090 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14091 hr
= IDirect3DDevice7_EndScene(device
);
14092 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14093 color
= get_surface_color(offscreen
, 320, 240);
14094 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
14096 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14097 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14098 hr
= IDirect3DDevice7_BeginScene(device
);
14099 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14100 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14102 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14103 hr
= IDirect3DDevice7_EndScene(device
);
14104 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14105 color
= get_surface_color(offscreen
, 320, 240);
14106 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
14108 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
14109 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
14111 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14112 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14113 hr
= IDirect3DDevice7_BeginScene(device
);
14114 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14115 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14117 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14118 hr
= IDirect3DDevice7_EndScene(device
);
14119 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14120 color
= get_surface_color(offscreen
, 320, 240);
14121 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14123 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14124 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14125 hr
= IDirect3DDevice7_BeginScene(device
);
14126 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14127 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14129 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14130 hr
= IDirect3DDevice7_EndScene(device
);
14131 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14132 color
= get_surface_color(offscreen
, 320, 240);
14133 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14135 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
14136 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
14138 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14139 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14140 hr
= IDirect3DDevice7_BeginScene(device
);
14141 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14142 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14144 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14145 hr
= IDirect3DDevice7_EndScene(device
);
14146 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14147 color
= get_surface_color(offscreen
, 320, 240);
14148 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14150 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14151 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14152 hr
= IDirect3DDevice7_BeginScene(device
);
14153 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14154 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14156 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14157 hr
= IDirect3DDevice7_EndScene(device
);
14158 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14159 color
= get_surface_color(offscreen
, 320, 240);
14160 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14162 IDirectDrawSurface7_Release(offscreen
);
14163 IDirectDraw7_Release(ddraw
);
14164 refcount
= IDirect3DDevice7_Release(device
);
14165 ok(!refcount
, "Device has %u references left.\n", refcount
);
14166 DestroyWindow(window
);
14169 static void test_display_mode_surface_pixel_format(void)
14171 unsigned int width
, height
, bpp
;
14172 IDirectDrawSurface7
*surface
;
14173 DDSURFACEDESC2 surface_desc
;
14174 IDirectDraw7
*ddraw
;
14179 if (!(ddraw
= create_ddraw()))
14181 skip("Failed to create ddraw.\n");
14185 surface_desc
.dwSize
= sizeof(surface_desc
);
14186 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
14187 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14188 width
= surface_desc
.dwWidth
;
14189 height
= surface_desc
.dwHeight
;
14191 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14192 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
14193 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14194 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14197 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
14199 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
14201 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
14203 ok(bpp
, "Set display mode failed.\n");
14205 surface_desc
.dwSize
= sizeof(surface_desc
);
14206 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
14207 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14208 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
14209 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
14210 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14211 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14213 memset(&surface_desc
, 0, sizeof(surface_desc
));
14214 surface_desc
.dwSize
= sizeof(surface_desc
);
14215 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14216 U5(surface_desc
).dwBackBufferCount
= 1;
14217 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
14218 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14219 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14220 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
14221 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14222 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
14223 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
14224 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
14225 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
14226 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14227 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14228 IDirectDrawSurface7_Release(surface
);
14230 memset(&surface_desc
, 0, sizeof(surface_desc
));
14231 surface_desc
.dwSize
= sizeof(surface_desc
);
14232 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
14233 surface_desc
.dwWidth
= width
;
14234 surface_desc
.dwHeight
= height
;
14235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14236 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14237 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14238 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
14239 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14240 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
14241 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
14242 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14243 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14244 IDirectDrawSurface7_Release(surface
);
14246 /* Test compatibility mode mipmap texture creation. */
14247 hr
= IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0);
14248 ok(hr
== DD_OK
|| hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
14251 win_skip("SetDisplayMode failed, skipping test.");
14256 memset(&surface_desc
, 0, sizeof(surface_desc
));
14257 surface_desc
.dwSize
= sizeof(surface_desc
);
14258 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
| DDSD_PITCH
;
14259 U2(surface_desc
).dwMipMapCount
= 2;
14260 surface_desc
.dwWidth
= 4;
14261 surface_desc
.dwHeight
= 4;
14262 U1(surface_desc
).lPitch
= surface_desc
.dwWidth
* bpp
/ 8;
14263 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
| DDSCAPS_VIDEOMEMORY
;
14264 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14265 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#x.\n", hr
);
14267 IDirectDrawSurface7_Release(surface
);
14270 refcount
= IDirectDraw7_Release(ddraw
);
14271 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14272 DestroyWindow(window
);
14275 static void test_surface_desc_size(void)
14280 DDSURFACEDESC desc1
;
14281 DDSURFACEDESC2 desc2
;
14284 IDirectDrawSurface7
*surface7
;
14285 IDirectDrawSurface3
*surface3
;
14286 IDirectDrawSurface
*surface
;
14287 DDSURFACEDESC2 surface_desc
;
14288 HRESULT expected_hr
, hr
;
14289 IDirectDraw7
*ddraw
;
14293 static const struct
14300 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
14301 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
14302 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
14304 static const unsigned int desc_sizes
[] =
14306 sizeof(DDSURFACEDESC
),
14307 sizeof(DDSURFACEDESC2
),
14308 sizeof(DDSURFACEDESC
) + 1,
14309 sizeof(DDSURFACEDESC2
) + 1,
14310 2 * sizeof(DDSURFACEDESC
),
14311 2 * sizeof(DDSURFACEDESC2
),
14312 sizeof(DDSURFACEDESC
) - 1,
14313 sizeof(DDSURFACEDESC2
) - 1,
14314 sizeof(DDSURFACEDESC
) / 2,
14315 sizeof(DDSURFACEDESC2
) / 2,
14320 sizeof(desc
) - 100,
14323 if (!(ddraw
= create_ddraw()))
14325 skip("Failed to create ddraw.\n");
14328 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
14329 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14331 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
14333 memset(&surface_desc
, 0, sizeof(surface_desc
));
14334 surface_desc
.dwSize
= sizeof(surface_desc
);
14335 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
14336 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
14337 surface_desc
.dwHeight
= 128;
14338 surface_desc
.dwWidth
= 128;
14339 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface7
, NULL
)))
14341 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
14344 hr
= IDirectDrawSurface_QueryInterface(surface7
, &IID_IDirectDrawSurface
, (void **)&surface
);
14345 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
14346 hr
= IDirectDrawSurface_QueryInterface(surface7
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
14347 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
14349 /* GetSurfaceDesc() */
14350 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14352 memset(&desc
, 0, sizeof(desc
));
14353 desc
.dwSize
= desc_sizes
[j
];
14354 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14355 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
14356 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14357 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14359 memset(&desc
, 0, sizeof(desc
));
14360 desc
.dwSize
= desc_sizes
[j
];
14361 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14362 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
14363 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14364 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14366 memset(&desc
, 0, sizeof(desc
));
14367 desc
.dwSize
= desc_sizes
[j
];
14368 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14369 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
14370 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14371 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14375 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14377 const BOOL ignore_size
= surface_caps
[i
].caps
& DDSCAPS_TEXTURE
14378 && !(surface_caps
[i
].caps
& DDSCAPS_VIDEOMEMORY
);
14379 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
14380 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
14381 DWORD expected_texture_stage
;
14383 memset(&desc
, 0, sizeof(desc
));
14384 desc
.dwSize
= desc_sizes
[j
];
14385 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14386 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14387 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
14388 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14389 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14390 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14391 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14392 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14393 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14394 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14397 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14398 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14399 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14400 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14401 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14402 todo_wine_if(!expected_texture_stage
)
14403 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14404 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14405 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14406 IDirectDrawSurface_Unlock(surface
, NULL
);
14409 memset(&desc
, 0, sizeof(desc
));
14410 desc
.dwSize
= desc_sizes
[j
];
14411 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14412 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14413 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
14414 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14415 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14416 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14417 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14418 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14419 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14420 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14423 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14424 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14425 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14426 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14427 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14428 todo_wine_if(!expected_texture_stage
)
14429 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14430 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14431 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14432 IDirectDrawSurface3_Unlock(surface3
, NULL
);
14435 memset(&desc
, 0, sizeof(desc
));
14436 desc
.dwSize
= desc_sizes
[j
];
14437 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14438 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14439 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
14440 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14441 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14442 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14443 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14444 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14445 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14446 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14449 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14450 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14451 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14452 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14453 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14454 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14455 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14456 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14457 IDirectDrawSurface7_Unlock(surface7
, NULL
);
14461 IDirectDrawSurface7_Release(surface7
);
14462 IDirectDrawSurface3_Release(surface3
);
14463 IDirectDrawSurface_Release(surface
);
14466 /* GetDisplayMode() */
14467 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14469 memset(&desc
, 0xcc, sizeof(desc
));
14470 desc
.dwSize
= desc_sizes
[j
];
14471 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
14472 ? DD_OK
: DDERR_INVALIDPARAMS
;
14473 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &desc
.desc2
);
14474 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
14477 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
14478 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
14479 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
14483 refcount
= IDirectDraw7_Release(ddraw
);
14484 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14487 static void test_get_surface_from_dc(void)
14489 IDirectDrawSurface
*surface1
, *tmp1
;
14490 IDirectDrawSurface7
*surface
, *tmp
;
14491 DDSURFACEDESC2 surface_desc
;
14492 IDirectDraw7
*ddraw
;
14499 window
= create_window();
14500 ddraw
= create_ddraw();
14501 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14502 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14503 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14505 memset(&surface_desc
, 0, sizeof(surface_desc
));
14506 surface_desc
.dwSize
= sizeof(surface_desc
);
14507 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14508 surface_desc
.dwWidth
= 64;
14509 surface_desc
.dwHeight
= 64;
14510 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14512 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14513 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14514 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
14515 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14517 refcount
= get_refcount((IUnknown
*)surface1
);
14518 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14519 refcount
= get_refcount((IUnknown
*)surface
);
14520 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14522 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
14523 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
14525 tmp1
= (void *)0xdeadbeef;
14526 device_dc
= (void *)0xdeadbeef;
14527 hr
= GetSurfaceFromDC(NULL
, &tmp1
, &device_dc
);
14528 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14529 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14530 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
14532 device_dc
= (void *)0xdeadbeef;
14533 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
14534 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14535 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
14537 tmp1
= (void *)0xdeadbeef;
14538 hr
= GetSurfaceFromDC(dc
, &tmp1
, NULL
);
14539 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14540 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14542 hr
= GetSurfaceFromDC(dc
, &tmp1
, &device_dc
);
14543 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14544 ok(tmp1
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp1
, surface1
);
14545 IDirectDrawSurface_Release(tmp1
);
14547 ret
= GetObjectType(device_dc
);
14548 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#x.\n", ret
);
14549 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
14550 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#x.\n", ret
);
14552 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, NULL
);
14553 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14555 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, &tmp
);
14556 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14557 ok(tmp
== surface
, "Got unexpected surface %p, expected %p.\n", tmp
, surface
);
14559 refcount
= get_refcount((IUnknown
*)surface1
);
14560 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14561 refcount
= get_refcount((IUnknown
*)surface
);
14562 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14564 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
14565 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#x.\n", hr
);
14567 IDirectDrawSurface_Release(tmp
);
14569 dc
= CreateCompatibleDC(NULL
);
14570 ok(!!dc
, "CreateCompatibleDC failed.\n");
14572 tmp1
= (void *)0xdeadbeef;
14573 device_dc
= (void *)0xdeadbeef;
14574 hr
= GetSurfaceFromDC(dc
, &tmp1
, &device_dc
);
14575 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14576 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14577 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
14579 tmp
= (void *)0xdeadbeef;
14580 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, &tmp
);
14581 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14582 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14584 ok(DeleteDC(dc
), "DeleteDC failed.\n");
14586 tmp
= (void *)0xdeadbeef;
14587 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, NULL
, &tmp
);
14588 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14589 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14591 IDirectDrawSurface7_Release(surface
);
14592 IDirectDrawSurface_Release(surface1
);
14593 IDirectDraw7_Release(ddraw
);
14594 DestroyWindow(window
);
14597 static void test_ck_operation(void)
14599 IDirectDrawSurface7
*src
, *dst
;
14600 IDirectDrawSurface
*src1
, *dst1
;
14601 DDSURFACEDESC2 surface_desc
;
14602 IDirectDraw7
*ddraw
;
14611 window
= create_window();
14612 ddraw
= create_ddraw();
14613 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14614 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14615 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14617 memset(&surface_desc
, 0, sizeof(surface_desc
));
14618 surface_desc
.dwSize
= sizeof(surface_desc
);
14619 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14620 surface_desc
.dwWidth
= 4;
14621 surface_desc
.dwHeight
= 1;
14622 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14623 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
14624 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14625 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14626 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14627 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14628 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14629 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14631 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
14632 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
14633 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
14634 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14635 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14637 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14638 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14639 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14640 color
= surface_desc
.lpSurface
;
14641 color
[0] = 0x77010203;
14642 color
[1] = 0x00010203;
14643 color
[2] = 0x77ff00ff;
14644 color
[3] = 0x00ff00ff;
14645 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
14646 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14648 for (i
= 0; i
< 2; ++i
)
14650 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14651 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14652 color
= surface_desc
.lpSurface
;
14653 color
[0] = 0xcccccccc;
14654 color
[1] = 0xcccccccc;
14655 color
[2] = 0xcccccccc;
14656 color
[3] = 0xcccccccc;
14657 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14658 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14662 hr
= IDirectDrawSurface7_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
14663 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14667 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
14668 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14671 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
14672 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14673 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14674 color
= surface_desc
.lpSurface
;
14675 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
14676 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
14677 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
14678 * color keying nor copies it. */
14679 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
14680 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
14681 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14682 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
14683 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14684 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
14685 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
14686 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
14687 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
14688 color
[0], color
[1], color
[2], color
[3], i
);
14689 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14690 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14693 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14694 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14695 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
14696 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14698 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14699 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14700 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14702 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14703 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14704 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14705 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
14706 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14708 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
14709 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
14710 hr
= IDirectDrawSurface7_GetSurfaceDesc(src
, &surface_desc
);
14711 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
14712 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
14713 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
14714 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
14715 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
14717 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
14718 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14719 ckey
.dwColorSpaceHighValue
= 0x00000000;
14720 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14721 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14723 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14724 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14725 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14726 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14727 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14729 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14730 ckey
.dwColorSpaceHighValue
= 0x00000001;
14731 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14732 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14734 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14735 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14736 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14737 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14738 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14740 ckey
.dwColorSpaceLowValue
= 0x000000fe;
14741 ckey
.dwColorSpaceHighValue
= 0x000000fd;
14742 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14743 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14745 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14746 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14747 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14748 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
14749 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14751 IDirectDrawSurface7_Release(src
);
14752 IDirectDrawSurface7_Release(dst
);
14754 /* Test source and destination keys and where they are read from. Use a surface with alpha
14755 * to avoid driver-dependent content in the X channel. */
14756 memset(&surface_desc
, 0, sizeof(surface_desc
));
14757 surface_desc
.dwSize
= sizeof(surface_desc
);
14758 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14759 surface_desc
.dwWidth
= 6;
14760 surface_desc
.dwHeight
= 1;
14761 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14762 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
14763 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14764 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14765 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14766 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14767 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
14768 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14769 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14770 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14771 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14773 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
14774 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14775 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
14776 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14777 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
14778 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
14779 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
14780 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
14783 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
14784 skip("Failed to set destination color key, skipping related tests.\n");
14788 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14789 ckey
.dwColorSpaceHighValue
= 0x000000ff;
14790 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14791 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14792 ckey
.dwColorSpaceLowValue
= 0x000000aa;
14793 ckey
.dwColorSpaceHighValue
= 0x000000aa;
14794 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
14795 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14797 memset(&fx
, 0, sizeof(fx
));
14798 fx
.dwSize
= sizeof(fx
);
14799 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
14800 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
14801 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
14802 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
14804 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14805 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14806 color
= surface_desc
.lpSurface
;
14807 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
14808 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
14809 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
14810 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
14811 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
14812 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
14813 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
14814 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14816 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14817 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14818 color
= surface_desc
.lpSurface
;
14819 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14820 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14821 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14823 /* Test a blit without keying. */
14824 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
14825 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14827 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14828 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14829 color
= surface_desc
.lpSurface
;
14830 /* Should have copied src data unmodified to dst. */
14831 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14832 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14833 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14834 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14836 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14837 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14838 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14841 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
14842 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14844 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14845 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14846 color
= surface_desc
.lpSurface
;
14847 /* Src key applied to color[0]. It is unmodified, the others are copied. */
14848 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14849 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14850 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14851 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14853 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14854 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14855 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14857 /* Src override. */
14858 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
14859 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14861 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14862 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14863 color
= surface_desc
.lpSurface
;
14864 /* Override key applied to color[5]. It is unmodified, the others are copied. */
14865 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14866 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
14867 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14868 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14870 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14871 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14872 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14874 /* Src override AND src key. That is not supposed to work. */
14875 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
14876 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14878 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14879 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14880 color
= surface_desc
.lpSurface
;
14881 /* Ensure the destination was not changed. */
14882 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
14883 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
14884 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14885 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14887 /* Use different dst colors for the dst key test. */
14888 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14889 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14890 color
[2] = 0x00001100; /* Dest key in override. */
14891 color
[3] = 0x00001100; /* Dest key in override. */
14892 color
[4] = 0x000000aa; /* Dest key in src surface. */
14893 color
[5] = 0x000000aa; /* Dest key in src surface. */
14894 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14895 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14897 /* Dest key blit. The key is taken from the DESTINATION surface in v7! */
14898 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14899 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14901 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14902 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14903 color
= surface_desc
.lpSurface
;
14904 /* Dst key applied to color[0,1], they are the only changed pixels. */
14905 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
14906 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14907 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14908 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14910 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14911 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14912 color
[2] = 0x00001100; /* Dest key in override. */
14913 color
[3] = 0x00001100; /* Dest key in override. */
14914 color
[4] = 0x000000aa; /* Dest key in src surface. */
14915 color
[5] = 0x000000aa; /* Dest key in src surface. */
14916 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14917 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14919 /* What happens with a QI'd older version of the interface? It takes the key
14920 * from the source surface. */
14921 hr
= IDirectDrawSurface7_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
14922 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14923 hr
= IDirectDrawSurface7_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
14924 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14926 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
14927 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14929 IDirectDrawSurface_Release(dst1
);
14930 IDirectDrawSurface_Release(src1
);
14932 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14933 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14934 color
= surface_desc
.lpSurface
;
14935 /* Dst key applied to color[4,5], they are the only changed pixels. */
14936 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14937 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14938 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14939 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14941 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14942 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14943 color
[2] = 0x00001100; /* Dest key in override. */
14944 color
[3] = 0x00001100; /* Dest key in override. */
14945 color
[4] = 0x000000aa; /* Dest key in src surface. */
14946 color
[5] = 0x000000aa; /* Dest key in src surface. */
14947 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14948 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14950 /* Dest override key blit. */
14951 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
14952 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14954 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14955 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14956 color
= surface_desc
.lpSurface
;
14957 /* Dst key applied to color[2,3], they are the only changed pixels. */
14958 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
14959 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14960 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14961 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14963 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14964 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14965 color
[2] = 0x00001100; /* Dest key in override. */
14966 color
[3] = 0x00001100; /* Dest key in override. */
14967 color
[4] = 0x000000aa; /* Dest key in src surface. */
14968 color
[5] = 0x000000aa; /* Dest key in src surface. */
14969 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14970 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14972 /* Dest override together with surface key. Supposed to fail. */
14973 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
14974 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14976 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14977 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14978 color
= surface_desc
.lpSurface
;
14979 /* Destination is unchanged. */
14980 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14981 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14982 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14983 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14984 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14985 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14987 /* Source and destination key. This is driver dependent. New HW treats it like
14988 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
14991 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
14992 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14994 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14995 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14996 color
= surface_desc
.lpSurface
;
14997 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
14998 * the driver applies it. */
14999 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
15000 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
15001 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15002 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15004 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15005 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15006 color
[2] = 0x00001100; /* Dest key in override. */
15007 color
[3] = 0x00001100; /* Dest key in override. */
15008 color
[4] = 0x000000aa; /* Dest key in src surface. */
15009 color
[5] = 0x000000aa; /* Dest key in src surface. */
15010 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
15011 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
15014 /* Override keys without ddbltfx parameter fail */
15015 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
15016 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15017 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
15018 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15020 /* Try blitting without keys in the source surface. */
15021 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
15022 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
15023 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
15024 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
15026 /* That fails now. Do not bother to check that the data is unmodified. */
15027 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
15028 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15030 /* Dest key blit still works, the destination surface key is used in v7. */
15031 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
15032 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
15034 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15035 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
15036 color
= surface_desc
.lpSurface
;
15037 /* Dst key applied to color[0,1], they are the only changed pixels. */
15038 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
15039 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
15040 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15041 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15042 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
15043 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
15045 /* Try blitting without keys in the destination surface. */
15046 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
15047 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
15048 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
15049 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
15051 /* This fails, as sanity would dictate. */
15052 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
15053 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15056 IDirectDrawSurface7_Release(src
);
15057 IDirectDrawSurface7_Release(dst
);
15058 refcount
= IDirectDraw7_Release(ddraw
);
15059 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
15060 DestroyWindow(window
);
15063 static void test_vb_refcount(void)
15065 ULONG prev_d3d_refcount
, prev_device_refcount
;
15066 ULONG cur_d3d_refcount
, cur_device_refcount
;
15067 IDirect3DVertexBuffer7
*vb
, *vb7
;
15068 D3DVERTEXBUFFERDESC vb_desc
;
15069 IDirect3DVertexBuffer
*vb1
;
15070 IDirect3DDevice7
*device
;
15077 window
= create_window();
15078 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15080 skip("Failed to create a 3D device, skipping test.\n");
15081 DestroyWindow(window
);
15085 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15086 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15088 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
15089 prev_device_refcount
= get_refcount((IUnknown
*)device
);
15091 memset(&vb_desc
, 0, sizeof(vb_desc
));
15092 vb_desc
.dwSize
= sizeof(vb_desc
);
15093 vb_desc
.dwFVF
= D3DFVF_XYZ
;
15094 vb_desc
.dwNumVertices
= 4;
15095 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
15096 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
15098 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
15099 cur_device_refcount
= get_refcount((IUnknown
*)device
);
15100 ok(cur_d3d_refcount
> prev_d3d_refcount
, "D3D object refcount didn't change from %u.\n", prev_d3d_refcount
);
15101 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %u to %u.\n",
15102 prev_device_refcount
, cur_device_refcount
);
15104 prev_d3d_refcount
= cur_d3d_refcount
;
15105 hr
= IDirect3DVertexBuffer7_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
15106 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer7, hr %#x.\n", hr
);
15107 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
15108 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %u to %u.\n",
15109 prev_d3d_refcount
, cur_d3d_refcount
);
15110 IDirect3DVertexBuffer7_Release(vb7
);
15112 hr
= IDirect3DVertexBuffer7_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
15113 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer returned unexpected hr %#x.\n", hr
);
15115 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
15116 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#x.\n", hr
);
15117 ok((IUnknown
*)vb
== unk
,
15118 "IDirect3DVertexBuffer7 and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
15119 IUnknown_Release(unk
);
15121 refcount
= IDirect3DVertexBuffer7_Release(vb
);
15122 ok(!refcount
, "Vertex buffer has %u references left.\n", refcount
);
15124 IDirect3D7_Release(d3d
);
15125 refcount
= IDirect3DDevice7_Release(device
);
15126 ok(!refcount
, "Device has %u references left.\n", refcount
);
15127 DestroyWindow(window
);
15130 static void test_compute_sphere_visibility(void)
15132 static D3DVALUE clip_plane
[4] = {1.0f
, 0.0f
, 0.0f
, 0.5f
};
15133 static D3DMATRIX proj_1
=
15135 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
15136 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
15137 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
15138 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
15140 static D3DMATRIX proj_2
=
15142 10.0f
, 0.0f
, 0.0f
, 0.0f
,
15143 0.0f
, 10.0f
, 0.0f
, 0.0f
,
15144 0.0f
, 0.0f
, 10.0f
, 0.0f
,
15145 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15147 static D3DMATRIX view_1
=
15149 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
15150 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
15151 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
15152 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
15154 static D3DMATRIX identity
=
15156 1.0f
, 0.0f
, 0.0f
, 0.0f
,
15157 0.0f
, 1.0f
, 0.0f
, 0.0f
,
15158 0.0f
, 0.0f
, 1.0f
, 0.0f
,
15159 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15163 D3DMATRIX
*view
, *proj
;
15164 unsigned int sphere_count
;
15165 D3DVECTOR center
[3];
15166 D3DVALUE radius
[3];
15167 DWORD enable_planes
;
15168 const DWORD expected
[3];
15172 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, 0, {0x3f}},
15173 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
15174 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
15175 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
15176 {4.354097f
, 12.500704f
, 17.251318f
}, 0, {0x103d, 0x3f, 0x3f}},
15177 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, 0, {0}},
15178 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, 0, {0}},
15179 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, 0, {0}},
15180 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, 0, {0x9}}, /* 5 */
15181 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x103d}},
15182 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x203e}},
15183 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x803b}},
15184 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x4037}},
15185 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, 0, {0x1001f}}, /* 10 */
15186 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, 0, {0x2002f}},
15187 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {5.0f
}, 1, {0x7f}},
15188 {&identity
, &identity
, 1, {{{-0.5f
}, {0.0f
}, {0.0f
}}}, {5.0f
}, 1, {0x7f}},
15189 {&identity
, &identity
, 1, {{{-0.5f
}, {0.0f
}, {0.0f
}}}, {1.0f
}, 1, {0x51}},
15190 {&identity
, &identity
, 1, {{{-2.5f
}, {0.0f
}, {0.0f
}}}, {1.0f
}, 1, {0x41051}}, /* 15 */
15192 IDirect3DDevice7
*device
;
15199 window
= create_window();
15200 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15202 skip("Failed to create a 3D device, skipping test.\n");
15203 DestroyWindow(window
);
15207 hr
= IDirect3DDevice7_SetClipPlane(device
, 0, clip_plane
);
15208 ok(SUCCEEDED(hr
), "Failed to set user clip plane, hr %#x.\n", hr
);
15210 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
15212 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15214 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
15215 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
15217 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
,
15218 tests
[i
].enable_planes
);
15219 ok(SUCCEEDED(hr
), "Failed to enable / disable user clip planes, hr %#x.\n", hr
);
15221 hr
= IDirect3DDevice7_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
15222 tests
[i
].sphere_count
, 0, result
);
15223 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15225 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
15226 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#x, got %#x.\n",
15227 i
, j
, tests
[i
].expected
[j
], result
[j
]);
15230 refcount
= IDirect3DDevice7_Release(device
);
15231 ok(!refcount
, "Device has %u references left.\n", refcount
);
15232 DestroyWindow(window
);
15235 static void test_clip_planes_limits(void)
15237 IDirect3DDevice7
*device
;
15238 D3DDEVICEDESC7 caps
;
15246 window
= create_window();
15247 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15249 skip("Failed to create 3D device.\n");
15250 DestroyWindow(window
);
15254 memset(&caps
, 0, sizeof(caps
));
15255 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
15256 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
15258 trace("Max user clip planes: %u.\n", caps
.wMaxUserClipPlanes
);
15260 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15262 memset(plane
, 0xff, sizeof(plane
));
15263 hr
= IDirect3DDevice7_GetClipPlane(device
, i
, plane
);
15264 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#x.\n", i
, hr
);
15265 ok(!plane
[0] && !plane
[1] && !plane
[2] && !plane
[3],
15266 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
15267 i
, plane
[0], plane
[1], plane
[2], plane
[3]);
15273 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15276 hr
= IDirect3DDevice7_SetClipPlane(device
, i
, plane
);
15277 ok(hr
== D3D_OK
, "Failed to set clip plane %u, hr %#x.\n", i
, hr
);
15279 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15281 memset(plane
, 0xff, sizeof(plane
));
15282 hr
= IDirect3DDevice7_GetClipPlane(device
, i
, plane
);
15283 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#x.\n", i
, hr
);
15284 ok(plane
[0] == 2.0f
&& plane
[1] == 8.0f
&& plane
[2] == 5.0f
&& plane
[3] == i
,
15285 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
15286 i
, plane
[0], plane
[1], plane
[2], plane
[3]);
15289 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, 0xffffffff);
15290 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15291 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, &state
);
15292 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
15293 ok(state
== 0xffffffff, "Got unexpected state %#x.\n", state
);
15294 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, 0x80000000);
15295 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15296 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, &state
);
15297 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
15298 ok(state
== 0x80000000, "Got unexpected state %#x.\n", state
);
15300 refcount
= IDirect3DDevice7_Release(device
);
15301 ok(!refcount
, "Device has %u references left.\n", refcount
);
15302 DestroyWindow(window
);
15305 static void test_texture_stages_limits(void)
15307 IDirectDrawSurface7
*texture
;
15308 DDSURFACEDESC2 surface_desc
;
15309 IDirect3DDevice7
*device
;
15310 IDirectDraw7
*ddraw
;
15317 window
= create_window();
15318 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15320 skip("Failed to create 3D device.\n");
15321 DestroyWindow(window
);
15324 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15325 ok(SUCCEEDED(hr
), "Failed to get Direct3D interface, hr %#x.\n", hr
);
15326 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15327 ok(SUCCEEDED(hr
), "Failed to get DirectDraw interface, hr %#x.\n", hr
);
15328 IDirect3D7_Release(d3d
);
15330 memset(&surface_desc
, 0, sizeof(surface_desc
));
15331 surface_desc
.dwSize
= sizeof(surface_desc
);
15332 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15333 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
15334 surface_desc
.dwWidth
= 16;
15335 surface_desc
.dwHeight
= 16;
15336 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
15337 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
15339 for (i
= 0; i
< 8; ++i
)
15341 hr
= IDirect3DDevice7_SetTexture(device
, i
, texture
);
15342 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
15343 hr
= IDirect3DDevice7_SetTexture(device
, i
, NULL
);
15344 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
15345 hr
= IDirect3DDevice7_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
15346 ok(hr
== D3D_OK
, "Failed to set texture stage state %u, hr %#x.\n", i
, hr
);
15349 IDirectDrawSurface7_Release(texture
);
15350 IDirectDraw7_Release(ddraw
);
15351 refcount
= IDirect3DDevice7_Release(device
);
15352 ok(!refcount
, "Device has %u references left.\n", refcount
);
15353 DestroyWindow(window
);
15356 static void test_set_render_state(void)
15358 IDirect3DDevice7
*device
;
15364 window
= create_window();
15365 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15367 skip("Failed to create 3D device.\n");
15368 DestroyWindow(window
);
15372 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
15373 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15374 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
15375 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15377 /* States deprecated in D3D7 */
15378 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
15379 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15380 state
= 0xdeadbeef;
15381 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
15382 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15383 ok(state
== 0xdeadbeef, "Got unexpected render state %#x.\n", state
);
15384 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
15385 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15386 state
= 0xdeadbeef;
15387 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
15388 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15389 ok(state
== 0xdeadbeef, "Got unexpected render state %#x.\n", state
);
15391 refcount
= IDirect3DDevice7_Release(device
);
15392 ok(!refcount
, "Device has %u references left.\n", refcount
);
15393 DestroyWindow(window
);
15396 static void test_map_synchronisation(void)
15398 LARGE_INTEGER frequency
, diff
, ts
[3];
15399 IDirect3DVertexBuffer7
*buffer
;
15400 unsigned int i
, j
, tri_count
;
15401 D3DVERTEXBUFFERDESC vb_desc
;
15402 IDirect3DDevice7
*device
;
15403 BOOL unsynchronised
, ret
;
15404 IDirectDrawSurface7
*rt
;
15405 IDirectDraw7
*ddraw
;
15412 static const struct
15414 unsigned int flags
;
15415 BOOL unsynchronised
;
15420 {DDLOCK_NOOVERWRITE
, TRUE
},
15421 {DDLOCK_DISCARDCONTENTS
, FALSE
},
15422 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, TRUE
},
15425 static const struct quad
15429 struct vec3 position
;
15436 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
15437 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
15438 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
15439 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
15445 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
15446 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
15447 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
15448 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
15451 struct quad
*quads
;
15453 window
= create_window();
15454 ok(!!window
, "Failed to create a window.\n");
15456 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15458 skip("Failed to create a D3D device, skipping tests.\n");
15459 DestroyWindow(window
);
15463 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15464 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15465 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15466 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15467 /* Maps are always synchronised on WARP. */
15468 if (ddraw_is_warp(ddraw
))
15470 skip("Running on WARP, skipping test.\n");
15474 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15475 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15477 tri_count
= 0x1000;
15479 ret
= QueryPerformanceFrequency(&frequency
);
15480 ok(ret
, "Failed to get performance counter frequency.\n");
15482 vb_desc
.dwSize
= sizeof(vb_desc
);
15483 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
15484 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
15485 vb_desc
.dwNumVertices
= tri_count
+ 2;
15486 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0);
15487 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
15488 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
15489 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15490 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
15494 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15495 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15497 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15498 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15500 /* Initial draw to initialise states, compile shaders, etc. */
15501 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15502 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15503 hr
= IDirect3DDevice7_BeginScene(device
);
15504 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15505 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15506 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15507 hr
= IDirect3DDevice7_EndScene(device
);
15508 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15509 /* Read the result to ensure the GPU has finished drawing. */
15510 colour
= get_surface_color(rt
, 320, 240);
15512 /* Time drawing tri_count triangles. */
15513 ret
= QueryPerformanceCounter(&ts
[0]);
15514 ok(ret
, "Failed to read performance counter.\n");
15515 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15516 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15517 hr
= IDirect3DDevice7_BeginScene(device
);
15518 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15519 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15520 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15521 hr
= IDirect3DDevice7_EndScene(device
);
15522 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15523 colour
= get_surface_color(rt
, 320, 240);
15524 /* Time drawing a single triangle. */
15525 ret
= QueryPerformanceCounter(&ts
[1]);
15526 ok(ret
, "Failed to read performance counter.\n");
15527 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15528 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15529 hr
= IDirect3DDevice7_BeginScene(device
);
15530 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15531 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
15532 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15533 hr
= IDirect3DDevice7_EndScene(device
);
15534 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15535 colour
= get_surface_color(rt
, 320, 240);
15536 ret
= QueryPerformanceCounter(&ts
[2]);
15537 ok(ret
, "Failed to read performance counter.\n");
15539 IDirect3DVertexBuffer7_Release(buffer
);
15541 /* Estimate the number of triangles we can draw in 100ms. */
15542 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
15543 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
15544 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
15545 vb_desc
.dwNumVertices
= tri_count
+ 2;
15547 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15549 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0);
15550 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
15551 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
15552 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15553 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
15557 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15558 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15560 /* Start a draw operation. */
15561 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15562 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15563 hr
= IDirect3DDevice7_BeginScene(device
);
15564 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15565 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15566 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15567 hr
= IDirect3DDevice7_EndScene(device
);
15568 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15570 /* Map the last quad while the draw is in progress. */
15571 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
15572 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15573 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
15574 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15575 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15577 colour
= get_surface_color(rt
, 320, 240);
15578 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
15579 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
15580 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
15582 IDirect3DVertexBuffer7_Release(buffer
);
15585 IDirectDrawSurface7_Release(rt
);
15587 IDirectDraw7_Release(ddraw
);
15588 IDirect3D7_Release(d3d
);
15589 refcount
= IDirect3DDevice7_Release(device
);
15590 ok(!refcount
, "Device has %u references left.\n", refcount
);
15591 DestroyWindow(window
);
15594 static void test_depth_readback(void)
15596 DWORD depth
, expected_depth
, max_diff
, raw_value
, passed_fmts
= 0;
15597 IDirectDrawSurface7
*rt
, *ds
;
15598 DDSURFACEDESC2 surface_desc
;
15599 IDirect3DDevice7
*device
;
15600 unsigned int i
, x
, y
;
15601 IDirectDraw7
*ddraw
;
15607 BOOL all_zero
, all_one
, all_pass
;
15611 struct vec3 position
;
15616 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
15617 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
15618 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
15619 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
15622 static const struct
15624 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
15629 {16, 0, 0x0000ffff, 0x00000000},
15630 {24, 0, 0x00ffffff, 0x00000000},
15631 {32, 0, 0x00ffffff, 0x00000000},
15632 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
15633 {32, 0, 0xffffffff, 0x00000000},
15636 window
= create_window();
15637 ok(!!window
, "Failed to create a window.\n");
15639 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15641 skip("Failed to create a D3D device, skipping tests.\n");
15642 DestroyWindow(window
);
15646 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15647 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15648 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15649 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15651 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15652 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15654 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15655 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15657 ds
= get_depth_stencil(device
);
15658 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
15659 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15660 IDirectDrawSurface7_Release(ds
);
15662 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15664 memset(&surface_desc
, 0, sizeof(surface_desc
));
15665 surface_desc
.dwSize
= sizeof(surface_desc
);
15666 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
15667 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
15668 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
15669 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
15670 if (tests
[i
].s_depth
)
15671 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
15672 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
15673 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
15674 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
15675 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
15676 surface_desc
.dwWidth
= 640;
15677 surface_desc
.dwHeight
= 480;
15678 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
15681 skip("Format %u not supported, skipping test.\n", i
);
15685 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
15686 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
15687 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
15688 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
15690 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
15691 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15692 hr
= IDirect3DDevice7_BeginScene(device
);
15693 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15694 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
15695 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15696 hr
= IDirect3DDevice7_EndScene(device
);
15697 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15699 all_zero
= all_one
= all_pass
= TRUE
;
15700 for (y
= 60; y
< 480; y
+= 120)
15702 for (x
= 80; x
< 640; x
+= 160)
15704 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
15705 memset(&surface_desc
, 0, sizeof(surface_desc
));
15706 surface_desc
.dwSize
= sizeof(surface_desc
);
15707 hr
= IDirectDrawSurface7_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
, NULL
);
15708 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
15710 raw_value
= *((DWORD
*)surface_desc
.lpSurface
);
15713 if (raw_value
!= 0x00ffffff)
15716 depth
= raw_value
& tests
[i
].z_mask
;
15717 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
15718 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
15719 /* This test is very reliably on older AMD drivers, but fails in a number of interesting
15720 * ways on Nvidia GPUs:
15722 * Geforce 7 GPUs work only with D16. D24 and D24S8 return 0, D24X8 broken data.
15724 * Geforce 9 GPUs return broken data for D16 that resembles the expected data in
15725 * the lower 8 bits and has 0xff in the upper 8 bits. D24X8 works, D24 and D24S8 return
15728 * Geforce GTX 650 has working D16 and D24, but D24S8 returns 0.
15730 * Arx Fatalis is broken on the Geforce 9 in the same way it was broken in Wine (bug 43654).
15731 * The !tests[i].s_depth is supposed to rule out D16 on GF9 and D24X8 on GF7.
15733 * On new-ish AMD GPUs (Radeon Polaris at least) returns weird data for D24 and D24X8. D16
15736 * Some of the tested places pass on some GPUs on Wine by accident. */
15737 todo_wine_if(tests
[i
].todo
&& !compare_uint(expected_depth
, depth
, max_diff
))
15738 ok(compare_uint(expected_depth
, depth
, max_diff
)
15739 || (ddraw_is_nvidia(ddraw
) && (all_zero
|| all_one
|| !tests
[i
].s_depth
))
15740 || (ddraw_is_amd(ddraw
) && !tests
[i
].s_depth
&& tests
[i
].z_mask
== 0x00ffffff),
15741 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
15742 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
15743 if (!compare_uint(expected_depth
, depth
, max_diff
))
15746 hr
= IDirectDrawSurface7_Unlock(ds
, &r
);
15747 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
15753 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
15754 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15755 IDirectDrawSurface7_Release(ds
);
15758 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
15760 IDirectDrawSurface7_Release(rt
);
15761 IDirectDraw7_Release(ddraw
);
15762 IDirect3D7_Release(d3d
);
15763 refcount
= IDirect3DDevice7_Release(device
);
15764 ok(!refcount
, "Device has %u references left.\n", refcount
);
15765 DestroyWindow(window
);
15768 static void test_clear(void)
15770 IDirect3DDevice7
*device
;
15771 IDirectDrawSurface7
*rt
;
15772 D3DVIEWPORT7 vp
, old_vp
;
15773 IDirectDraw7
*ddraw
;
15774 D3DRECT rect_negneg
;
15782 window
= create_window();
15783 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15785 skip("Failed to create 3D device.\n");
15786 DestroyWindow(window
);
15790 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15791 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15792 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15793 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15795 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15796 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15798 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15799 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15801 /* Positive x, negative y. */
15802 U1(rect
[0]).x1
= 0;
15803 U2(rect
[0]).y1
= 480;
15804 U3(rect
[0]).x2
= 320;
15805 U4(rect
[0]).y2
= 240;
15807 /* Positive x, positive y. */
15808 U1(rect
[1]).x1
= 0;
15809 U2(rect
[1]).y1
= 0;
15810 U3(rect
[1]).x2
= 320;
15811 U4(rect
[1]).y2
= 240;
15813 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
15814 * refuse negative rectangles, but it will not clear them either. */
15815 hr
= IDirect3DDevice7_Clear(device
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
15816 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15818 color
= get_surface_color(rt
, 160, 360);
15819 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
15820 color
= get_surface_color(rt
, 160, 120);
15821 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
15822 color
= get_surface_color(rt
, 480, 360);
15823 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
15824 color
= get_surface_color(rt
, 480, 120);
15825 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
15827 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
15828 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15829 /* negative x, negative y.
15830 * Also ignored, except on WARP, which clears the entire screen. */
15831 U1(rect_negneg
).x1
= 640;
15832 U2(rect_negneg
).y1
= 240;
15833 U3(rect_negneg
).x2
= 320;
15834 U4(rect_negneg
).y2
= 0;
15835 hr
= IDirect3DDevice7_Clear(device
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15836 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15838 color
= get_surface_color(rt
, 160, 360);
15839 ok(compare_color(color
, 0x00ffffff, 0)
15840 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15841 "Got unexpected color 0x%08x.\n", color
);
15842 color
= get_surface_color(rt
, 160, 120);
15843 ok(compare_color(color
, 0x00ffffff, 0)
15844 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15845 "Got unexpected color 0x%08x.\n", color
);
15846 color
= get_surface_color(rt
, 480, 360);
15847 ok(compare_color(color
, 0x00ffffff, 0)
15848 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15849 "Got unexpected color 0x%08x.\n", color
);
15850 color
= get_surface_color(rt
, 480, 120);
15851 ok(compare_color(color
, 0x00ffffff, 0)
15852 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15853 "Got unexpected color 0x%08x.\n", color
);
15855 /* Test how the viewport affects clears. */
15856 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15857 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15858 hr
= IDirect3DDevice7_GetViewport(device
, &old_vp
);
15859 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#x.\n", hr
);
15867 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
15868 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15869 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15870 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15878 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
15879 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15881 U1(rect
[0]).x1
= 160;
15882 U2(rect
[0]).y1
= 120;
15883 U3(rect
[0]).x2
= 480;
15884 U4(rect
[0]).y2
= 360;
15885 hr
= IDirect3DDevice7_Clear(device
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15886 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15888 hr
= IDirect3DDevice7_SetViewport(device
, &old_vp
);
15889 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15891 color
= get_surface_color(rt
, 158, 118);
15892 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
15893 color
= get_surface_color(rt
, 162, 118);
15894 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
15895 color
= get_surface_color(rt
, 158, 122);
15896 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
15897 color
= get_surface_color(rt
, 162, 122);
15898 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
15900 color
= get_surface_color(rt
, 318, 238);
15901 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
15902 color
= get_surface_color(rt
, 322, 238);
15903 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
15904 color
= get_surface_color(rt
, 318, 242);
15905 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
15906 color
= get_surface_color(rt
, 322, 242);
15907 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
15909 color
= get_surface_color(rt
, 478, 358);
15910 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
15911 color
= get_surface_color(rt
, 482, 358);
15912 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
15913 color
= get_surface_color(rt
, 478, 362);
15914 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
15915 color
= get_surface_color(rt
, 482, 362);
15916 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
15918 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
15921 IDirectDrawSurface7_Release(rt
);
15922 IDirectDraw7_Release(ddraw
);
15923 IDirect3D7_Release(d3d
);
15924 refcount
= IDirect3DDevice7_Release(device
);
15925 ok(!refcount
, "Device has %u references left.\n", refcount
);
15926 DestroyWindow(window
);
15929 struct enum_surfaces_param
15931 IDirectDraw7
*ddraw
;
15932 DDSURFACEDESC2 modes
[20];
15933 unsigned int mode_count
;
15935 IDirectDrawSurface7
*surfaces
[8];
15936 unsigned int count
;
15939 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC2
*desc
, void *context
)
15941 struct enum_surfaces_param
*param
= context
;
15942 IDirectDrawSurface7
*surface
;
15944 if (SUCCEEDED(IDirectDraw7_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
15946 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
15947 param
->modes
[param
->mode_count
] = *desc
;
15948 ++param
->mode_count
;
15949 IDirectDrawSurface7_Release(surface
);
15952 return DDENUMRET_OK
;
15955 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
15957 struct enum_surfaces_param
*param
= context
;
15958 BOOL found
= FALSE
;
15961 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
15963 if (param
->surfaces
[i
] == surface
)
15970 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
15971 IDirectDrawSurface7_Release(surface
);
15974 return DDENUMRET_OK
;
15977 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
15979 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
15980 struct enum_surfaces_param
*param
= context
;
15982 ok(!surface
, "Unexpected surface %p.\n", surface
);
15983 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#x.\n", desc
->dwFlags
);
15984 if (param
->count
< ARRAY_SIZE(param
->modes
))
15986 const DDSURFACEDESC2
*expect
= ¶m
->modes
[param
->count
];
15987 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %u, got %u.\n", expect
->dwWidth
, desc
->dwWidth
);
15988 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %u, got %u.\n", expect
->dwHeight
, desc
->dwHeight
);
15989 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
15990 "Pixel formats didn't match.\n");
15995 return DDENUMRET_OK
;
15998 static void test_enum_surfaces(void)
16000 struct enum_surfaces_param param
= {0};
16001 DDPIXELFORMAT current_format
;
16002 DDSURFACEDESC2 desc
;
16003 IDirectDraw7
*ddraw
;
16006 ddraw
= create_ddraw();
16007 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16008 param
.ddraw
= ddraw
;
16010 memset(&desc
, 0, sizeof(desc
));
16011 desc
.dwSize
= sizeof(desc
);
16012 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &desc
);
16013 ok(hr
== DD_OK
, "Failed to get display mode, hr %#x.\n", hr
);
16014 current_format
= U4(desc
).ddpfPixelFormat
;
16016 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
16017 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#x.\n", hr
);
16019 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
, NULL
, NULL
, NULL
);
16020 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16022 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
16023 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16025 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
16026 NULL
, NULL
, enum_surfaces_cb
);
16027 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16029 memset(&desc
, 0, sizeof(desc
));
16030 desc
.dwSize
= sizeof(desc
);
16031 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
16032 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
16033 U2(desc
).dwMipMapCount
= 3;
16035 desc
.dwHeight
= 32;
16036 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
)))
16038 win_skip("Failed to create a texture, skipping tests.\n");
16039 IDirectDraw7_Release(ddraw
);
16043 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
16044 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#x.\n", hr
);
16045 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
16046 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#x.\n", hr
);
16047 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
16048 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
16049 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
16052 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16053 &desc
, ¶m
, enum_surfaces_cb
);
16054 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16055 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16058 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16059 NULL
, ¶m
, enum_surfaces_cb
);
16060 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16061 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16063 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
16065 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16066 &desc
, ¶m
, enum_surfaces_cb
);
16067 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16068 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16071 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
16072 &desc
, ¶m
, enum_surfaces_cb
);
16073 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16074 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16078 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16079 &desc
, ¶m
, enum_surfaces_cb
);
16080 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16081 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16085 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
16086 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16087 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16089 IDirectDrawSurface7_Release(param
.surfaces
[2]);
16090 IDirectDrawSurface7_Release(param
.surfaces
[1]);
16091 IDirectDrawSurface7_Release(param
.surfaces
[0]);
16094 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16095 NULL
, ¶m
, enum_surfaces_cb
);
16096 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16097 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16099 memset(&desc
, 0, sizeof(desc
));
16100 desc
.dwSize
= sizeof(desc
);
16101 desc
.dwFlags
= DDSD_CAPS
;
16102 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16104 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
16105 &desc
, ¶m
, enum_surfaces_create_cb
);
16106 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16108 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
16109 &desc
, ¶m
, enum_surfaces_create_cb
);
16110 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16112 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
16113 &desc
, ¶m
, enum_surfaces_create_cb
);
16114 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16116 /* When not passed width and height, the callback is called with every
16117 * available display resolution. */
16119 param
.mode_count
= 0;
16120 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
16121 U4(desc
).ddpfPixelFormat
= current_format
;
16122 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
16123 ok(hr
== DD_OK
, "Failed to build mode list, hr %#x.\n", hr
);
16126 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
16127 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16128 &desc
, ¶m
, enum_surfaces_create_cb
);
16129 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16130 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
16132 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
16133 desc
.dwWidth
= desc
.dwHeight
= 32;
16135 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
16138 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16139 &desc
, ¶m
, enum_surfaces_create_cb
);
16140 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16141 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16143 hr
= IDirectDraw7_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
16144 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
16146 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16147 &desc
, ¶m
, enum_surfaces_create_cb
);
16148 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16149 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16150 IDirectDrawSurface7_Release(param
.surfaces
[0]);
16152 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
16153 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
16154 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
16155 U4(desc
).ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
16158 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16159 &desc
, ¶m
, enum_surfaces_create_cb
);
16160 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16161 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16163 IDirectDraw7_Release(ddraw
);
16166 static void test_viewport(void)
16172 RECT expected_rect
;
16173 const char *message
;
16177 {{ 0, 0, 640, 480}, 0.001f
, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
16178 {{ 0, 0, 320, 240}, 0.001f
, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
16179 /* Don't run this right after the other 640x480 test, it breaks r500. */
16180 {{ 0, 0, 640, 480, 0.5f
, 0.0f
}, 0.501f
,
16181 {0, 120, 479, 359}, "Viewport (0, 0, 0.5) - (640, 480, 0.0)"},
16182 {{ 0, 0, 1280, 960}, 0.001f
, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
16183 {{ 0, 0, 2000, 1600}, 0.001f
, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
16184 {{100, 100, 640, 480}, 0.001f
, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
16185 {{ 0, 0, 8192, 8192}, 0.001f
, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
16187 static struct vec3 quad
[] =
16189 {-1.5f
, -0.5f
, 1.0f
},
16190 {-1.5f
, 0.5f
, 1.0f
},
16191 { 0.5f
, -0.5f
, 1.0f
},
16192 { 0.5f
, 0.5f
, 1.0f
},
16194 static const struct vec2 rt_sizes
[] =
16196 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
16198 IDirectDrawSurface7
*rt
, *ds
;
16199 DDSURFACEDESC2 surface_desc
;
16200 const float z_eps
= 0.0001;
16201 IDirect3DDevice7
*device
;
16202 IDirectDraw7
*ddraw
;
16203 DDPIXELFORMAT z_fmt
;
16210 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16211 0, 0, 640, 480, 0, 0, 0, 0);
16212 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16214 skip("Failed to create a 3D device, skipping test.\n");
16215 DestroyWindow(window
);
16219 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
16220 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16221 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
16222 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16223 IDirect3D7_Release(d3d
);
16225 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16226 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16228 /* Well, by default the vertices without color info should be white, and without any texture
16229 * ops this should just show up in the output, but the r200 driver begs to differ and draws a
16231 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
16232 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16233 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
16234 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16235 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00ffffff);
16236 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16238 hr
= IDirect3DDevice7_SetViewport(device
, NULL
);
16239 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
16241 ds
= get_depth_stencil(device
);
16242 memset(&surface_desc
, 0, sizeof(surface_desc
));
16243 surface_desc
.dwSize
= sizeof(surface_desc
);
16244 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds
, &surface_desc
);
16245 z_fmt
= U4(surface_desc
).ddpfPixelFormat
;
16247 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
16251 memset(&surface_desc
, 0, sizeof(surface_desc
));
16252 surface_desc
.dwSize
= sizeof(surface_desc
);
16253 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
16254 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
16255 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
16256 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
16257 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
16258 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16260 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
16261 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16262 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
16263 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
16264 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16265 hr
= IDirectDrawSurface7_AddAttachedSurface(rt
, ds
);
16266 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16268 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
16269 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16273 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
16274 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16277 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
16279 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000,
16280 tests
[j
].expected_z
- z_eps
, 0);
16281 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16282 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_GREATER
);
16283 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16285 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, !i
);
16286 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16288 hr
= IDirect3DDevice7_SetViewport(device
, &tests
[j
].vp
);
16289 if (tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
16290 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
)
16292 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16297 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16300 hr
= IDirect3DDevice7_BeginScene(device
);
16301 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16302 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
16303 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16304 hr
= IDirect3DDevice7_EndScene(device
);
16305 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16307 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
16311 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000,
16312 tests
[j
].expected_z
+ z_eps
, 0);
16313 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16314 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESS
);
16315 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16317 hr
= IDirect3DDevice7_BeginScene(device
);
16318 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16319 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
16320 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16321 hr
= IDirect3DDevice7_EndScene(device
);
16322 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16324 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
16328 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
16329 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16330 IDirectDrawSurface7_Release(ds
);
16331 IDirectDrawSurface7_Release(rt
);
16334 refcount
= IDirect3DDevice7_Release(device
);
16335 ok(!refcount
, "Device has %u references left.\n", refcount
);
16336 IDirectDraw7_Release(ddraw
);
16337 DestroyWindow(window
);
16340 static unsigned int validate_loaded_surface(IDirectDrawSurface7
*surface
, unsigned int face
,
16341 unsigned int level
, const RECT
*src_rect
, const POINT
*dst_point
)
16343 DDSURFACEDESC2 surface_desc
;
16344 unsigned int diff
, x
, y
;
16347 memset(&surface_desc
, 0, sizeof(surface_desc
));
16348 surface_desc
.dwSize
= sizeof(surface_desc
);
16349 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
16350 ok(SUCCEEDED(hr
), "Failed to map surface, hr %#x.\n", hr
);
16352 for (y
= 0, diff
= 0; y
< surface_desc
.dwHeight
; ++y
)
16354 DWORD
*texture_row
= (DWORD
*)((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
16356 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
16358 DWORD colour
= texture_row
[x
];
16359 DWORD r
= (colour
& 0xff0000) >> 16;
16360 DWORD g
= (colour
& 0xff00) >> 8;
16361 DWORD b
= (colour
& 0xff);
16363 if (x
< dst_point
->x
|| x
>= dst_point
->x
+ src_rect
->right
- src_rect
->left
16364 || y
< dst_point
->y
|| y
>= dst_point
->y
+ src_rect
->bottom
- src_rect
->top
)
16366 if (colour
& 0xffffff)
16371 if (r
!= ((face
<< 4) | level
)
16372 || g
!= x
+ src_rect
->left
- dst_point
->x
16373 || b
!= y
+ src_rect
->top
- dst_point
->y
)
16379 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
16380 ok(SUCCEEDED(hr
), "Failed to unmap surface, hr %#x.\n", hr
);
16385 static void test_device_load(void)
16387 IDirectDrawSurface7
*src_surface
, *dst_surface
, *surface
, *tmp
;
16388 DDSCAPS2 mip_caps
= {0, DDSCAPS2_MIPMAPSUBLEVEL
, 0, {0}};
16389 IDirectDrawPalette
*src_palette
, *dst_palette
, *palette
;
16390 unsigned int i
, j
, k
, l
, x
, y
;
16391 DDSURFACEDESC2 surface_desc
;
16392 IDirect3DDevice7
*device
;
16393 PALETTEENTRY table1
[256];
16394 D3DDEVICEDESC7 d3d_caps
;
16395 DDCOLORKEY colour_key
;
16396 IDirectDraw7
*ddraw
;
16404 #define TEX_MIP 0x01
16405 #define TEX_CUBE 0x02
16406 #define NULL_COORDS 0x04
16408 /* Creating partial cube maps (e.g. created with just
16409 * DDSCAPS2_CUBEMAP_POSITIVEX) BSODs some Windows machines. (Radeon X1600,
16410 * Windows XP, Catalyst 10.2 driver, 6.14.10.6925)
16412 * Passing non-toplevel surfaces to IDirect3DDevice7_Load() crashes on
16413 * native. (Windows XP / NVIDIA, Windows 98 / RGB software rasteriser) */
16414 static const struct
16416 unsigned int src_w
, src_h
, src_mip_count
;
16419 unsigned int dst_w
, dst_h
, dst_mip_count
;
16426 {128, 128, 0, { 0, 0, 0, 0}, TEX_MIP
, 128, 128, 0, { 0, 0}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16427 {128, 128, 0, { 0, 0, 100, 100}, TEX_MIP
, 128, 128, 0, {50, 50}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16428 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 0, {31, 31}, TEX_MIP
, D3D_OK
},
16429 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, NULL_COORDS
, D3D_OK
},
16430 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 256, 128, 0, { 0, 0}, NULL_COORDS
, DDERR_INVALIDPARAMS
},
16431 {256, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, NULL_COORDS
, DDERR_INVALIDPARAMS
},
16432 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
| TEX_CUBE
, 128, 128, 0, {10, 10}, TEX_MIP
| TEX_CUBE
, D3D_OK
},
16433 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, TEX_CUBE
| NULL_COORDS
, DDERR_INVALIDPARAMS
},
16434 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 4, {31, 31}, TEX_MIP
, D3D_OK
},
16435 {128, 128, 4, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 0, {31, 31}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16436 {128, 128, 0, {32, 32, 96, 96}, TEX_MIP
, 32, 32, 0, {32, 32}, 0, D3D_OK
},
16437 {128, 128, 0, { 0, 0, 64, 64}, TEX_MIP
, 32, 32, 4, { 0, 0}, TEX_MIP
, D3D_OK
},
16440 window
= create_window();
16441 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16443 skip("Failed to create a 3D device, skipping test.\n");
16444 DestroyWindow(window
);
16448 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
16449 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
16450 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
16451 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
16452 IDirect3D7_Release(d3d
);
16454 memset(&d3d_caps
, 0, sizeof(d3d_caps
));
16455 hr
= IDirect3DDevice7_GetCaps(device
, &d3d_caps
);
16456 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
16457 cube_support
= d3d_caps
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
;
16459 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16461 unsigned int src_count
, dst_count
;
16462 POINT dst_point
, dst_point_broken
;
16463 RECT src_rect
, src_rect_broken
;
16465 if ((tests
[i
].src_flags
| tests
[i
].dst_flags
) & TEX_CUBE
&& !cube_support
)
16467 skip("No cubemap support, skipping test %u.\n", i
);
16471 memset(&surface_desc
, 0, sizeof(surface_desc
));
16472 surface_desc
.dwSize
= sizeof(surface_desc
);
16473 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16474 if (tests
[i
].src_mip_count
)
16475 surface_desc
.dwFlags
|= DDSD_MIPMAPCOUNT
;
16476 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16477 if (tests
[i
].src_flags
& (TEX_MIP
| TEX_CUBE
))
16478 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
16479 if (tests
[i
].src_flags
& TEX_MIP
)
16480 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_MIPMAP
;
16481 if (tests
[i
].src_flags
& TEX_CUBE
)
16482 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
16483 surface_desc
.dwWidth
= tests
[i
].src_w
;
16484 surface_desc
.dwHeight
= tests
[i
].src_h
;
16485 U2(surface_desc
).dwMipMapCount
= tests
[i
].src_mip_count
;
16486 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16487 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
16488 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
16489 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
16490 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
16491 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
16492 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
16493 ok(SUCCEEDED(hr
), "Test %u: Failed to create source surface, hr %#x.\n", i
, hr
);
16495 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16496 if (tests
[i
].dst_mip_count
)
16497 surface_desc
.dwFlags
|= DDSD_MIPMAPCOUNT
;
16498 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16499 if (tests
[i
].dst_flags
& (TEX_MIP
| TEX_CUBE
))
16500 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
16501 if (tests
[i
].dst_flags
& TEX_MIP
)
16502 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_MIPMAP
;
16503 surface_desc
.ddsCaps
.dwCaps2
= 0;
16504 if (tests
[i
].dst_flags
& TEX_CUBE
)
16505 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
16506 surface_desc
.dwWidth
= tests
[i
].dst_w
;
16507 surface_desc
.dwHeight
= tests
[i
].dst_h
;
16508 U2(surface_desc
).dwMipMapCount
= tests
[i
].dst_mip_count
;
16509 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
16510 ok(SUCCEEDED(hr
), "Test %u: Failed to create destination surface, hr %#x.\n", i
, hr
);
16512 src_count
= dst_count
= 1;
16513 if (tests
[i
].src_flags
& TEX_MIP
)
16514 src_count
= tests
[i
].src_mip_count
? tests
[i
].src_mip_count
: 8;
16515 if (tests
[i
].dst_flags
& TEX_MIP
)
16516 dst_count
= tests
[i
].dst_mip_count
? tests
[i
].dst_mip_count
: 8;
16518 surface
= src_surface
;
16519 IDirectDrawSurface7_AddRef(surface
);
16522 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16524 /* Check the number of created mipmaps. */
16525 if (tests
[i
].src_flags
& TEX_MIP
)
16527 memset(&surface_desc
, 0, sizeof(surface_desc
));
16528 surface_desc
.dwSize
= sizeof(surface_desc
);
16529 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
16530 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface description, hr %#x.\n", i
, hr
);
16531 ok(U2(surface_desc
).dwMipMapCount
== src_count
,
16532 "Test %u: Got unexpected mip count %u, expected %u.\n",
16533 i
, U2(surface_desc
).dwMipMapCount
, src_count
);
16538 memset(&surface_desc
, 0, sizeof(surface_desc
));
16539 surface_desc
.dwSize
= sizeof(surface_desc
);
16540 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
16541 ok(SUCCEEDED(hr
), "Test %u: Failed to map surface, hr %#x.\n", i
, hr
);
16543 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
16545 DWORD
*texture_row
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
16547 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
16549 /* The face number is stored in the high 4 bits of the
16550 * red component, the mip-level in the low 4 bits. The
16551 * x-coordinate is stored in the green component, and
16552 * the y-coordinate in the blue component. */
16553 texture_row
[x
] = (j
<< 20) | (k
<< 16) | (x
<< 8) | y
;
16557 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
16558 ok(SUCCEEDED(hr
), "Test %u: Failed to unmap surface, hr %#x.\n", i
, hr
);
16560 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16561 IDirectDrawSurface7_Release(surface
);
16567 if (!(tests
[i
].src_flags
& TEX_CUBE
) || ++j
>= 6)
16570 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16571 hr
= IDirectDrawSurface7_GetAttachedSurface(src_surface
, &face_caps
, &surface
);
16572 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16575 surface
= dst_surface
;
16576 IDirectDrawSurface7_AddRef(surface
);
16579 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16581 /* Check the number of created mipmaps. */
16582 if (tests
[i
].dst_flags
& TEX_MIP
)
16584 memset(&surface_desc
, 0, sizeof(surface_desc
));
16585 surface_desc
.dwSize
= sizeof(surface_desc
);
16586 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
16587 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface description, hr %#x.\n", i
, hr
);
16588 ok(U2(surface_desc
).dwMipMapCount
== dst_count
,
16589 "Test %u: Got unexpected mip count %u, expected %u.\n",
16590 i
, U2(surface_desc
).dwMipMapCount
, dst_count
);
16595 memset(&fx
, 0, sizeof(fx
));
16596 fx
.dwSize
= sizeof(fx
);
16597 U5(fx
).dwFillColor
= 0x00000000;
16598 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
16599 ok(SUCCEEDED(hr
), "Test %u: Failed to clear surface, hr %#x.\n", i
, hr
);
16601 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16602 IDirectDrawSurface7_Release(surface
);
16608 if (!(tests
[i
].dst_flags
& TEX_CUBE
) || ++j
>= 6)
16611 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16612 hr
= IDirectDrawSurface7_GetAttachedSurface(dst_surface
, &face_caps
, &surface
);
16613 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16616 src_rect
= tests
[i
].src_rect
;
16617 dst_point
= tests
[i
].dst_point
;
16618 hr
= IDirect3DDevice7_Load(device
,
16619 dst_surface
, tests
[i
].dst_flags
& NULL_COORDS
? NULL
: &dst_point
,
16620 src_surface
, tests
[i
].src_flags
& NULL_COORDS
? NULL
: &src_rect
,
16621 tests
[i
].dst_flags
& TEX_CUBE
? DDSCAPS2_CUBEMAP_ALLFACES
: 0);
16622 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
16626 unsigned int level_offset
, level_offset_broken
;
16628 for (level_offset
= 0, k
= tests
[i
].src_w
; k
> tests
[i
].dst_w
; ++level_offset
, k
/= 2);
16629 level_offset_broken
= src_count
- dst_count
;
16631 surface
= dst_surface
;
16632 IDirectDrawSurface7_AddRef(surface
);
16635 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16637 if (tests
[i
].src_flags
& NULL_COORDS
)
16638 SetRect(&src_rect
, 0, 0, tests
[i
].src_w
, tests
[i
].src_h
);
16640 src_rect
= tests
[i
].src_rect
;
16642 if (tests
[i
].dst_flags
& NULL_COORDS
)
16643 dst_point
.x
= dst_point
.y
= 0;
16645 dst_point
= tests
[i
].dst_point
;
16647 for (k
= 0; k
< level_offset
; ++k
)
16652 src_rect
.left
/= 2;
16653 src_rect
.right
= (src_rect
.right
+ 1) / 2;
16654 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
16659 unsigned int diff
, diff2
, diff3
;
16661 diff
= validate_loaded_surface(surface
, j
, k
+ level_offset
, &src_rect
, &dst_point
);
16663 /* On some newer (XP+) versions of Windows, it appears the
16664 * source/destination coordinates are divided too often.
16665 * This works correctly on Windows 98 with the RGB
16666 * software rasteriser. */
16667 src_rect_broken
= src_rect
;
16668 dst_point_broken
= dst_point
;
16669 for (l
= 0; l
< level_offset
; ++l
)
16671 dst_point_broken
.x
/= 2;
16672 dst_point_broken
.y
/= 2;
16673 src_rect_broken
.top
/= 2;
16674 src_rect_broken
.left
/= 2;
16675 src_rect_broken
.right
= (src_rect_broken
.right
+ 1) / 2;
16676 src_rect_broken
.bottom
= (src_rect_broken
.bottom
+ 1) / 2;
16678 diff2
= validate_loaded_surface(surface
, j
, k
+ level_offset
,
16679 &src_rect_broken
, &dst_point_broken
);
16681 /* On Windows 8+ things are slightly worse still. Instead
16682 * of applying the correct level offset twice, like on
16683 * XP+, an incorrect offset is applied in addition to the
16684 * correct one. Additionally, on Windows 8+, this offset
16685 * also affects the selected source mip-level, as opposed
16686 * to Windows XP+ where it only affects the
16687 * source/destination coordinates. */
16688 src_rect_broken
= src_rect
;
16689 dst_point_broken
= dst_point
;
16690 for (l
= 0; l
< level_offset_broken
; ++l
)
16692 dst_point_broken
.x
/= 2;
16693 dst_point_broken
.y
/= 2;
16694 src_rect_broken
.top
/= 2;
16695 src_rect_broken
.left
/= 2;
16696 src_rect_broken
.right
= (src_rect_broken
.right
+ 1) / 2;
16697 src_rect_broken
.bottom
= (src_rect_broken
.bottom
+ 1) / 2;
16699 diff3
= validate_loaded_surface(surface
, j
, k
+ level_offset_broken
,
16700 &src_rect_broken
, &dst_point_broken
);
16702 ok(!diff
|| broken(!diff2
|| !diff3
), "Test %u, face %u, level %u: "
16703 "Unexpected destination texture level pixels; %u/%u/%u differences.\n",
16704 i
, j
, k
, diff
, diff2
, diff3
);
16706 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16707 IDirectDrawSurface7_Release(surface
);
16715 src_rect
.left
/= 2;
16716 src_rect
.right
= (src_rect
.right
+ 1) / 2;
16717 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
16720 if (!(tests
[i
].dst_flags
& TEX_CUBE
) || ++j
>= 6)
16723 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16724 hr
= IDirectDrawSurface7_GetAttachedSurface(dst_surface
, &face_caps
, &surface
);
16725 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16729 IDirectDrawSurface7_Release(dst_surface
);
16730 IDirectDrawSurface7_Release(src_surface
);
16736 memset(&surface_desc
, 0, sizeof(surface_desc
));
16737 surface_desc
.dwSize
= sizeof(surface_desc
);
16738 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16739 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
16740 surface_desc
.dwWidth
= 128;
16741 surface_desc
.dwHeight
= 128;
16742 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16743 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED8
;
16744 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
16745 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
16746 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
16747 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
16748 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
16749 hr
= IDirectDrawSurface7_GetAttachedSurface(src_surface
, &mip_caps
, &surface
);
16750 ok(SUCCEEDED(hr
), "Failed to get surface, hr %#x.\n", hr
);
16752 /* Test palette copying. */
16753 memset(table1
, 0, sizeof(table1
));
16754 table1
[0].peBlue
= 1;
16755 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table1
, &src_palette
, NULL
);
16756 ok(SUCCEEDED(hr
), "Failed to create source palette, hr %#x.\n", hr
);
16757 table1
[0].peBlue
= 3;
16758 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table1
, &dst_palette
, NULL
);
16759 ok(SUCCEEDED(hr
), "Failed to create destination palette, hr %#x.\n", hr
);
16761 hr
= IDirectDrawSurface7_SetPalette(src_surface
, src_palette
);
16762 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
16764 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16765 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16767 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette
);
16768 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
16769 hr
= IDirectDrawSurface7_GetPalette(dst_surface
, &palette
);
16770 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
16772 hr
= IDirectDrawSurface7_SetPalette(surface
, src_palette
);
16773 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
16774 hr
= IDirectDrawSurface7_SetPalette(dst_surface
, dst_palette
);
16775 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
16777 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16778 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16780 hr
= IDirectDrawSurface7_GetPalette(dst_surface
, &palette
);
16781 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
16782 ok(palette
== dst_palette
, "Got unexpected palette %p, expected %p.\n", palette
, dst_palette
);
16783 memset(table1
, 0, sizeof(table1
));
16784 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 0, 256, table1
);
16785 ok(SUCCEEDED(hr
), "Failed to retrieve palette entries, hr %#x.\n", hr
);
16786 ok(table1
[0].peBlue
== 1, "Got unexpected palette colour %#x.\n", (unsigned int)table1
[0].peBlue
);
16787 IDirectDrawPalette_Release(palette
);
16789 IDirectDrawPalette_Release(dst_palette
);
16790 IDirectDrawPalette_Release(src_palette
);
16792 /* Test colour-key copying. */
16793 colour_key
.dwColorSpaceLowValue
= 32;
16794 colour_key
.dwColorSpaceHighValue
= 64;
16795 hr
= IDirectDrawSurface7_SetColorKey(src_surface
, DDCKEY_SRCBLT
, &colour_key
);
16796 ok(SUCCEEDED(hr
), "Failed to set colour-key, hr %#x.\n", hr
);
16797 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &colour_key
);
16798 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
16800 hr
= IDirectDrawSurface7_GetColorKey(dst_surface
, DDCKEY_SRCBLT
, &colour_key
);
16801 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
16803 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16804 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16806 hr
= IDirectDrawSurface7_GetColorKey(dst_surface
, DDCKEY_SRCBLT
, &colour_key
);
16807 ok(SUCCEEDED(hr
), "Failed to get colour-key, hr %#x.\n", hr
);
16808 ok(colour_key
.dwColorSpaceLowValue
== 32, "Got unexpected value %u.\n", colour_key
.dwColorSpaceLowValue
);
16809 ok(colour_key
.dwColorSpaceHighValue
== 32, "Got unexpected value %u.\n", colour_key
.dwColorSpaceHighValue
);
16811 IDirectDrawSurface7_Release(surface
);
16812 IDirectDrawSurface7_Release(dst_surface
);
16813 IDirectDrawSurface7_Release(src_surface
);
16815 IDirectDraw7_Release(ddraw
);
16816 refcount
= IDirect3DDevice7_Release(device
);
16817 ok(!refcount
, "Device has %u references left.\n", refcount
);
16818 DestroyWindow(window
);
16821 static void test_color_vertex(void)
16823 IDirect3DDevice7
*device
;
16824 IDirectDrawSurface7
*rt
;
16825 D3DMATERIAL7 material
;
16834 struct vec3 position
;
16840 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16841 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16842 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16843 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16847 struct vec3 position
;
16852 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16853 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
16854 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16855 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
16859 struct vec3 position
;
16863 {{-1.0f
, -1.0f
, 0.0f
}},
16864 {{-1.0f
, 1.0f
, 0.0f
}},
16865 {{ 1.0f
, -1.0f
, 0.0f
}},
16866 {{ 1.0f
, 1.0f
, 0.0f
}},
16869 /* The idea here is to set up ambient light parameters in a way that the
16870 * ambient colour from the material is just passed through. The emissive
16871 * colour is just passed through anyway. The sum of ambient + emissive
16872 * should allow deduction of where the material colour came from. */
16873 static const struct
16875 DWORD fvf
, color_vertex
, ambient
, emissive
, result
;
16880 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, FALSE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0, quad_2c
},
16882 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ffff00, quad_2c
},
16883 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x0000ff80, quad_2c
},
16884 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040, quad_2c
},
16885 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR1
, 0x00ff0000, quad_2c
},
16886 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR2
, D3DMCS_COLOR2
, 0x0000ff00, quad_2c
},
16888 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0080, quad_1c
},
16889 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x000000c0, quad_1c
},
16890 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x00ff0080, quad_1c
},
16891 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0040, quad_1c
},
16892 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040, quad_1c
},
16893 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR2
, D3DMCS_MATERIAL
, 0x000000c0, quad_1c
},
16895 {0, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0, quad_0c
},
16898 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16899 0, 0, 640, 480, 0, 0, 0, 0);
16900 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16902 skip("Failed to create a 3D device, skipping test.\n");
16903 DestroyWindow(window
);
16906 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
16907 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
16909 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
16910 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16911 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_AMBIENT
, 0xffffffff);
16912 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16914 memset(&material
, 0, sizeof(material
));
16915 U3(U1(material
).ambient
).b
= 0.5f
;
16916 U3(U3(material
).emissive
).b
= 0.25f
;
16917 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
16918 ok(SUCCEEDED(hr
), "Failed to set material, hr %#x\n", hr
);
16920 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16922 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORVERTEX
, tests
[i
].color_vertex
);
16923 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16924 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_AMBIENTMATERIALSOURCE
, tests
[i
].ambient
);
16925 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16926 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
, tests
[i
].emissive
);
16927 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16928 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
16929 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16931 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
16932 ok(SUCCEEDED(hr
), "Failed to clear depth/stencil, hr %#x.\n", hr
);
16934 hr
= IDirect3DDevice7_BeginScene(device
);
16935 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
16936 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
16937 D3DFVF_XYZ
| tests
[i
].fvf
, tests
[i
].vtx
, 4, 0);
16938 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
16939 hr
= IDirect3DDevice7_EndScene(device
);
16940 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
16942 colour
= get_surface_color(rt
, 320, 240);
16943 ok(compare_color(colour
, tests
[i
].result
, 1),
16944 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
16945 tests
[i
].result
, i
, colour
);
16948 IDirectDrawSurface7_Release(rt
);
16949 refcount
= IDirect3DDevice7_Release(device
);
16950 ok(!refcount
, "Device has %u references left.\n", refcount
);
16951 DestroyWindow(window
);
16954 static IDirectDraw7
*killfocus_ddraw
;
16955 static IDirectDrawSurface7
*killfocus_surface
;
16957 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
16961 if (message
== WM_KILLFOCUS
)
16963 ref
= IDirectDrawSurface7_Release(killfocus_surface
);
16964 ok(!ref
, "Unexpected surface refcount %u.\n", ref
);
16965 ref
= IDirectDraw7_Release(killfocus_ddraw
);
16966 ok(!ref
, "Unexpected ddraw refcount %u.\n", ref
);
16967 killfocus_ddraw
= NULL
;
16970 return DefWindowProcA(window
, message
, wparam
, lparam
);
16973 static void test_killfocus(void)
16975 DDSURFACEDESC2 surface_desc
;
16978 WNDCLASSA wc
= {0};
16980 wc
.lpfnWndProc
= killfocus_proc
;
16981 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
16982 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
16984 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16985 0, 0, 640, 480, 0, 0, 0, 0);
16987 killfocus_ddraw
= create_ddraw();
16988 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
16990 hr
= IDirectDraw7_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
16991 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
16993 memset(&surface_desc
, 0, sizeof(surface_desc
));
16994 surface_desc
.dwSize
= sizeof(surface_desc
);
16995 surface_desc
.dwFlags
= DDSD_CAPS
;
16996 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
16997 hr
= IDirectDraw7_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
16998 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
17000 SetForegroundWindow(GetDesktopWindow());
17001 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
17003 DestroyWindow(window
);
17004 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
17007 static void test_sysmem_draw(void)
17009 IDirectDrawSurface7
*rt
, *texture
;
17010 DDSURFACEDESC2 surface_desc
;
17011 D3DVERTEXBUFFERDESC vb_desc
;
17012 IDirect3DVertexBuffer7
*vb
;
17013 IDirect3DDevice7
*device
;
17014 IDirectDraw7
*ddraw
;
17022 static const struct
17024 struct vec3 position
;
17029 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
17030 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
17031 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
17032 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
17034 static WORD indices
[] = {0, 1, 2, 3};
17036 window
= create_window();
17037 ok(!!window
, "Failed to create a window.\n");
17039 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17041 skip("Failed to create a 3D device, skipping test.\n");
17042 DestroyWindow(window
);
17046 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
17047 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17048 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
17049 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17050 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
17051 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17053 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17054 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17056 vb_desc
.dwSize
= sizeof(vb_desc
);
17057 vb_desc
.dwCaps
= D3DVBCAPS_SYSTEMMEMORY
;
17058 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
17059 vb_desc
.dwNumVertices
= 4;
17060 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
17061 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17063 hr
= IDirect3DVertexBuffer7_Lock(vb
, 0, (void **)&data
, NULL
);
17064 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17065 memcpy(data
, quad
, sizeof(quad
));
17066 hr
= IDirect3DVertexBuffer7_Unlock(vb
);
17067 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17069 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
17070 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17072 hr
= IDirect3DDevice7_BeginScene(device
);
17073 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17074 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
17075 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17076 hr
= IDirect3DDevice7_EndScene(device
);
17077 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17079 colour
= get_surface_color(rt
, 320, 240);
17080 ok(compare_color(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
17082 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
17083 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17085 hr
= IDirect3DDevice7_BeginScene(device
);
17086 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17087 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, indices
, 4, 0);
17088 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17089 hr
= IDirect3DDevice7_EndScene(device
);
17090 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17092 colour
= get_surface_color(rt
, 320, 240);
17093 ok(compare_color(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
17095 memset(&surface_desc
, 0, sizeof(surface_desc
));
17096 surface_desc
.dwSize
= sizeof(surface_desc
);
17097 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
17098 surface_desc
.dwHeight
= 2;
17099 surface_desc
.dwWidth
= 2;
17100 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
17101 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
17102 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
17103 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
17104 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
17105 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
17106 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
17107 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
17108 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
17109 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17110 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
17111 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17113 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
17114 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17116 hr
= IDirect3DDevice7_BeginScene(device
);
17117 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17118 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
17119 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17120 hr
= IDirect3DDevice7_EndScene(device
);
17121 ok(hr
== D3D_OK
|| hr
== D3DERR_SCENE_END_FAILED
, "Got unexpected hr %#x.\n", hr
);
17123 IDirectDrawSurface7_Release(texture
);
17124 IDirect3DVertexBuffer7_Release(vb
);
17125 IDirectDrawSurface7_Release(rt
);
17126 IDirectDraw7_Release(ddraw
);
17127 IDirect3D7_Release(d3d
);
17128 refcount
= IDirect3DDevice7_Release(device
);
17129 ok(!refcount
, "Device has %u references left.\n", refcount
);
17130 DestroyWindow(window
);
17133 static void test_gdi_surface(void)
17135 IDirectDrawSurface7
*primary
, *backbuffer
, *gdi_surface
;
17136 DDSCAPS2 caps
= {DDSCAPS_BACKBUFFER
, 0, 0, {0}};
17137 DDSURFACEDESC2 surface_desc
;
17138 IDirectDraw7
*ddraw
;
17143 window
= create_window();
17144 ddraw
= create_ddraw();
17145 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17146 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17147 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17149 /* Retrieving the GDI surface requires a primary surface to exist. */
17150 gdi_surface
= (void *)0xc0dec0de;
17151 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17152 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
17153 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
17155 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17156 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
17158 memset(&surface_desc
, 0, sizeof(surface_desc
));
17159 surface_desc
.dwSize
= sizeof(surface_desc
);
17160 surface_desc
.dwFlags
= DDSD_CAPS
;
17161 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17162 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17163 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17165 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17166 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17167 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17168 IDirectDrawSurface7_Release(gdi_surface
);
17170 /* Flipping to the GDI surface requires the primary surface to be
17172 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17173 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
17175 IDirectDrawSurface7_Release(primary
);
17177 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
17178 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17180 memset(&surface_desc
, 0, sizeof(surface_desc
));
17181 surface_desc
.dwSize
= sizeof(surface_desc
);
17182 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
17183 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
17184 U5(surface_desc
).dwBackBufferCount
= 1;
17185 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17186 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17187 hr
= IDirectDrawSurface7_GetAttachedSurface(primary
, &caps
, &backbuffer
);
17188 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17189 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
17191 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17192 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17193 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17194 IDirectDrawSurface7_Release(gdi_surface
);
17196 hr
= IDirectDrawSurface7_Flip(primary
, NULL
, DDFLIP_WAIT
);
17197 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17198 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17199 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17200 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
17201 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
17202 IDirectDrawSurface7_Release(gdi_surface
);
17204 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17205 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17207 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17208 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17209 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17210 IDirectDrawSurface7_Release(gdi_surface
);
17212 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17213 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17215 IDirectDrawSurface7_Release(backbuffer
);
17216 IDirectDrawSurface7_Release(primary
);
17218 refcount
= IDirectDraw7_Release(ddraw
);
17219 ok(!refcount
, "%u references left.\n", refcount
);
17220 DestroyWindow(window
);
17223 static void test_multiply_transform(void)
17225 IDirect3DDevice7
*device
;
17233 static const D3DTRANSFORMSTATETYPE tests
[] =
17235 D3DTRANSFORMSTATE_WORLD
,
17236 D3DTRANSFORMSTATE_VIEW
,
17237 D3DTRANSFORMSTATE_PROJECTION
,
17238 D3DTRANSFORMSTATE_WORLD1
,
17239 D3DTRANSFORMSTATE_WORLD2
,
17240 D3DTRANSFORMSTATE_WORLD3
,
17241 D3DTRANSFORMSTATE_TEXTURE0
,
17242 D3DTRANSFORMSTATE_TEXTURE1
,
17243 D3DTRANSFORMSTATE_TEXTURE2
,
17244 D3DTRANSFORMSTATE_TEXTURE3
,
17245 D3DTRANSFORMSTATE_TEXTURE4
,
17246 D3DTRANSFORMSTATE_TEXTURE5
,
17247 D3DTRANSFORMSTATE_TEXTURE6
,
17248 D3DTRANSFORMSTATE_TEXTURE7
,
17253 1.0f
, 0.0f
, 0.0f
, 0.0f
,
17254 0.0f
, 1.0f
, 0.0f
, 0.0f
,
17255 0.0f
, 0.0f
, 1.0f
, 0.0f
,
17256 0.0f
, 0.0f
, 0.0f
, 1.0f
,
17260 2.0f
, 0.0f
, 0.0f
, 0.0f
,
17261 0.0f
, 2.0f
, 0.0f
, 0.0f
,
17262 0.0f
, 0.0f
, 2.0f
, 0.0f
,
17263 0.0f
, 0.0f
, 0.0f
, 2.0f
,
17266 window
= create_window();
17267 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17269 skip("Failed to create 3D device.\n");
17270 DestroyWindow(window
);
17274 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
17276 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17277 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17278 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
17280 hr
= IDirect3DDevice7_MultiplyTransform(device
, tests
[i
], &mat2
);
17281 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17283 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17284 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17285 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
17287 /* MultiplyTransform() goes directly into the primary stateblock. */
17289 hr
= IDirect3DDevice7_SetTransform(device
, tests
[i
], &mat1
);
17290 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17292 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17293 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17295 hr
= IDirect3DDevice7_MultiplyTransform(device
, tests
[i
], &mat2
);
17296 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17298 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock
);
17299 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17301 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17302 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17303 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
17305 hr
= IDirect3DDevice7_CaptureStateBlock(device
, stateblock
);
17306 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17308 hr
= IDirect3DDevice7_SetTransform(device
, tests
[i
], &mat1
);
17309 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17311 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock
);
17312 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17314 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17315 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17316 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
17318 IDirect3DDevice7_DeleteStateBlock(device
, stateblock
);
17321 refcount
= IDirect3DDevice7_Release(device
);
17322 ok(!refcount
, "Device has %u references left.\n", refcount
);
17323 DestroyWindow(window
);
17326 static void test_alphatest(void)
17328 #define ALPHATEST_PASSED 0x0000ff00
17329 #define ALPHATEST_FAILED 0x00ff0000
17330 IDirect3DDevice7
*device
;
17331 IDirectDrawSurface7
*rt
;
17339 static const struct
17342 D3DCOLOR color_less
;
17343 D3DCOLOR color_equal
;
17344 D3DCOLOR color_greater
;
17348 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17349 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17350 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17351 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17352 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17353 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17354 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17355 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17359 struct vec3 position
;
17364 {{-1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17365 {{-1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17366 {{ 1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17367 {{ 1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17370 window
= create_window();
17371 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17373 skip("Failed to create a 3D device.\n");
17374 DestroyWindow(window
);
17377 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
17378 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17380 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
17381 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17382 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17383 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17384 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
17385 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17386 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
17387 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17389 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
17391 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
17392 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17394 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17395 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17396 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
17397 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17398 hr
= IDirect3DDevice7_BeginScene(device
);
17399 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17400 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17401 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17402 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17403 hr
= IDirect3DDevice7_EndScene(device
);
17404 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17405 color
= get_surface_color(rt
, 320, 240);
17406 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17407 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17408 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17410 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17411 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17412 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
17413 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17414 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
17415 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17416 ok(value
== 0xff70, "Got unexpected value %#x.\n", value
);
17417 hr
= IDirect3DDevice7_BeginScene(device
);
17418 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17419 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17420 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17421 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17422 hr
= IDirect3DDevice7_EndScene(device
);
17423 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17424 color
= get_surface_color(rt
, 320, 240);
17425 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17426 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17427 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17430 IDirectDrawSurface7_Release(rt
);
17431 refcount
= IDirect3DDevice7_Release(device
);
17432 ok(!refcount
, "Device has %u references left.\n", refcount
);
17433 DestroyWindow(window
);
17436 static void test_clipper_refcount(void)
17438 IDirectDrawSurface7
*surface
;
17439 IDirectDrawClipper
*clipper
, *clipper2
;
17440 DDSURFACEDESC2 surface_desc
;
17441 IDirectDraw7
*ddraw
;
17442 IDirectDraw
*ddraw1
;
17447 const IDirectDrawClipperVtbl
*orig_vtbl
;
17449 window
= create_window();
17450 ddraw
= create_ddraw();
17451 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17452 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17453 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17455 memset(&surface_desc
, 0, sizeof(surface_desc
));
17456 surface_desc
.dwSize
= sizeof(surface_desc
);
17457 surface_desc
.dwFlags
= DDSD_CAPS
;
17458 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17459 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17460 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17462 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17463 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17464 refcount
= get_refcount((IUnknown
*)clipper
);
17465 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17467 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
17469 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
17470 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17471 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
17472 clipper
->lpVtbl
, clipper2
->lpVtbl
);
17473 orig_vtbl
= clipper
->lpVtbl
;
17474 IDirectDrawClipper_Release(clipper2
);
17476 /* Surfaces hold a reference to clippers. No surprises there. */
17477 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17478 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17479 refcount
= get_refcount((IUnknown
*)clipper
);
17480 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17482 hr
= IDirectDrawSurface7_GetClipper(surface
, &clipper2
);
17483 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
17484 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17485 refcount
= IDirectDrawClipper_Release(clipper2
);
17486 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17488 hr
= IDirectDrawSurface7_SetClipper(surface
, NULL
);
17489 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17490 refcount
= get_refcount((IUnknown
*)clipper
);
17491 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17493 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17494 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17495 refcount
= get_refcount((IUnknown
*)clipper
);
17496 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17498 refcount
= IDirectDrawSurface7_Release(surface
);
17499 ok(!refcount
, "%u references left.\n", refcount
);
17500 refcount
= get_refcount((IUnknown
*)clipper
);
17501 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17503 /* SetClipper with an invalid pointer crashes. */
17505 /* Clipper methods work with a broken vtable, with the exception of Release. */
17506 clipper
->lpVtbl
= (void *)0xdeadbeef;
17507 refcount
= orig_vtbl
->AddRef(clipper
);
17508 todo_wine
ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17509 refcount
= orig_vtbl
->Release(clipper
);
17510 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
17512 clipper
->lpVtbl
= orig_vtbl
;
17513 refcount
= orig_vtbl
->Release(clipper
);
17514 todo_wine
ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17516 /* Fix the refcount difference because Wine did not increase the ref in the
17517 * AddRef call above. */
17520 refcount
= IDirectDrawClipper_Release(clipper
);
17521 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
17524 /* Steal the reference and see what happens - releasing the surface works fine.
17525 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
17526 * release it after the GetClipper call is likely to crash, and certain to crash
17527 * if we allocate and zero as much heap memory as we can get. */
17528 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17529 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17530 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17531 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17532 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17533 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17535 IDirectDrawClipper_Release(clipper
);
17536 IDirectDrawClipper_Release(clipper
);
17540 /* Disabled because it causes heap corruption (HeapValidate fails and random
17541 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
17542 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
17543 * is affected too. Some testbot machines have crashes directly in GetClipper
17544 * or proceed with a corrupted heap too.
17546 * The same Windows and driver versions run the test without heap corruption on
17547 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
17548 hr
= IDirectDrawSurface7_GetClipper(surface
, &clipper2
);
17549 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
17550 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17553 /* Show that invoking the Release method does not crash, but don't get the
17554 * vtable through the clipper pointer because it is no longer pointing to
17556 refcount
= orig_vtbl
->Release(clipper
);
17557 ok(!refcount
, "%u references left.\n", refcount
);
17559 refcount
= IDirectDrawSurface7_Release(surface
);
17560 ok(!refcount
, "%u references left.\n", refcount
);
17562 /* It looks like the protection against invalid thispointers is part of
17563 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
17564 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
17565 ok(!!clipper
, "failed to allocate memory\n");
17567 /* Assigning the vtable to our fake clipper does NOT make a difference on
17568 * native - there is a different member of the clipper implementation struct
17569 * that is used to determine if a clipper is valid. */
17570 clipper
->lpVtbl
= orig_vtbl
;
17572 refcount
= orig_vtbl
->AddRef(clipper
);
17573 todo_wine
ok(!refcount
, "Got refcount %u.\n", refcount
);
17574 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
17575 ok(!refcount
, "Got refcount %u.\n", refcount
);
17578 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
17579 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17580 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17583 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
17584 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17585 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17587 /* Nope, we can't initialize our fake clipper. */
17588 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
17589 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#x.\n", hr
);
17591 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
17592 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17594 IDirectDraw_Release(ddraw1
);
17596 HeapFree(GetProcessHeap(), 0, clipper
);
17598 refcount
= IDirectDraw7_Release(ddraw
);
17599 ok(!refcount
, "%u references left.\n", refcount
);
17600 DestroyWindow(window
);
17603 static void test_begin_end_state_block(void)
17605 DWORD stateblock
, stateblock2
;
17606 IDirect3DDevice7
*device
;
17612 window
= create_window();
17613 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17615 skip("Failed to create 3D device.\n");
17616 DestroyWindow(window
);
17620 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17621 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17623 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17624 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17626 stateblock
= 0xdeadbeef;
17627 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock
);
17628 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17629 ok(!!stateblock
&& stateblock
!= 0xdeadbeef, "Got unexpected stateblock %#x.\n", stateblock
);
17631 stateblock2
= 0xdeadbeef;
17632 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock2
);
17633 ok(hr
== D3DERR_NOTINBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17634 ok(stateblock2
== 0xdeadbeef, "Got unexpected stateblock %#x.\n", stateblock2
);
17636 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17637 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17638 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17640 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17641 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17643 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17644 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17646 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock
);
17647 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17649 hr
= IDirect3DDevice7_CaptureStateBlock(device
, stateblock
);
17650 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17652 hr
= IDirect3DDevice7_CreateStateBlock(device
, D3DSBT_ALL
, &stateblock2
);
17653 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17655 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17656 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17657 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17659 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock2
);
17660 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17662 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock2
);
17663 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17665 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17666 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17667 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17669 refcount
= IDirect3DDevice7_Release(device
);
17670 ok(!refcount
, "Device has %u references left.\n", refcount
);
17671 DestroyWindow(window
);
17674 static void test_caps(void)
17676 DWORD caps_never
, caps_always
, caps_hal
;
17677 DDCAPS hal_caps
, hel_caps
;
17678 IDirectDraw7
*ddraw
;
17682 caps_never
= DDSCAPS_RESERVED1
17684 | DDSCAPS_PRIMARYSURFACELEFT
17685 | DDSCAPS_SYSTEMMEMORY
17687 | DDSCAPS_WRITEONLY
17688 | DDSCAPS_LIVEVIDEO
17691 | DDSCAPS_RESERVED2
17694 | DDSCAPS_ALLOCONLOAD
17695 | DDSCAPS_VIDEOPORT
17696 | DDSCAPS_STANDARDVGAMODE
17697 | DDSCAPS_OPTIMIZED
;
17699 caps_always
= DDSCAPS_FLIP
17700 | DDSCAPS_OFFSCREENPLAIN
17701 | DDSCAPS_PRIMARYSURFACE
17706 caps_hal
= DDSCAPS_BACKBUFFER
17708 | DDSCAPS_FRONTBUFFER
17710 | DDSCAPS_VIDEOMEMORY
17711 | DDSCAPS_LOCALVIDMEM
17712 | DDSCAPS_NONLOCALVIDMEM
;
17714 ddraw
= create_ddraw();
17715 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17717 memset(&hal_caps
, 0, sizeof(hal_caps
));
17718 memset(&hel_caps
, 0, sizeof(hel_caps
));
17719 hal_caps
.dwSize
= sizeof(hal_caps
);
17720 hel_caps
.dwSize
= sizeof(hel_caps
);
17721 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17722 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17723 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17724 "Got unexpected caps %#x, expected %#x.\n",
17725 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17726 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17727 "Got unexpected caps %#x, expected %#x.\n",
17728 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17730 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
17731 if (hal_caps
.ddsCaps
.dwCaps
)
17733 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17734 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17735 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17736 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17738 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17739 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17740 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17741 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17743 IDirectDraw7_Release(ddraw
);
17745 if (hal_caps
.ddsCaps
.dwCaps
)
17747 hr
= pDirectDrawCreateEx((GUID
*)DDCREATE_HARDWAREONLY
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
);
17748 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17750 memset(&hal_caps
, 0, sizeof(hal_caps
));
17751 memset(&hel_caps
, 0, sizeof(hel_caps
));
17752 hal_caps
.dwSize
= sizeof(hal_caps
);
17753 hel_caps
.dwSize
= sizeof(hel_caps
);
17754 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17755 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17756 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17757 "Got unexpected caps %#x, expected %#x.\n",
17758 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17759 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17760 "Got unexpected caps %#x, expected %#x.\n",
17761 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17763 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17764 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17765 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17766 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17767 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17769 IDirectDraw7_Release(ddraw
);
17772 hr
= pDirectDrawCreateEx((GUID
*)DDCREATE_EMULATIONONLY
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
);
17773 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17775 memset(&hal_caps
, 0, sizeof(hal_caps
));
17776 memset(&hel_caps
, 0, sizeof(hel_caps
));
17777 hal_caps
.dwSize
= sizeof(hal_caps
);
17778 hel_caps
.dwSize
= sizeof(hel_caps
);
17779 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17780 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17781 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17782 "Got unexpected caps %#x, expected %#x.\n",
17783 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17784 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17785 "Got unexpected caps %#x, expected %#x.\n",
17786 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17788 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17789 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17790 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17791 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17792 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17794 IDirectDraw7_Release(ddraw
);
17797 static void test_d32_support(void)
17799 IDirectDrawSurface7
*surface
;
17800 DDSURFACEDESC2 surface_desc
;
17801 IDirectDraw7
*ddraw
;
17806 window
= create_window();
17807 ddraw
= create_ddraw();
17808 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17809 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17810 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17812 memset(&surface_desc
, 0, sizeof(surface_desc
));
17813 surface_desc
.dwSize
= sizeof(surface_desc
);
17814 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
17815 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
17816 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
17817 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
17818 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 32;
17819 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0xffffffff;
17820 surface_desc
.dwWidth
= 64;
17821 surface_desc
.dwHeight
= 64;
17822 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17823 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17825 memset(&surface_desc
, 0, sizeof(surface_desc
));
17826 surface_desc
.dwSize
= sizeof(surface_desc
);
17827 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
17828 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17829 ok((surface_desc
.dwFlags
& DDSD_PIXELFORMAT
), "Got unexpected flags %#x.\n", surface_desc
.dwFlags
);
17830 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
& DDPF_ZBUFFER
,
17831 "Got unexpected format flags %#x.\n", U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
17832 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
== 32,
17833 "Got unexpected dwZBufferBitDepth %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
);
17834 ok(U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
== 0xffffffff,
17835 "Got unexpected Z mask 0x%08x.\n", U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
);
17836 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
17837 "Got unexpected surface caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
17838 IDirectDrawSurface7_Release(surface
);
17840 refcount
= IDirectDraw7_Release(ddraw
);
17841 ok(!refcount
, "%u references left.\n", refcount
);
17842 DestroyWindow(window
);
17845 static void test_surface_format_conversion_alpha(void)
17847 static const unsigned int rgba_data
[4 * 4] =
17849 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff0000ff,
17850 0xff0000ff, 0xff00ff00, 0xff0000ff, 0xff0000ff,
17851 0xff00ff00, 0xff0000ff, 0xff00ff00, 0xff0000ff,
17852 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff00ff00,
17854 static const unsigned int rgbx_data
[4 * 4] =
17856 0x0000ff00, 0x000000ff, 0x000000ff, 0x000000ff,
17857 0x000000ff, 0x0000ff00, 0x000000ff, 0x000000ff,
17858 0x0000ff00, 0x000000ff, 0x0000ff00, 0x000000ff,
17859 0x0000ff00, 0x000000ff, 0x000000ff, 0x0000ff00,
17861 static const unsigned short int r5g6b5_data
[4 * 4] =
17863 0x07e0, 0x001f, 0x001f, 0x001f,
17864 0x001f, 0x07e0, 0x001f, 0x001f,
17865 0x07e0, 0x001f, 0x07e0, 0x001f,
17866 0x07e0, 0x001f, 0x001f, 0x07e0,
17868 static const unsigned short int r5g5b5x1_data
[4 * 4] =
17870 0x03e0, 0x001f, 0x001f, 0x001f,
17871 0x001f, 0x03e0, 0x001f, 0x001f,
17872 0x03e0, 0x001f, 0x03e0, 0x001f,
17873 0x03e0, 0x001f, 0x001f, 0x03e0,
17875 static const unsigned short int r5g5b5a1_data
[4 * 4] =
17877 0x83e0, 0x801f, 0x801f, 0x801f,
17878 0x801f, 0x83e0, 0x801f, 0x801f,
17879 0x83e0, 0x801f, 0x83e0, 0x801f,
17880 0x83e0, 0x801f, 0x801f, 0x83e0,
17882 static const unsigned int dxt1_data
[8] =
17884 0x001f07e0, 0x14445154,
17886 static const unsigned int dxt2_data
[16] =
17888 0xffffffff, 0xffffffff, 0x001f07e0, 0x14445154,
17891 enum test_format_id
17903 static const struct test_format
17907 unsigned int block_size
, x_blocks
, y_blocks
;
17908 DWORD support_flag
;
17909 BOOL broken_software_blit
, broken_hardware_blit
;
17915 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
17916 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
17922 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17923 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
17929 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17930 {16}, {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}
17932 "R5G6B5", 2, 4, 4, 0, TRUE
,
17933 /* Looks broken for sysmem texture conversions on Windows (at
17934 * least with hardware device), the result is either error from
17935 * _Blt() or a copy of the source data without any conversion. */
17939 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17940 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}
17942 "R5G5B5X1", 2, 4, 4,
17946 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
17947 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}
17949 "R5G5B5A1", 2, 4, 4, 0, FALSE
, TRUE
,
17953 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
17954 {0}, {0}, {0}, {0}, {0}
17956 "DXT1", 8, 1, 1, SUPPORT_DXT1
,
17960 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '2'),
17961 {0}, {0}, {0}, {0}, {0}
17963 "DXT2", 16, 1, 1, SUPPORT_DXT2
,
17967 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '3'),
17968 {0}, {0}, {0}, {0}, {0}
17970 "DXT3", 16, 1, 1, SUPPORT_DXT3
,
17974 static const struct
17976 DWORD src_caps
, dst_caps
;
17980 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
17981 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
17982 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
17983 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
17986 static const struct
17988 enum test_format_id src_format
;
17989 const void *src_data
;
17990 enum test_format_id dst_format
;
17991 const void *expected_data
;
17997 /* The following 3 tests give different results on AMD and NVIDIA on Windows, disabling. */
17998 {FMT_RGBX
, rgbx_data
, FMT_RGBA
, rgba_data
},
17999 {FMT_RGBA
, rgba_data
, FMT_RGBX
, rgbx_data
},
18000 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_RGBA
, rgba_data
},
18002 {FMT_R5G6B5
, r5g6b5_data
, FMT_RGBA
, rgba_data
},
18003 {FMT_R5G6B5
, r5g6b5_data
, FMT_R5G5B5A1
, r5g5b5a1_data
},
18004 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_R5G5B5A1
, r5g5b5x1_data
, TRUE
},
18005 {FMT_R5G5B5A1
, r5g5b5a1_data
, FMT_R5G6B5
, r5g6b5_data
},
18006 {FMT_RGBA
, rgba_data
, FMT_DXT1
, dxt1_data
},
18007 {FMT_RGBX
, rgbx_data
, FMT_DXT1
, dxt1_data
},
18008 {FMT_RGBA
, rgba_data
, FMT_DXT2
, dxt2_data
},
18009 {FMT_RGBX
, rgbx_data
, FMT_DXT2
, dxt2_data
},
18010 {FMT_RGBA
, rgba_data
, FMT_DXT3
, dxt2_data
},
18011 {FMT_RGBX
, rgbx_data
, FMT_DXT3
, dxt2_data
},
18012 {FMT_DXT1
, dxt1_data
, FMT_DXT2
, dxt2_data
},
18013 {FMT_DXT1
, dxt1_data
, FMT_RGBA
, rgba_data
},
18014 {FMT_DXT1
, dxt1_data
, FMT_RGBX
, rgba_data
},
18015 {FMT_DXT3
, dxt2_data
, FMT_RGBA
, rgba_data
},
18016 {FMT_DXT3
, dxt2_data
, FMT_RGBX
, rgba_data
},
18019 const struct test_format
*src_format
, *dst_format
;
18020 IDirectDrawSurface7
*src_surf
, *dst_surf
;
18021 DDSURFACEDESC2 surface_desc
, lock
;
18022 unsigned int i
, j
, x
, y
, pitch
;
18023 IDirect3DDevice7
*device
;
18024 DWORD supported_fmts
;
18025 IDirectDraw7
*ddraw
;
18032 window
= create_window();
18033 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
18035 skip("Failed to create a 3D device, skipping test.\n");
18036 DestroyWindow(window
);
18040 ddraw
= create_ddraw();
18041 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18042 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18043 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18045 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
18047 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18049 is_wine
= !strcmp(winetest_platform
, "wine");
18051 memset(&surface_desc
, 0, sizeof(surface_desc
));
18052 surface_desc
.dwSize
= sizeof(surface_desc
);
18053 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18054 surface_desc
.dwWidth
= 4;
18055 surface_desc
.dwHeight
= 4;
18057 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
18059 src_format
= &formats
[tests
[i
].src_format
];
18060 dst_format
= &formats
[tests
[i
].dst_format
];
18062 if (~supported_fmts
& dst_format
->support_flag
)
18064 skip("%s format is not supported, skipping test %u.\n", dst_format
->name
, i
);
18067 if (~supported_fmts
& src_format
->support_flag
)
18069 skip("%s format is not supported, skipping test %u.\n", src_format
->name
, i
);
18073 for (j
= 0; j
< ARRAY_SIZE(test_caps
); ++j
)
18075 if (!is_wine
&& ((test_caps
[j
].src_caps
| test_caps
[j
].dst_caps
) & DDSCAPS_SYSTEMMEMORY
)
18076 && (src_format
->broken_software_blit
|| dst_format
->broken_software_blit
))
18078 if (!is_wine
&& (test_caps
[j
].dst_caps
& DDSCAPS_VIDEOMEMORY
)
18079 && dst_format
->broken_hardware_blit
)
18082 U4(surface_desc
).ddpfPixelFormat
= src_format
->fmt
;
18083 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].src_caps
;
18084 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surf
, NULL
);
18085 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", j
, i
, hr
);
18087 U4(surface_desc
).ddpfPixelFormat
= dst_format
->fmt
;
18088 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].dst_caps
;
18089 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surf
, NULL
);
18090 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", j
, i
, hr
);
18092 memset(&lock
, 0, sizeof(lock
));
18093 lock
.dwSize
= sizeof(lock
);
18094 hr
= IDirectDrawSurface7_Lock(src_surf
, NULL
, &lock
, 0, NULL
);
18095 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18096 pitch
= U1(lock
).lPitch
;
18097 for (y
= 0; y
< src_format
->y_blocks
; ++y
)
18099 memcpy((BYTE
*)lock
.lpSurface
+ y
* pitch
,
18100 (BYTE
*)tests
[i
].src_data
+ y
* src_format
->x_blocks
* src_format
->block_size
,
18101 src_format
->block_size
* src_format
->x_blocks
);
18103 hr
= IDirectDrawSurface7_Unlock(src_surf
, NULL
);
18104 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18106 hr
= IDirectDrawSurface7_Blt(dst_surf
, NULL
, src_surf
, NULL
, DDBLT_WAIT
, NULL
);
18107 if (!is_wine
&& FAILED(hr
))
18109 /* Some software blits are rejected on Windows. */
18110 IDirectDrawSurface7_Release(dst_surf
);
18111 IDirectDrawSurface7_Release(src_surf
);
18112 skip("Skipping test (%u, %u), cannot blit %s -> %s, hr %#x.\n", j
, i
,
18113 src_format
->name
, dst_format
->name
, hr
);
18116 ok(hr
== DD_OK
, "Test (%u, %s -> %s), got unexpected hr %#x.\n", j
,
18117 src_format
->name
, dst_format
->name
, hr
);
18119 memset(&lock
, 0, sizeof(lock
));
18120 lock
.dwSize
= sizeof(lock
);
18121 hr
= IDirectDrawSurface7_Lock(dst_surf
, NULL
, &lock
, 0, NULL
);
18122 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18123 pitch
= U1(lock
).lPitch
;
18125 for (y
= 0; y
< dst_format
->y_blocks
; ++y
)
18127 const void *expected_data
= tests
[i
].expected_data
;
18129 passed
= !memcmp((BYTE
*)lock
.lpSurface
+ y
* pitch
,
18130 (BYTE
*)expected_data
+ y
* dst_format
->x_blocks
* dst_format
->block_size
,
18131 dst_format
->block_size
* dst_format
->x_blocks
);
18132 todo_wine_if(tests
[i
].todo
)
18133 ok(passed
, "Test (%u, %s -> %s), row %u, unexpected surface data.\n", j
,
18134 src_format
->name
, dst_format
->name
, y
);
18136 if (!passed
&& !(is_wine
&& tests
[i
].todo
))
18138 for (x
= 0; x
< dst_format
->x_blocks
* dst_format
->block_size
/ 4; ++x
)
18140 trace("Test (%u, %u), x %u, y %u, got 0x%08x, expected 0x%08x.\n", j
, i
, x
, y
,
18141 *(unsigned int *)((BYTE
*)lock
.lpSurface
+ y
* pitch
+ x
* 4),
18142 *(unsigned int *)((BYTE
*)expected_data
+ y
* dst_format
->x_blocks
18143 * dst_format
->block_size
+ x
* 4));
18149 hr
= IDirectDrawSurface7_Unlock(dst_surf
, NULL
);
18150 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18152 IDirectDrawSurface7_Release(dst_surf
);
18153 IDirectDrawSurface7_Release(src_surf
);
18157 IDirect3DDevice7_Release(device
);
18158 refcount
= IDirectDraw7_Release(ddraw
);
18159 ok(!refcount
, "%u references left.\n", refcount
);
18160 DestroyWindow(window
);
18163 static void test_compressed_surface_stretch(void)
18165 static const struct
18167 unsigned int src_width
, src_height
;
18168 unsigned int dst_width
, dst_height
;
18169 unsigned int src_x
, src_y
;
18170 unsigned int dst_x
, dst_y
;
18171 BOOL todo_src
, todo_dst
;
18177 {4, 4, 2, 2, 0, 0, 0, 0, FALSE
, TRUE
},
18178 {4, 4, 6, 6, 0, 0, 0, 0, FALSE
, TRUE
},
18179 {4, 4, 8, 8, 2, 2, 2, 2, TRUE
, TRUE
},
18182 static const struct
18184 DWORD src_caps
, dst_caps
;
18189 /* Broken on Windows. */
18190 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18192 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18193 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18194 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18201 DWORD support_flag
;
18207 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18208 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}
18214 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
18215 {0}, {0}, {0}, {0}, {0}
18217 "DXT1", SUPPORT_DXT1
,
18221 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '3'),
18222 {0}, {0}, {0}, {0}, {0}
18224 "DXT3", SUPPORT_DXT3
,
18228 unsigned int i
, j
, k
, l
, x
, y
, pitch
;
18229 DDSURFACEDESC2 rb_surface_desc
, src_surface_desc
, dst_surface_desc
, lock
;
18230 IDirectDrawSurface7
*src_surf
, *dst_surf
, *rb_surf
;
18231 IDirect3DDevice7
*device
;
18232 RECT src_rect
, dst_rect
;
18233 DWORD supported_fmts
;
18234 unsigned short *data
;
18235 IDirectDraw7
*ddraw
;
18242 window
= create_window();
18243 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
18245 skip("Failed to create a 3D device, skipping test.\n");
18246 DestroyWindow(window
);
18250 ddraw
= create_ddraw();
18251 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18252 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18253 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18255 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
18257 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18259 memset(&src_surface_desc
, 0, sizeof(src_surface_desc
));
18260 src_surface_desc
.dwSize
= sizeof(src_surface_desc
);
18261 src_surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18262 dst_surface_desc
= src_surface_desc
;
18264 memset(&rb_surface_desc
, 0, sizeof(rb_surface_desc
));
18265 rb_surface_desc
.dwSize
= sizeof(rb_surface_desc
);
18266 rb_surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18267 U4(rb_surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(rb_surface_desc
).ddpfPixelFormat
);
18268 U4(rb_surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
18269 U1(U4(rb_surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
18270 U2(U4(rb_surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
18271 U3(U4(rb_surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
18272 U4(U4(rb_surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
18273 U5(U4(rb_surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00008000;
18274 rb_surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
18276 memset(&fx
, 0, sizeof(fx
));
18277 fx
.dwSize
= sizeof(fx
);
18279 memset(&lock
, 0, sizeof(lock
));
18280 lock
.dwSize
= sizeof(lock
);
18282 for (i
= 0; i
< ARRAY_SIZE(test_caps
); ++i
)
18284 src_surface_desc
.ddsCaps
.dwCaps
= test_caps
[i
].src_caps
;
18285 dst_surface_desc
.ddsCaps
.dwCaps
= test_caps
[i
].dst_caps
;
18287 for (j
= 0; j
< ARRAY_SIZE(test_sizes
); ++j
)
18289 SetRect(&src_rect
, test_sizes
[j
].src_x
, test_sizes
[j
].src_y
,
18290 test_sizes
[j
].src_width
, test_sizes
[j
].src_height
);
18291 SetRect(&dst_rect
, test_sizes
[j
].dst_x
, test_sizes
[j
].dst_y
,
18292 test_sizes
[j
].dst_width
, test_sizes
[j
].dst_height
);
18294 src_surface_desc
.dwWidth
= test_sizes
[j
].src_width
;
18295 src_surface_desc
.dwHeight
= test_sizes
[j
].src_height
;
18297 dst_surface_desc
.dwWidth
= (test_sizes
[j
].dst_width
+ 3) & ~3;
18298 dst_surface_desc
.dwHeight
= (test_sizes
[j
].dst_height
+ 3) & ~3;
18300 rb_surface_desc
.dwWidth
= max(src_surface_desc
.dwWidth
, dst_surface_desc
.dwWidth
);
18301 rb_surface_desc
.dwHeight
= max(src_surface_desc
.dwHeight
, dst_surface_desc
.dwHeight
);
18303 hr
= IDirectDraw7_CreateSurface(ddraw
, &rb_surface_desc
, &rb_surf
, NULL
);
18304 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", i
, j
, hr
);
18306 for (k
= 0; k
< ARRAY_SIZE(test_formats
); ++k
)
18308 U4(src_surface_desc
).ddpfPixelFormat
= test_formats
[k
].fmt
;
18309 hr
= IDirectDraw7_CreateSurface(ddraw
, &src_surface_desc
, &src_surf
, NULL
);
18310 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18312 U5(fx
).dwFillColor
= 0x801f;
18313 hr
= IDirectDrawSurface7_Blt(rb_surf
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
18314 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18316 hr
= IDirectDrawSurface7_Blt(src_surf
, &src_rect
, rb_surf
, &src_rect
, DDBLT_WAIT
, NULL
);
18318 todo_wine_if(test_formats
[k
].fmt
.dwFlags
== DDPF_FOURCC
&& test_sizes
[j
].todo_src
)
18319 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18322 IDirectDrawSurface7_Release(src_surf
);
18326 for (l
= 0; l
< ARRAY_SIZE(test_formats
); ++l
)
18328 if (~supported_fmts
& test_formats
[l
].support_flag
)
18330 skip("%s format is not supported, skipping test %u.\n", test_formats
[l
].name
, i
);
18334 U4(dst_surface_desc
).ddpfPixelFormat
= test_formats
[l
].fmt
;
18336 hr
= IDirectDraw7_CreateSurface(ddraw
, &dst_surface_desc
, &dst_surf
, NULL
);
18337 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18339 memset(&lock
, 0, sizeof(lock
));
18340 lock
.dwSize
= sizeof(lock
);
18342 /* r200 does not init vidmem DXT3 surfaces to 0 correctly. Do it manually.
18343 * We can't use DDBLT_COLORFILL on compressed surfaces, so we need memset.
18345 * Locking alone is not enough, so this isn't an accidental workaround that
18346 * forces a different codepath because the destination is currently in sysmem. */
18347 if (test_formats
[l
].fmt
.dwFourCC
== MAKEFOURCC('D', 'X', 'T', '3'))
18349 hr
= IDirectDrawSurface7_Lock(dst_surf
, NULL
, &lock
, 0, NULL
);
18350 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18351 memset(lock
.lpSurface
, 0, U1(lock
).dwLinearSize
);
18352 hr
= IDirectDrawSurface7_Unlock(dst_surf
, NULL
);
18353 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18356 hr
= IDirectDrawSurface7_Blt(dst_surf
, &dst_rect
, src_surf
, &src_rect
, DDBLT_WAIT
, NULL
);
18357 todo_wine_if(test_formats
[l
].fmt
.dwFlags
== DDPF_FOURCC
&& test_sizes
[j
].todo_dst
)
18358 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18361 IDirectDrawSurface7_Release(dst_surf
);
18365 U5(fx
).dwFillColor
= 0xffffffff;
18366 hr
= IDirectDrawSurface7_Blt(rb_surf
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
18367 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18369 hr
= IDirectDrawSurface7_Blt(rb_surf
, &dst_rect
, dst_surf
, &dst_rect
, DDBLT_WAIT
, NULL
);
18370 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18371 hr
= IDirectDrawSurface7_Lock(rb_surf
, NULL
, &lock
, 0, NULL
);
18372 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18373 pitch
= U1(lock
).lPitch
;
18376 for (y
= dst_rect
.top
; y
< dst_rect
.bottom
&& passed
; ++y
)
18378 data
= (unsigned short *)((BYTE
*)lock
.lpSurface
+ y
* pitch
);
18380 for (x
= dst_rect
.left
; x
< dst_rect
.right
&& passed
; ++x
)
18382 passed
= data
[x
] == 0x801f;
18383 ok(passed
, "Test (%u, %u, %u, %u), x %u, y %u, "
18384 "got unexpected colour 0x%04x.\n", i
, j
, k
, l
, x
, y
, data
[x
]);
18387 hr
= IDirectDrawSurface7_Unlock(rb_surf
, NULL
);
18388 IDirectDrawSurface7_Release(dst_surf
);
18390 IDirectDrawSurface7_Release(src_surf
);
18392 IDirectDrawSurface7_Release(rb_surf
);
18396 IDirect3DDevice7_Release(device
);
18397 refcount
= IDirectDraw7_Release(ddraw
);
18398 ok(!refcount
, "%u references left.\n", refcount
);
18399 DestroyWindow(window
);
18402 struct find_different_mode_param
18404 unsigned int old_width
;
18405 unsigned int old_height
;
18406 unsigned int old_frequency
;
18407 unsigned int new_width
;
18408 unsigned int new_height
;
18409 unsigned int new_frequency
;
18410 unsigned int new_bpp
;
18413 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC2
*surface_desc
, void *context
)
18415 struct find_different_mode_param
*param
= context
;
18417 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
18418 return DDENUMRET_OK
;
18420 /* Windows will advertise 59hz (for 59.94) and 60hz (for proper 60hz) on monitors that support
18421 * only one of the two (usually 59.94). If an application requests 60hz windows will apply 59.94.
18422 * Thus if we think we found a different refresh rate, we get 59hz instead of the 60hz we
18425 * The same is true of other 1% slowed-down TV compatible refresh rates according to a Microsoft
18426 * support document: 23.976 vs 24, 30, 48, 72 and 120 hz. It can be reproduced by attempting to
18427 * set 60hz in the advanced display properties manually. Usually the restriction to one refresh
18428 * rate applies to laptop panels. */
18429 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
18430 (!compare_uint(surface_desc
->dwRefreshRate
, param
->old_frequency
, 1) || !param
->old_frequency
))
18432 param
->new_width
= surface_desc
->dwWidth
;
18433 param
->new_height
= surface_desc
->dwHeight
;
18434 param
->new_frequency
= surface_desc
->dwRefreshRate
;
18435 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
18436 return DDENUMRET_CANCEL
;
18439 return DDENUMRET_OK
;
18442 static void test_cursor_clipping(void)
18444 struct find_different_mode_param param
;
18445 DDSURFACEDESC2 surface_desc
;
18446 RECT rect
, clip_rect
;
18447 IDirectDraw7
*ddraw
;
18452 window
= create_window();
18453 ok(!!window
, "Failed to create a window.\n");
18454 ddraw
= create_ddraw();
18455 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18457 memset(&surface_desc
, 0, sizeof(surface_desc
));
18458 surface_desc
.dwSize
= sizeof(surface_desc
);
18459 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18460 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18462 memset(¶m
, 0, sizeof(param
));
18463 param
.old_width
= surface_desc
.dwWidth
;
18464 param
.old_height
= surface_desc
.dwHeight
;
18465 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
18466 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
18467 if (!(param
.new_width
&& param
.new_height
))
18469 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
18473 ret
= ClipCursor(NULL
);
18474 ok(ret
, "ClipCursor failed, error %#x.\n", GetLastError());
18475 get_virtual_rect(&rect
);
18476 ret
= GetClipCursor(&clip_rect
);
18477 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18478 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18479 wine_dbgstr_rect(&clip_rect
));
18481 /* Set cooperative level to normal */
18482 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18483 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18485 get_virtual_rect(&rect
);
18486 ret
= GetClipCursor(&clip_rect
);
18487 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18488 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18489 wine_dbgstr_rect(&clip_rect
));
18491 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18492 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
18495 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
18499 get_virtual_rect(&rect
);
18500 ret
= GetClipCursor(&clip_rect
);
18501 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18502 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18503 wine_dbgstr_rect(&clip_rect
));
18505 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
18506 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
18508 get_virtual_rect(&rect
);
18509 ret
= GetClipCursor(&clip_rect
);
18510 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18511 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18512 wine_dbgstr_rect(&clip_rect
));
18514 /* Switch to full screen cooperative level */
18515 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18516 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18518 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18519 ret
= GetClipCursor(&clip_rect
);
18520 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18521 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18522 wine_dbgstr_rect(&clip_rect
));
18524 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18525 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
18528 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
18532 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
18533 ret
= GetClipCursor(&clip_rect
);
18534 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18535 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18536 wine_dbgstr_rect(&clip_rect
));
18538 /* Restore display mode */
18539 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
18540 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
18542 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18543 ret
= GetClipCursor(&clip_rect
);
18544 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18545 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18546 wine_dbgstr_rect(&clip_rect
));
18548 /* Switch to normal cooperative level */
18549 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18550 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18552 get_virtual_rect(&rect
);
18553 ret
= GetClipCursor(&clip_rect
);
18554 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18555 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18556 wine_dbgstr_rect(&clip_rect
));
18559 IDirectDraw7_Release(ddraw
);
18560 DestroyWindow(window
);
18563 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18566 RECT primary_rect
, window_rect
, new_rect
;
18567 IDirectDraw7
*ddraw
;
18572 ddraw
= create_ddraw();
18573 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18574 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
18575 monitor_rect
->top
, monitor_rect
->right
- monitor_rect
->left
,
18576 monitor_rect
->bottom
- monitor_rect
->top
, NULL
, NULL
, NULL
, NULL
);
18577 ok(!!window
, "Failed to create a window.\n");
18580 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18581 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18583 ret
= GetWindowRect(window
, &window_rect
);
18584 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18585 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
18586 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18587 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18589 new_rect
= window_rect
;
18593 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
18594 new_rect
.bottom
- new_rect
.top
, TRUE
);
18595 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18596 ret
= GetWindowRect(window
, &window_rect
);
18597 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18598 ok(EqualRect(&window_rect
, &new_rect
),
18599 "Expected window rect %s, got %s.\n",
18600 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18601 /* After processing window events window rectangle gets restored. But only once, the size set
18602 * on the second resize remains. */
18604 ret
= GetWindowRect(window
, &window_rect
);
18605 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18606 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
18607 * it may get adjusted depending on window manager. */
18608 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
18609 "Expected window rect %s, got %s.\n",
18610 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18612 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
18613 new_rect
.bottom
- new_rect
.top
, TRUE
);
18614 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18615 ret
= GetWindowRect(window
, &window_rect
);
18616 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18617 ok(EqualRect(&window_rect
, &new_rect
),
18618 "Expected window rect %s, got %s.\n",
18619 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18621 ret
= GetWindowRect(window
, &window_rect
);
18622 ok(ret
, "Got unexpected ret %#x, error %#x.\n", ret
, GetLastError());
18623 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
18624 "Expected window rect %s, got %s.\n",
18625 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18627 /* Window activation should restore the window to fit the whole primary monitor */
18628 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18629 SWP_NOZORDER
| SWP_NOSIZE
);
18630 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
18631 ret
= SetForegroundWindow(GetDesktopWindow());
18632 ok(ret
, "Failed to set foreground window.\n");
18634 ret
= ShowWindow(window
, SW_RESTORE
);
18635 ok(ret
, "Failed to restore window, error %#x.\n", GetLastError());
18637 ret
= SetForegroundWindow(window
);
18638 ok(ret
, "SetForegroundWindow failed, error %#x.\n", GetLastError());
18640 ret
= GetWindowRect(window
, &window_rect
);
18641 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18642 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18643 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18645 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18646 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18647 ret
= GetWindowRect(window
, &window_rect
);
18648 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18649 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18650 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18652 DestroyWindow(window
);
18653 IDirectDraw7_Release(ddraw
);
18657 static void test_window_position(void)
18659 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
18662 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18665 DDSURFACEDESC2 surface_desc
;
18666 IDirectDraw7
*ddraw
;
18671 ddraw
= create_ddraw();
18672 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18673 window
= create_window();
18674 ok(!!window
, "Failed to create a window.\n");
18676 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
18677 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18678 SWP_NOZORDER
| SWP_NOSIZE
);
18679 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
18681 surface_desc
.dwSize
= sizeof(surface_desc
);
18682 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18683 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18684 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %d.\n",
18685 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
18686 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %d.\n",
18687 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
18689 DestroyWindow(window
);
18690 IDirectDraw7_Release(ddraw
);
18694 static void test_get_display_mode(void)
18696 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
18697 struct find_different_mode_param param
;
18698 DDSURFACEDESC2 surface_desc
;
18699 IDirectDraw7
*ddraw
;
18705 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
18707 ddraw
= create_ddraw();
18708 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18709 window
= create_window();
18710 ok(!!window
, "Failed to create a window.\n");
18712 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18713 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18715 memset(&devmode
, 0, sizeof(devmode
));
18716 devmode
.dmSize
= sizeof(devmode
);
18717 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
18718 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
18720 surface_desc
.dwSize
= sizeof(surface_desc
);
18721 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18722 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18723 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Expected dwSize %u, got %u.\n",
18724 sizeof(surface_desc
), surface_desc
.dwSize
);
18725 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#x, got %#x.\n", flags
,
18726 surface_desc
.dwFlags
);
18727 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %u, got %u.\n",
18728 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
18729 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %u, got %u.\n",
18730 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
18731 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %u, got %u.\n",
18732 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
18733 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
18734 "Expected ddpfPixelFormat.dwSize %u, got %u.\n", sizeof(surface_desc
.ddpfPixelFormat
),
18735 surface_desc
.ddpfPixelFormat
.dwSize
);
18736 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
18737 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
18738 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18739 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18740 "Expected pitch %u, got %u.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18741 surface_desc
.lPitch
);
18743 memset(¶m
, 0, sizeof(param
));
18744 param
.old_frequency
= surface_desc
.dwRefreshRate
;
18745 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
18746 find_different_mode_callback
);
18747 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
18748 if (!param
.new_frequency
)
18750 skip("Failed to find a display mode with a different frequency.\n");
18754 hr
= IDirectDraw7_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
18755 param
.new_frequency
, 0);
18756 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#x.\n", hr
);
18757 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18758 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18759 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %u.\n", param
.new_width
,
18760 surface_desc
.dwWidth
);
18761 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %u.\n", param
.new_height
,
18762 surface_desc
.dwHeight
);
18763 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %u.\n",
18764 param
.new_frequency
, surface_desc
.dwRefreshRate
);
18765 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
18766 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
18767 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18770 DestroyWindow(window
);
18771 IDirectDraw7_Release(ddraw
);
18774 static void test_texture_wrong_caps(const GUID
*device_guid
)
18778 struct vec3 position
;
18779 struct vec2 texcoord
;
18783 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
18784 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
18785 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
18786 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
18788 static DDPIXELFORMAT fmt
=
18790 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18791 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
18793 IDirectDrawSurface7
*surface
, *rt
;
18794 IDirect3DDevice7
*device
;
18795 IDirectDraw7
*ddraw
;
18796 DDSURFACEDESC2 ddsd
;
18803 window
= create_window();
18804 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
18806 skip("Failed to create a 3D device, skipping test.\n");
18807 DestroyWindow(window
);
18810 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
18811 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18812 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
18813 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18814 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
18815 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18817 memset(&ddsd
, 0, sizeof(ddsd
));
18818 ddsd
.dwSize
= sizeof(ddsd
);
18819 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
18820 ddsd
.dwHeight
= 16;
18822 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
18823 U4(ddsd
).ddpfPixelFormat
= fmt
;
18824 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
18825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18827 fill_surface(surface
, 0xff00ff00);
18829 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
18830 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18832 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
18833 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18834 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
18835 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18836 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
18837 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18838 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
18839 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18841 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
18842 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18844 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
18845 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18846 if (is_software_device_type(device_guid
))
18847 fill_surface(rt
, 0x000000ff);
18849 hr
= IDirect3DDevice7_BeginScene(device
);
18850 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18851 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
18852 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
18853 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18854 hr
= IDirect3DDevice7_EndScene(device
);
18855 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18857 color
= get_surface_color(rt
, 320, 240);
18858 ok(color
== 0, "Got unexpected color 0x%08x.\n", color
);
18860 IDirectDrawSurface7_Release(surface
);
18861 IDirectDrawSurface7_Release(rt
);
18862 IDirectDraw7_Release(ddraw
);
18863 IDirect3D7_Release(d3d
);
18864 refcount
= IDirect3DDevice3_Release(device
);
18865 ok(!refcount
, "Device has %u references left.\n", refcount
);
18866 DestroyWindow(window
);
18869 static void test_filling_convention(void)
18871 static const DWORD colour_bottom
= 0x00ffff00;
18872 static const DWORD colour_clear
= 0x000000ff;
18873 static const DWORD colour_right
= 0x00000000;
18874 static const DWORD colour_left
= 0x00ff0000;
18875 static const DWORD colour_top
= 0x0000ff00;
18876 IDirectDrawSurface7
*rt
, *backbuffer
, *cur
;
18877 IDirect3DDevice7
*device
;
18878 unsigned int i
, j
, x
, y
;
18879 DWORD colour
, expected
;
18880 IDirectDraw7
*ddraw
;
18881 DDSURFACEDESC2 desc
;
18888 static const unsigned int vp_size
= 8;
18889 D3DVIEWPORT7 vp
= { 0, 0, vp_size
, vp_size
, 0.0, 1.0 };
18891 /* This test data follows the examples in MSDN's
18892 * "Rasterization Rules (Direct3D 9)" article.
18894 * See the d3d9 test for a comment about the eps value. */
18895 static const float eps
= 1.0f
/ 64.0f
;
18898 struct vec3 position
;
18904 {{-2.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_left
},
18905 {{-2.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_left
},
18906 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_left
},
18909 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_top
},
18910 {{-2.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_top
},
18911 {{-0.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_top
},
18914 {{-0.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_right
},
18915 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_right
},
18916 {{-0.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_right
},
18919 {{-2.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18920 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18921 {{-0.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18927 {{-2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18928 {{-2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18929 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18932 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18933 {{-2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18934 {{ 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18937 {{ 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18938 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18939 {{ 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18942 {{-2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18943 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18944 {{ 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18946 nudge_right_tris
[] =
18949 {{eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18950 {{eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18951 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18954 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18955 {{eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18956 {{eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18959 {{eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18960 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18961 {{eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18964 {{eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18965 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18966 {{eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18968 nudge_left_tris
[] =
18970 {{-eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18971 {{-eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18972 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18975 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18976 {{-eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18977 {{-eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18980 {{-eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18981 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18982 {{-eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18985 {{-eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18986 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18987 {{-eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18992 {{-2.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18993 {{-2.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18994 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18997 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18998 {{-2.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18999 {{ 0.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
19002 {{ 0.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
19003 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
19004 {{ 0.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
19007 {{-2.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19008 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19009 {{ 0.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19011 nudge_bottom_tris
[] =
19014 {{-2.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
19015 {{-2.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
19016 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
19019 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
19020 {{-2.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
19021 {{ 0.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
19024 {{ 0.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
19025 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
19026 {{ 0.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
19029 {{-2.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19030 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19031 {{ 0.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
19036 struct vec4 position
;
19042 {{ 1.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_left
},
19043 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_left
},
19044 {{ 1.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_left
},
19047 {{ 1.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_top
},
19048 {{ 3.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_top
},
19049 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_top
},
19052 {{ 3.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_right
},
19053 {{ 3.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_right
},
19054 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_right
},
19057 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_bottom
},
19058 {{ 3.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_bottom
},
19059 {{ 1.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_bottom
},
19064 {{ 2.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_left
},
19065 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_left
},
19066 {{ 2.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_left
},
19069 {{ 2.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_top
},
19070 {{ 4.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_top
},
19071 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_top
},
19074 {{ 4.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_right
},
19075 {{ 4.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_right
},
19076 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_right
},
19079 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_bottom
},
19080 {{ 4.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_bottom
},
19081 {{ 2.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_bottom
},
19088 const char *expected
[8];
19094 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19108 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19122 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19136 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19150 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19164 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19178 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
,
19192 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
,
19206 window
= create_window();
19207 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
19209 skip("Failed to create 3D device.\n");
19210 DestroyWindow(window
);
19214 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
19215 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
19216 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
19217 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
19218 hr
= IDirect3DDevice7_GetRenderTarget(device
, &backbuffer
);
19219 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
19221 memset(&desc
, 0, sizeof(desc
));
19222 desc
.dwSize
= sizeof(desc
);
19223 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
19224 desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
19225 desc
.dwWidth
= vp_size
;
19226 desc
.dwHeight
= vp_size
;
19227 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
19228 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
19229 desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
19230 desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
19231 desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
19232 desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
19233 hr
= IDirectDraw7_CreateSurface(ddraw
, &desc
, &rt
, NULL
);
19234 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19236 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
19237 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19238 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
19239 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19241 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
19243 for (j
= 0; j
< 2; ++j
)
19245 cur
= j
? rt
: backbuffer
;
19247 hr
= IDirect3DDevice7_SetRenderTarget(device
, cur
, 0);
19248 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19249 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, colour_clear
, 0.0f
, 0);
19250 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19251 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
19252 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19254 hr
= IDirect3DDevice7_BeginScene(device
);
19255 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19256 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLELIST
,
19257 tests
[i
].fvf
, tests
[i
].geometry
, 12, 0);
19258 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19259 hr
= IDirect3DDevice7_EndScene(device
);
19260 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
19262 for (y
= 0; y
< 8; y
++)
19264 for (x
= 0; x
< 8; x
++)
19267 switch (tests
[i
].expected
[y
][x
])
19269 case 'l': todo
= TRUE
;
19271 expected
= colour_left
;
19273 case 't': todo
= TRUE
;
19275 expected
= colour_top
;
19277 case 'r': todo
= TRUE
;
19279 expected
= colour_right
;
19281 case 'b': todo
= TRUE
;
19283 expected
= colour_bottom
;
19286 expected
= colour_clear
;
19289 ok(0, "Unexpected entry in expected test char\n");
19290 expected
= 0xdeadbeef;
19292 colour
= get_surface_color(cur
, x
, y
);
19293 /* The nudge-to-bottom test fails on cards that give us a bottom-left
19294 * filling convention. The cause isn't the bottom part of the filling
19295 * convention, but because wined3d will nudge geometry to the left to
19296 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
19297 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
19298 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
19299 colour
, x
, y
, i
, j
);
19305 IDirectDrawSurface7_Release(backbuffer
);
19306 IDirectDrawSurface7_Release(rt
);
19307 IDirectDraw7_Release(ddraw
);
19308 IDirect3D7_Release(d3d
);
19309 refcount
= IDirect3DDevice7_Release(device
);
19310 ok(!refcount
, "Device has %u references left.\n", refcount
);
19311 DestroyWindow(window
);
19314 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
19316 test_func(hw_device_guid
);
19317 test_func(&IID_IDirect3DRGBDevice
);
19322 DDDEVICEIDENTIFIER2 identifier
;
19323 HMODULE module
, dwmapi
;
19324 DEVMODEW current_mode
;
19325 IDirectDraw7
*ddraw
;
19330 module
= GetModuleHandleA("ddraw.dll");
19331 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
19333 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
19337 if (!(ddraw
= create_ddraw()))
19339 skip("Failed to create a ddraw object, skipping tests.\n");
19343 if (ddraw_get_identifier(ddraw
, &identifier
))
19345 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
19346 trace("Description string: \"%s\"\n", identifier
.szDescription
);
19347 trace("Driver version %d.%d.%d.%d\n",
19348 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
19349 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
19352 if (IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
) == DD_OK
)
19354 hr
= IDirect3D7_EnumDevices(d3d
, enum_devtype_cb
, &hal_ok
);
19355 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
19357 hw_device_guid
= &IID_IDirect3DTnLHalDevice
;
19358 IDirectDraw7_Release(d3d
);
19362 trace("D3D interface is not available.\n");
19365 IDirectDraw7_Release(ddraw
);
19367 memset(¤t_mode
, 0, sizeof(current_mode
));
19368 current_mode
.dmSize
= sizeof(current_mode
);
19369 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
19370 registry_mode
.dmSize
= sizeof(registry_mode
);
19371 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
19372 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
19373 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
19375 skip("Current mode does not match registry mode, skipping test.\n");
19379 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
19380 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
19382 test_process_vertices();
19383 test_coop_level_create_device_window();
19384 test_clipper_blt();
19385 test_coop_level_d3d_state();
19386 test_surface_interface_mismatch();
19387 test_coop_level_threaded();
19388 run_for_each_device_type(test_depth_blit
);
19389 test_texture_load_ckey();
19390 run_for_each_device_type(test_zenable
);
19391 run_for_each_device_type(test_ck_rgba
);
19397 test_window_style();
19398 test_redundant_mode_set();
19399 test_coop_level_mode_set();
19400 test_coop_level_mode_set_multi();
19402 test_coop_level_surf_create();
19404 test_coop_level_multi_window();
19405 test_draw_strided();
19407 test_specular_lighting();
19408 test_clear_rect_count();
19409 test_coop_level_versions();
19410 test_fog_special();
19411 test_lighting_interface_versions();
19412 test_coop_level_activateapp();
19413 test_texturemanage();
19414 test_block_formats_creation();
19415 test_unsupported_formats();
19416 run_for_each_device_type(test_rt_caps
);
19417 test_primary_caps();
19418 test_surface_lock();
19419 test_surface_discard();
19421 test_set_surface_desc();
19422 test_user_memory_getdc();
19423 test_sysmem_overlay();
19424 test_primary_palette();
19425 test_surface_attachment();
19426 test_private_data();
19427 test_pixel_format();
19428 test_create_surface_pitch();
19430 test_palette_complex();
19433 test_palette_gdi();
19434 test_palette_alpha();
19435 test_vb_writeonly();
19436 test_lost_device();
19437 test_resource_priority();
19438 test_surface_desc_lock();
19439 test_fog_interpolation();
19440 test_fog_process_vertices();
19441 test_negative_fixedfunction_fog();
19442 test_table_fog_zw();
19443 test_signed_formats();
19445 test_texcoordindex();
19446 test_colorkey_precision();
19447 test_range_colorkey();
19449 test_lockrect_invalid();
19450 test_yv12_overlay();
19451 test_offscreen_overlay();
19452 test_overlay_rect();
19454 test_blt_z_alpha();
19455 test_cross_device_blt();
19456 test_color_clamping();
19458 test_draw_primitive();
19459 test_edge_antialiasing_blending();
19460 test_display_mode_surface_pixel_format();
19461 test_surface_desc_size();
19462 test_get_surface_from_dc();
19463 test_ck_operation();
19464 test_vb_refcount();
19465 test_compute_sphere_visibility();
19466 test_clip_planes_limits();
19467 test_texture_stages_limits();
19468 test_set_render_state();
19469 test_map_synchronisation();
19470 test_depth_readback();
19472 test_enum_surfaces();
19474 test_device_load();
19475 test_color_vertex();
19477 test_sysmem_draw();
19478 test_gdi_surface();
19479 test_multiply_transform();
19481 test_clipper_refcount();
19482 test_begin_end_state_block();
19484 test_d32_support();
19485 test_surface_format_conversion_alpha();
19486 test_compressed_surface_stretch();
19487 test_cursor_clipping();
19488 test_window_position();
19489 test_get_display_mode();
19490 run_for_each_device_type(test_texture_wrong_caps
);
19491 test_filling_convention();