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 IDirectDraw7
*ddraw
;
2573 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2574 0, 0, 100, 100, 0, 0, 0, 0);
2575 ddraw
= create_ddraw();
2576 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2578 style
= GetWindowLongA(window
, GWL_STYLE
);
2579 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2580 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2582 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2583 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2585 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2586 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2587 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2588 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2590 GetWindowRect(window
, &r
);
2591 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2592 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2593 GetClientRect(window
, &r
);
2594 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2596 ret
= SetForegroundWindow(GetDesktopWindow());
2597 ok(ret
, "Failed to set foreground window.\n");
2599 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2600 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2601 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2602 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2604 ret
= SetForegroundWindow(window
);
2605 ok(ret
, "Failed to set foreground window.\n");
2606 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2607 * the next tests expect this. */
2608 ShowWindow(window
, SW_HIDE
);
2610 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2611 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2613 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2614 ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2615 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2616 ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2618 ShowWindow(window
, SW_SHOW
);
2619 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2620 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2622 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2623 expected_style
= style
| WS_VISIBLE
;
2624 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2625 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2626 expected_style
= exstyle
| WS_EX_TOPMOST
;
2627 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2629 ret
= SetForegroundWindow(GetDesktopWindow());
2630 ok(ret
, "Failed to set foreground window.\n");
2631 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2632 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
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 ref
= IDirectDraw7_Release(ddraw
);
2639 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2641 DestroyWindow(window
);
2644 static void test_redundant_mode_set(void)
2646 DDSURFACEDESC2 surface_desc
= {0};
2647 IDirectDraw7
*ddraw
;
2653 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2654 0, 0, 100, 100, 0, 0, 0, 0);
2655 ddraw
= create_ddraw();
2656 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2657 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2658 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2660 surface_desc
.dwSize
= sizeof(surface_desc
);
2661 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
2662 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2664 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2665 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2666 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2668 GetWindowRect(window
, &q
);
2672 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2673 GetWindowRect(window
, &s
);
2674 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2676 hr
= IDirectDraw7_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2677 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2678 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2680 GetWindowRect(window
, &s
);
2681 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2682 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2684 ref
= IDirectDraw7_Release(ddraw
);
2685 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2687 DestroyWindow(window
);
2690 static SIZE screen_size
, screen_size2
;
2692 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2694 if (message
== WM_SIZE
)
2696 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2697 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2700 return test_proc(hwnd
, message
, wparam
, lparam
);
2703 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2705 if (message
== WM_SIZE
)
2707 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2708 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2711 return test_proc(hwnd
, message
, wparam
, lparam
);
2714 struct test_coop_level_mode_set_enum_param
2716 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2719 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
2721 struct test_coop_level_mode_set_enum_param
*param
= context
;
2723 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2724 return DDENUMRET_OK
;
2725 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2726 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2727 return DDENUMRET_OK
;
2729 if (!param
->ddraw_width
)
2731 param
->ddraw_width
= surface_desc
->dwWidth
;
2732 param
->ddraw_height
= surface_desc
->dwHeight
;
2733 return DDENUMRET_OK
;
2735 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2736 return DDENUMRET_OK
;
2738 param
->user32_width
= surface_desc
->dwWidth
;
2739 param
->user32_height
= surface_desc
->dwHeight
;
2740 return DDENUMRET_CANCEL
;
2743 static void test_coop_level_mode_set(void)
2745 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2746 unsigned int display_count
= 0;
2747 IDirectDrawSurface7
*primary
;
2748 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2749 IDirectDraw7
*ddraw
;
2750 DDSURFACEDESC2 ddsd
;
2752 HWND window
, window2
;
2756 struct test_coop_level_mode_set_enum_param param
;
2760 static const struct message exclusive_messages
[] =
2762 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2763 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2764 {WM_SIZE
, FALSE
, 0},
2765 {WM_DISPLAYCHANGE
, FALSE
, 0},
2768 static const struct message exclusive_focus_loss_messages
[] =
2770 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
, DD_OK
},
2771 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DD_OK
}, /* Window resize due to mode change. */
2772 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DD_OK
},
2773 {WM_SIZE
, TRUE
, SIZE_RESTORED
, DD_OK
}, /* Generated by DefWindowProc. */
2774 {WM_DISPLAYCHANGE
, FALSE
, 0, DD_OK
},
2775 {WM_KILLFOCUS
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2776 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
}, /* Window minimized. */
2777 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2778 * SW_MINIMIZED, causing a recursive window activation that does not
2779 * produce the same result in Wine yet. Ignore the difference for now.
2780 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2781 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2782 {WM_MOVE
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2783 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
, DDERR_NOEXCLUSIVEMODE
},
2784 {WM_ACTIVATEAPP
, TRUE
, FALSE
, DDERR_NOEXCLUSIVEMODE
},
2787 static const struct message exclusive_focus_restore_messages
[] =
2789 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2790 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2791 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2792 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2793 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2794 /* Native redundantly sets the window size here. */
2795 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2796 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2797 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2798 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2801 static const struct message sc_restore_messages
[] =
2803 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2804 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2805 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2806 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2809 static const struct message sc_minimize_messages
[] =
2811 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2812 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2813 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2814 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2817 static const struct message sc_maximize_messages
[] =
2819 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2820 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2821 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2822 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2826 static const struct message normal_messages
[] =
2828 {WM_DISPLAYCHANGE
, FALSE
, 0},
2832 memset(&devmode
, 0, sizeof(devmode
));
2833 devmode
.dmSize
= sizeof(devmode
);
2834 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2835 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2836 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2837 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
2838 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
2839 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2841 ret
= save_display_modes(&original_modes
, &display_count
);
2842 ok(ret
, "Failed to save original display modes.\n");
2844 ddraw
= create_ddraw();
2845 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2847 memset(¶m
, 0, sizeof(param
));
2848 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2849 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2850 ref
= IDirectDraw7_Release(ddraw
);
2851 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2853 if (!param
.user32_height
)
2855 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2856 heap_free(original_modes
);
2860 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2861 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2862 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2864 memset(&devmode
, 0, sizeof(devmode
));
2865 devmode
.dmSize
= sizeof(devmode
);
2866 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2867 devmode
.dmPelsWidth
= param
.user32_width
;
2868 devmode
.dmPelsHeight
= param
.user32_height
;
2869 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2870 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2872 ddraw
= create_ddraw();
2873 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2875 wc
.lpfnWndProc
= mode_set_proc
;
2876 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2877 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2878 wc
.lpfnWndProc
= mode_set_proc2
;
2879 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2880 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2882 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2883 0, 0, 100, 100, 0, 0, 0, 0);
2884 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2885 0, 0, 100, 100, 0, 0, 0, 0);
2887 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2888 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2890 GetWindowRect(window
, &r
);
2891 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2892 wine_dbgstr_rect(&r
));
2894 memset(&ddsd
, 0, sizeof(ddsd
));
2895 ddsd
.dwSize
= sizeof(ddsd
);
2896 ddsd
.dwFlags
= DDSD_CAPS
;
2897 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2899 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2900 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2901 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2902 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2903 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2904 param
.user32_width
, ddsd
.dwWidth
);
2905 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2906 param
.user32_height
, ddsd
.dwHeight
);
2908 GetWindowRect(window
, &r
);
2909 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2910 wine_dbgstr_rect(&r
));
2912 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2913 expect_messages
= exclusive_messages
;
2917 hr
= IDirectDrawSurface7_IsLost(primary
);
2918 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2919 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2920 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2921 hr
= IDirectDrawSurface7_IsLost(primary
);
2922 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2924 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2925 expect_messages
= NULL
;
2926 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2927 "Expected screen size %ux%u, got %ux%u.\n",
2928 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2930 GetWindowRect(window
, &r
);
2931 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2932 wine_dbgstr_rect(&r
));
2934 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2935 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2936 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2937 param
.user32_width
, ddsd
.dwWidth
);
2938 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2939 param
.user32_height
, ddsd
.dwHeight
);
2940 IDirectDrawSurface7_Release(primary
);
2942 memset(&ddsd
, 0, sizeof(ddsd
));
2943 ddsd
.dwSize
= sizeof(ddsd
);
2944 ddsd
.dwFlags
= DDSD_CAPS
;
2945 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2947 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2948 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2949 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
2950 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2951 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2952 param
.ddraw_width
, ddsd
.dwWidth
);
2953 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2954 param
.ddraw_height
, ddsd
.dwHeight
);
2956 GetWindowRect(window
, &r
);
2957 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2958 wine_dbgstr_rect(&r
));
2960 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2961 expect_messages
= exclusive_messages
;
2965 hr
= IDirectDrawSurface7_IsLost(primary
);
2966 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2967 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2968 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2969 hr
= IDirectDrawSurface7_IsLost(primary
);
2970 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2972 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2973 expect_messages
= NULL
;
2974 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2975 "Expected screen size %ux%u, got %ux%u.\n",
2976 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2978 GetWindowRect(window
, &r
);
2979 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2980 wine_dbgstr_rect(&r
));
2982 expect_messages
= exclusive_focus_loss_messages
;
2983 focus_test_ddraw
= ddraw
;
2984 ret
= SetForegroundWindow(GetDesktopWindow());
2985 ok(ret
, "Failed to set foreground window.\n");
2986 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2987 focus_test_ddraw
= NULL
;
2989 memset(&devmode
, 0, sizeof(devmode
));
2990 devmode
.dmSize
= sizeof(devmode
);
2991 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2992 ok(ret
, "Failed to get display mode.\n");
2993 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2994 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %ux%u.\n",
2995 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2997 expect_messages
= exclusive_focus_restore_messages
;
2998 ShowWindow(window
, SW_RESTORE
);
2999 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3001 GetWindowRect(window
, &r
);
3002 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3003 wine_dbgstr_rect(&r
));
3004 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3005 ok(ret
, "Failed to get display mode.\n");
3006 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3007 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %ux%u.\n",
3008 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3010 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3011 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3012 /* Normally the primary should be restored here. Unfortunately this causes the
3013 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3014 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3015 * the point of the GetSurfaceDesc call. */
3017 expect_messages
= sc_minimize_messages
;
3018 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3019 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3020 expect_messages
= NULL
;
3022 expect_messages
= sc_restore_messages
;
3023 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3024 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3025 expect_messages
= NULL
;
3027 expect_messages
= sc_maximize_messages
;
3028 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3029 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3030 expect_messages
= NULL
;
3032 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3033 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3035 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3036 expect_messages
= exclusive_messages
;
3040 hr
= IDirectDrawSurface7_IsLost(primary
);
3041 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3042 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3043 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3044 hr
= IDirectDrawSurface7_IsLost(primary
);
3045 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3047 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3048 expect_messages
= NULL
;
3049 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3050 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3051 "Expected screen size %ux%u, got %ux%u.\n",
3052 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3054 GetWindowRect(window
, &r
);
3055 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3056 wine_dbgstr_rect(&r
));
3058 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3059 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3060 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3061 param
.ddraw_width
, ddsd
.dwWidth
);
3062 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3063 param
.ddraw_height
, ddsd
.dwHeight
);
3064 IDirectDrawSurface7_Release(primary
);
3067 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3068 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3070 memset(&ddsd
, 0, sizeof(ddsd
));
3071 ddsd
.dwSize
= sizeof(ddsd
);
3072 ddsd
.dwFlags
= DDSD_CAPS
;
3073 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3075 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3076 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3077 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3078 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3079 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3080 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3081 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3082 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3084 GetWindowRect(window
, &r
);
3085 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3086 wine_dbgstr_rect(&r
));
3088 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3089 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3091 GetWindowRect(window
, &r
);
3092 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3093 wine_dbgstr_rect(&r
));
3095 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3096 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3097 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3098 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3099 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3100 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3101 IDirectDrawSurface7_Release(primary
);
3103 memset(&ddsd
, 0, sizeof(ddsd
));
3104 ddsd
.dwSize
= sizeof(ddsd
);
3105 ddsd
.dwFlags
= DDSD_CAPS
;
3106 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3108 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3109 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3110 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3111 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3112 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3113 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3114 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3115 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3117 GetWindowRect(window
, &r
);
3118 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3119 wine_dbgstr_rect(&r
));
3121 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3122 expect_messages
= normal_messages
;
3126 hr
= IDirectDrawSurface7_IsLost(primary
);
3127 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3128 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3129 devmode
.dmPelsWidth
= param
.user32_width
;
3130 devmode
.dmPelsHeight
= param
.user32_height
;
3131 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3132 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3133 hr
= IDirectDrawSurface7_IsLost(primary
);
3134 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3136 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3137 expect_messages
= NULL
;
3138 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3140 GetWindowRect(window
, &r
);
3141 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3142 wine_dbgstr_rect(&r
));
3144 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3145 expect_messages
= normal_messages
;
3149 hr
= IDirectDrawSurface7_Restore(primary
);
3150 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3151 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3152 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3153 hr
= IDirectDrawSurface7_Restore(primary
);
3154 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3155 hr
= IDirectDrawSurface7_IsLost(primary
);
3156 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3158 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3159 expect_messages
= NULL
;
3160 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3162 GetWindowRect(window
, &r
);
3163 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3164 wine_dbgstr_rect(&r
));
3166 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3167 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3168 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3169 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3170 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3171 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3172 IDirectDrawSurface7_Release(primary
);
3174 memset(&ddsd
, 0, sizeof(ddsd
));
3175 ddsd
.dwSize
= sizeof(ddsd
);
3176 ddsd
.dwFlags
= DDSD_CAPS
;
3177 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3179 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3180 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3181 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3182 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3183 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3184 param
.ddraw_width
, ddsd
.dwWidth
);
3185 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3186 param
.ddraw_height
, ddsd
.dwHeight
);
3188 GetWindowRect(window
, &r
);
3189 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3190 wine_dbgstr_rect(&r
));
3192 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3193 expect_messages
= normal_messages
;
3197 hr
= IDirectDrawSurface7_IsLost(primary
);
3198 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3199 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3200 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3201 hr
= IDirectDrawSurface7_IsLost(primary
);
3202 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3204 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3205 expect_messages
= NULL
;
3206 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3208 GetWindowRect(window
, &r
);
3209 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3210 wine_dbgstr_rect(&r
));
3212 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3213 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3214 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3215 param
.ddraw_width
, ddsd
.dwWidth
);
3216 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3217 param
.ddraw_height
, ddsd
.dwHeight
);
3218 IDirectDrawSurface7_Release(primary
);
3220 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3221 ok(ret
, "Failed to get display mode.\n");
3222 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3223 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3224 "Expected resolution %ux%u, got %ux%u.\n",
3225 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3226 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3227 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3228 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3230 memset(&ddsd
, 0, sizeof(ddsd
));
3231 ddsd
.dwSize
= sizeof(ddsd
);
3232 ddsd
.dwFlags
= DDSD_CAPS
;
3233 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3235 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3236 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3237 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3238 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3239 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3240 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3241 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3242 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3244 GetWindowRect(window
, &r
);
3245 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3246 wine_dbgstr_rect(&r
));
3248 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3249 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3250 * not DDSCL_FULLSCREEN. */
3251 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3252 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3254 GetWindowRect(window
, &r
);
3255 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3256 wine_dbgstr_rect(&r
));
3258 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3259 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3260 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3261 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3262 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3263 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3264 IDirectDrawSurface7_Release(primary
);
3266 memset(&ddsd
, 0, sizeof(ddsd
));
3267 ddsd
.dwSize
= sizeof(ddsd
);
3268 ddsd
.dwFlags
= DDSD_CAPS
;
3269 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3271 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3272 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3273 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3274 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3275 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3276 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3277 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3278 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3280 GetWindowRect(window
, &r
);
3281 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3282 wine_dbgstr_rect(&r
));
3284 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3285 expect_messages
= normal_messages
;
3289 hr
= IDirectDrawSurface7_IsLost(primary
);
3290 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3291 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3292 devmode
.dmPelsWidth
= param
.user32_width
;
3293 devmode
.dmPelsHeight
= param
.user32_height
;
3294 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3295 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3296 hr
= IDirectDrawSurface7_IsLost(primary
);
3297 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3299 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3300 expect_messages
= NULL
;
3301 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3303 GetWindowRect(window
, &r
);
3304 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3305 wine_dbgstr_rect(&r
));
3307 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3308 expect_messages
= normal_messages
;
3312 hr
= IDirectDrawSurface7_Restore(primary
);
3313 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3314 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3315 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3316 hr
= IDirectDrawSurface7_Restore(primary
);
3317 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3318 hr
= IDirectDrawSurface7_IsLost(primary
);
3319 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3321 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3322 expect_messages
= NULL
;
3323 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3325 GetWindowRect(window
, &r
);
3326 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3327 wine_dbgstr_rect(&r
));
3329 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3330 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3331 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3332 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3333 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3334 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3335 IDirectDrawSurface7_Release(primary
);
3337 memset(&ddsd
, 0, sizeof(ddsd
));
3338 ddsd
.dwSize
= sizeof(ddsd
);
3339 ddsd
.dwFlags
= DDSD_CAPS
;
3340 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3342 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3343 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3344 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3345 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3346 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3347 param
.ddraw_width
, ddsd
.dwWidth
);
3348 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3349 param
.ddraw_height
, ddsd
.dwHeight
);
3351 GetWindowRect(window
, &r
);
3352 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3353 wine_dbgstr_rect(&r
));
3355 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3356 expect_messages
= normal_messages
;
3360 hr
= IDirectDrawSurface7_IsLost(primary
);
3361 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3362 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3363 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3364 hr
= IDirectDrawSurface7_IsLost(primary
);
3365 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3367 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3368 expect_messages
= NULL
;
3369 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3371 GetWindowRect(window
, &r
);
3372 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3373 wine_dbgstr_rect(&r
));
3375 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3376 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3377 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3378 param
.ddraw_width
, ddsd
.dwWidth
);
3379 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3380 param
.ddraw_height
, ddsd
.dwHeight
);
3381 IDirectDrawSurface7_Release(primary
);
3383 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3384 ok(ret
, "Failed to get display mode.\n");
3385 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3386 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3387 "Expected resolution %ux%u, got %ux%u.\n",
3388 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3389 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3390 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3391 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3393 memset(&ddsd
, 0, sizeof(ddsd
));
3394 ddsd
.dwSize
= sizeof(ddsd
);
3395 ddsd
.dwFlags
= DDSD_CAPS
;
3396 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3398 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3399 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3400 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3401 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3402 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3403 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3404 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3405 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3406 IDirectDrawSurface7_Release(primary
);
3408 GetWindowRect(window
, &r
);
3409 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3410 wine_dbgstr_rect(&r
));
3412 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3413 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3414 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3415 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3416 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3418 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3419 expect_messages
= exclusive_messages
;
3423 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3424 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3426 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3427 expect_messages
= NULL
;
3428 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3429 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3430 "Expected screen size %ux%u, got %ux%u.\n",
3431 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3432 screen_size
.cx
, screen_size
.cy
);
3434 GetWindowRect(window
, &r
);
3435 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3436 wine_dbgstr_rect(&r
));
3438 memset(&ddsd
, 0, sizeof(ddsd
));
3439 ddsd
.dwSize
= sizeof(ddsd
);
3440 ddsd
.dwFlags
= DDSD_CAPS
;
3441 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3443 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3444 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3445 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3446 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3447 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3448 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3449 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3450 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3451 IDirectDrawSurface7_Release(primary
);
3453 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3454 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3455 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3456 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3457 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3459 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3460 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3462 memset(&ddsd
, 0, sizeof(ddsd
));
3463 ddsd
.dwSize
= sizeof(ddsd
);
3464 ddsd
.dwFlags
= DDSD_CAPS
;
3465 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3467 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3468 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3469 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3470 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3471 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3472 param
.ddraw_width
, ddsd
.dwWidth
);
3473 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3474 param
.ddraw_height
, ddsd
.dwHeight
);
3475 IDirectDrawSurface7_Release(primary
);
3477 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3478 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3480 /* If the window is changed at the same time, messages are sent to the new window. */
3481 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3482 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3483 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3484 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3486 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3487 expect_messages
= exclusive_messages
;
3490 screen_size2
.cx
= 0;
3491 screen_size2
.cy
= 0;
3493 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3494 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3496 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3497 expect_messages
= NULL
;
3498 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3499 screen_size
.cx
, screen_size
.cy
);
3500 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3501 "Expected screen size 2 %ux%u, got %ux%u.\n",
3502 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3504 GetWindowRect(window
, &r
);
3505 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3506 wine_dbgstr_rect(&r
));
3507 GetWindowRect(window2
, &r
);
3508 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3509 wine_dbgstr_rect(&r
));
3511 memset(&ddsd
, 0, sizeof(ddsd
));
3512 ddsd
.dwSize
= sizeof(ddsd
);
3513 ddsd
.dwFlags
= DDSD_CAPS
;
3514 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3516 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3517 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3518 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &ddsd
);
3519 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3520 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3521 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3522 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3523 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3524 IDirectDrawSurface7_Release(primary
);
3526 ref
= IDirectDraw7_Release(ddraw
);
3527 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3529 GetWindowRect(window
, &r
);
3530 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3531 wine_dbgstr_rect(&r
));
3533 ret
= restore_display_modes(original_modes
, display_count
);
3534 ok(ret
, "Failed to restore display modes.\n");
3536 /* Test that no mode restorations if no mode changes happened */
3537 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3538 devmode
.dmPelsWidth
= param
.user32_width
;
3539 devmode
.dmPelsHeight
= param
.user32_height
;
3540 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3541 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3543 ddraw
= create_ddraw();
3544 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3545 ref
= IDirectDraw7_Release(ddraw
);
3546 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3548 memset(&devmode2
, 0, sizeof(devmode2
));
3549 devmode2
.dmSize
= sizeof(devmode2
);
3550 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3551 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3552 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3553 ret
= restore_display_modes(original_modes
, display_count
);
3554 ok(ret
, "Failed to restore display modes.\n");
3556 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3557 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3558 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3560 ddraw
= create_ddraw();
3561 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3562 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3563 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3564 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3565 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3566 ref
= IDirectDraw7_Release(ddraw
);
3567 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3569 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3570 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3571 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3572 ret
= restore_display_modes(original_modes
, display_count
);
3573 ok(ret
, "Failed to restore display modes.\n");
3575 /* Test that mode restorations use display settings in the registry after ddraw object releases
3576 * if SetDisplayMode() was called */
3577 ddraw
= create_ddraw();
3578 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3579 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3580 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3582 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3583 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3585 ref
= IDirectDraw7_Release(ddraw
);
3586 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3588 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3589 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3590 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3591 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3592 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3593 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3594 ret
= restore_display_modes(original_modes
, display_count
);
3595 ok(ret
, "Failed to restore display modes.\n");
3597 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3598 ddraw
= create_ddraw();
3599 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3600 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3601 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3603 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3604 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %d.\n", change_ret
);
3606 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
3607 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
3609 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3610 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3611 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3612 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3613 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3614 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3616 ref
= IDirectDraw7_Release(ddraw
);
3617 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3619 expect_messages
= NULL
;
3620 DestroyWindow(window
);
3621 DestroyWindow(window2
);
3622 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3623 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3624 ret
= restore_display_modes(original_modes
, display_count
);
3625 ok(ret
, "Failed to restore display modes.\n");
3626 heap_free(original_modes
);
3629 static void test_coop_level_mode_set_multi(void)
3631 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3632 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3633 WCHAR second_monitor_name
[CCHDEVICENAME
];
3634 IDirectDraw7
*ddraw1
, *ddraw2
;
3642 memset(&devmode
, 0, sizeof(devmode
));
3643 devmode
.dmSize
= sizeof(devmode
);
3644 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3645 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3646 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3647 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3648 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3649 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3651 ret
= save_display_modes(&original_modes
, &display_count
);
3652 ok(ret
, "Failed to save original display modes.\n");
3654 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3655 0, 0, 100, 100, 0, 0, 0, 0);
3656 ddraw1
= create_ddraw();
3657 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3659 /* With just a single ddraw object, the display mode is restored on
3661 hr
= set_display_mode(ddraw1
, 800, 600);
3662 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3663 w
= GetSystemMetrics(SM_CXSCREEN
);
3664 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3665 h
= GetSystemMetrics(SM_CYSCREEN
);
3666 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3668 ref
= IDirectDraw7_Release(ddraw1
);
3669 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3670 w
= GetSystemMetrics(SM_CXSCREEN
);
3671 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3672 h
= GetSystemMetrics(SM_CYSCREEN
);
3673 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3675 /* When there are multiple ddraw objects, the display mode is restored to
3676 * the initial mode, before the first SetDisplayMode() call. */
3677 ddraw1
= create_ddraw();
3678 hr
= set_display_mode(ddraw1
, 800, 600);
3679 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3680 w
= GetSystemMetrics(SM_CXSCREEN
);
3681 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3682 h
= GetSystemMetrics(SM_CYSCREEN
);
3683 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3685 ddraw2
= create_ddraw();
3686 hr
= set_display_mode(ddraw2
, 640, 480);
3687 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3688 w
= GetSystemMetrics(SM_CXSCREEN
);
3689 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3690 h
= GetSystemMetrics(SM_CYSCREEN
);
3691 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3693 ref
= IDirectDraw7_Release(ddraw2
);
3694 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3695 w
= GetSystemMetrics(SM_CXSCREEN
);
3696 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3697 h
= GetSystemMetrics(SM_CYSCREEN
);
3698 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3700 ref
= IDirectDraw7_Release(ddraw1
);
3701 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3702 w
= GetSystemMetrics(SM_CXSCREEN
);
3703 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3704 h
= GetSystemMetrics(SM_CYSCREEN
);
3705 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3707 /* Regardless of release ordering. */
3708 ddraw1
= create_ddraw();
3709 hr
= set_display_mode(ddraw1
, 800, 600);
3710 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3711 w
= GetSystemMetrics(SM_CXSCREEN
);
3712 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3713 h
= GetSystemMetrics(SM_CYSCREEN
);
3714 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3716 ddraw2
= create_ddraw();
3717 hr
= set_display_mode(ddraw2
, 640, 480);
3718 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3719 w
= GetSystemMetrics(SM_CXSCREEN
);
3720 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3721 h
= GetSystemMetrics(SM_CYSCREEN
);
3722 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3724 ref
= IDirectDraw7_Release(ddraw1
);
3725 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3726 w
= GetSystemMetrics(SM_CXSCREEN
);
3727 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3728 h
= GetSystemMetrics(SM_CYSCREEN
);
3729 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3731 ref
= IDirectDraw7_Release(ddraw2
);
3732 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3733 w
= GetSystemMetrics(SM_CXSCREEN
);
3734 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3735 h
= GetSystemMetrics(SM_CYSCREEN
);
3736 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3738 /* But only for ddraw objects that called SetDisplayMode(). */
3739 ddraw1
= create_ddraw();
3740 ddraw2
= create_ddraw();
3741 hr
= set_display_mode(ddraw2
, 640, 480);
3742 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3743 w
= GetSystemMetrics(SM_CXSCREEN
);
3744 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3745 h
= GetSystemMetrics(SM_CYSCREEN
);
3746 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3748 ref
= IDirectDraw7_Release(ddraw1
);
3749 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3750 w
= GetSystemMetrics(SM_CXSCREEN
);
3751 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3752 h
= GetSystemMetrics(SM_CYSCREEN
);
3753 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3755 ref
= IDirectDraw7_Release(ddraw2
);
3756 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3757 w
= GetSystemMetrics(SM_CXSCREEN
);
3758 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3759 h
= GetSystemMetrics(SM_CYSCREEN
);
3760 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3762 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3763 * restoring the display mode. */
3764 ddraw1
= create_ddraw();
3765 hr
= set_display_mode(ddraw1
, 800, 600);
3766 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3767 w
= GetSystemMetrics(SM_CXSCREEN
);
3768 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3769 h
= GetSystemMetrics(SM_CYSCREEN
);
3770 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3772 ddraw2
= create_ddraw();
3773 hr
= set_display_mode(ddraw2
, 640, 480);
3774 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3775 w
= GetSystemMetrics(SM_CXSCREEN
);
3776 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3777 h
= GetSystemMetrics(SM_CYSCREEN
);
3778 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3780 hr
= IDirectDraw7_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3781 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3783 ref
= IDirectDraw7_Release(ddraw1
);
3784 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3785 w
= GetSystemMetrics(SM_CXSCREEN
);
3786 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3787 h
= GetSystemMetrics(SM_CYSCREEN
);
3788 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3790 ref
= IDirectDraw7_Release(ddraw2
);
3791 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3792 w
= GetSystemMetrics(SM_CXSCREEN
);
3793 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3794 h
= GetSystemMetrics(SM_CYSCREEN
);
3795 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3797 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3798 ddraw1
= create_ddraw();
3799 hr
= set_display_mode(ddraw1
, 800, 600);
3800 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3801 w
= GetSystemMetrics(SM_CXSCREEN
);
3802 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3803 h
= GetSystemMetrics(SM_CYSCREEN
);
3804 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3806 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3807 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3809 ddraw2
= create_ddraw();
3810 hr
= set_display_mode(ddraw2
, 640, 480);
3811 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3813 ref
= IDirectDraw7_Release(ddraw1
);
3814 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3815 w
= GetSystemMetrics(SM_CXSCREEN
);
3816 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3817 h
= GetSystemMetrics(SM_CYSCREEN
);
3818 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3820 ref
= IDirectDraw7_Release(ddraw2
);
3821 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3822 w
= GetSystemMetrics(SM_CXSCREEN
);
3823 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3824 h
= GetSystemMetrics(SM_CYSCREEN
);
3825 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3827 if (display_count
< 2)
3829 skip("Following tests require two monitors.\n");
3833 ret
= restore_display_modes(original_modes
, display_count
);
3834 ok(ret
, "Failed to restore display modes.\n");
3836 second_monitor_name
[0] = '\0';
3837 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
3839 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
3841 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
3845 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
3846 memset(&old_devmode
, 0, sizeof(old_devmode
));
3847 old_devmode
.dmSize
= sizeof(old_devmode
);
3848 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
3849 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3851 devmode
= old_devmode
;
3852 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
3854 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3855 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
3858 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3859 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
3860 "Failed to find a different mode for the second monitor.\n");
3862 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
3863 ddraw1
= create_ddraw();
3864 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3865 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3866 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3868 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3869 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3871 memset(&devmode2
, 0, sizeof(devmode2
));
3872 devmode2
.dmSize
= sizeof(devmode2
);
3873 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3874 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3875 if (compare_mode_rect(&devmode2
, &old_devmode
))
3877 skip("Failed to change display settings of the second monitor.\n");
3878 ref
= IDirectDraw7_Release(ddraw1
);
3879 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3883 hr
= IDirectDraw7_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
3884 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
3885 ref
= IDirectDraw7_Release(ddraw1
);
3886 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3888 memset(&devmode3
, 0, sizeof(devmode3
));
3889 devmode3
.dmSize
= sizeof(devmode3
);
3890 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
3891 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3892 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
3893 ret
= restore_display_modes(original_modes
, display_count
);
3894 ok(ret
, "Failed to restore display modes.\n");
3896 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
3897 * SetDisplayMode() was called */
3898 ddraw1
= create_ddraw();
3899 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3900 hr
= set_display_mode(ddraw1
, 800, 600);
3901 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3903 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3904 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3906 ref
= IDirectDraw7_Release(ddraw1
);
3907 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3909 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3910 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3911 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3912 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3913 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3914 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3915 ret
= restore_display_modes(original_modes
, display_count
);
3916 ok(ret
, "Failed to restore display modes.\n");
3918 /* Test that mode restorations happen for non-primary monitors as well */
3919 ddraw1
= create_ddraw();
3920 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3921 hr
= set_display_mode(ddraw1
, 800, 600);
3922 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3924 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3925 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3927 hr
= IDirectDraw7_RestoreDisplayMode(ddraw1
);
3928 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
3930 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3931 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3932 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3933 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3934 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3935 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3937 ref
= IDirectDraw7_Release(ddraw1
);
3938 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3939 ret
= restore_display_modes(original_modes
, display_count
);
3940 ok(ret
, "Failed to restore display modes.\n");
3942 /* Test that mode restorations for non-primary monitors use display settings in the registry */
3943 ddraw1
= create_ddraw();
3944 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3945 hr
= set_display_mode(ddraw1
, 800, 600);
3946 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3948 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
3949 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
3950 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3952 ref
= IDirectDraw7_Release(ddraw1
);
3953 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3955 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3956 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3957 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
3958 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
3959 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
3960 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3961 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3962 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
3963 "Expected resolution %ux%u, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
3964 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
3965 ret
= restore_display_modes(original_modes
, display_count
);
3966 ok(ret
, "Failed to restore display modes.\n");
3968 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
3969 * objects and one of them restores display mode */
3970 ddraw1
= create_ddraw();
3971 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3972 ddraw2
= create_ddraw();
3973 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
3974 hr
= set_display_mode(ddraw1
, 800, 600);
3975 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3976 hr
= set_display_mode(ddraw2
, 640, 480);
3977 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
3979 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3980 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
3982 hr
= IDirectDraw7_RestoreDisplayMode(ddraw2
);
3983 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
3985 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3986 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3987 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3988 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3989 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
3990 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3992 ref
= IDirectDraw7_Release(ddraw2
);
3993 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3994 ref
= IDirectDraw7_Release(ddraw1
);
3995 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3996 ret
= restore_display_modes(original_modes
, display_count
);
3997 ok(ret
, "Failed to restore display modes.\n");
3999 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4000 * objects and one of them got released */
4001 ddraw1
= create_ddraw();
4002 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4003 ddraw2
= create_ddraw();
4004 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4005 hr
= set_display_mode(ddraw1
, 800, 600);
4006 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4007 hr
= set_display_mode(ddraw2
, 640, 480);
4008 ok(hr
== DD_OK
, "Failed to set display mode, hr %#x.\n", hr
);
4010 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4011 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %d.\n", change_ret
);
4013 ref
= IDirectDraw7_Release(ddraw2
);
4014 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4016 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4017 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4018 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4019 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4020 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
4021 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4023 ref
= IDirectDraw7_Release(ddraw1
);
4024 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
4027 DestroyWindow(window
);
4028 ret
= restore_display_modes(original_modes
, display_count
);
4029 ok(ret
, "Failed to restore display modes.\n");
4030 heap_free(original_modes
);
4033 static void test_initialize(void)
4035 IDirectDraw7
*ddraw
;
4038 ddraw
= create_ddraw();
4039 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4041 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4042 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
4043 IDirectDraw7_Release(ddraw
);
4046 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw7
, (void **)&ddraw
);
4047 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr
);
4048 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4049 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
4050 hr
= IDirectDraw7_Initialize(ddraw
, NULL
);
4051 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4052 IDirectDraw7_Release(ddraw
);
4056 static void test_coop_level_surf_create(void)
4058 IDirectDrawSurface7
*surface
;
4059 IDirectDraw7
*ddraw
;
4060 DDSURFACEDESC2 ddsd
;
4063 ddraw
= create_ddraw();
4064 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4066 memset(&ddsd
, 0, sizeof(ddsd
));
4067 ddsd
.dwSize
= sizeof(ddsd
);
4068 ddsd
.dwFlags
= DDSD_CAPS
;
4069 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4070 surface
= (void *)0xdeadbeef;
4071 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4072 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4073 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4075 surface
= (void *)0xdeadbeef;
4076 hr
= IDirectDraw7_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4077 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
4078 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4080 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4081 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4083 surface
= (void *)0xdeadbeef;
4084 hr
= IDirectDraw7_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4085 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
4086 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4088 IDirectDraw7_Release(ddraw
);
4091 static void test_vb_discard(void)
4093 static const struct vec4 quad
[] =
4095 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
4096 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
4097 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
4098 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
4101 IDirect3DDevice7
*device
;
4103 IDirect3DVertexBuffer7
*buffer
;
4106 D3DVERTEXBUFFERDESC desc
;
4108 static const unsigned int vbsize
= 16;
4111 window
= create_window();
4112 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4114 skip("Failed to create a 3D device, skipping test.\n");
4115 DestroyWindow(window
);
4119 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
4120 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
4122 memset(&desc
, 0, sizeof(desc
));
4123 desc
.dwSize
= sizeof(desc
);
4124 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
4125 desc
.dwFVF
= D3DFVF_XYZRHW
;
4126 desc
.dwNumVertices
= vbsize
;
4127 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0);
4128 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
4130 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4131 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4132 memcpy(data
, quad
, sizeof(quad
));
4133 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4134 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4136 hr
= IDirect3DDevice7_BeginScene(device
);
4137 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4138 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
4139 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4140 hr
= IDirect3DDevice7_EndScene(device
);
4141 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4143 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4144 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4145 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
4146 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4147 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4149 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4150 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
4151 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
4153 if (data
[i
] != 0xaa)
4155 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
4159 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
4160 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
4162 IDirect3DVertexBuffer7_Release(buffer
);
4163 IDirect3D7_Release(d3d
);
4164 IDirect3DDevice7_Release(device
);
4165 DestroyWindow(window
);
4168 static void test_coop_level_multi_window(void)
4170 HWND window1
, window2
;
4171 IDirectDraw7
*ddraw
;
4174 window1
= create_window();
4175 window2
= create_window();
4176 ddraw
= create_ddraw();
4177 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4179 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4180 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4181 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4182 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4183 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4184 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4186 IDirectDraw7_Release(ddraw
);
4187 DestroyWindow(window2
);
4188 DestroyWindow(window1
);
4191 static void test_draw_strided(void)
4193 static struct vec3 position
[] =
4200 static DWORD diffuse
[] =
4202 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
4204 static WORD indices
[] =
4209 IDirectDrawSurface7
*rt
;
4210 IDirect3DDevice7
*device
;
4214 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
4216 window
= create_window();
4217 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4219 skip("Failed to create a 3D device, skipping test.\n");
4220 DestroyWindow(window
);
4224 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
4225 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4227 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4228 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4229 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 1.0f
, 0);
4230 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
4231 hr
= IDirect3DDevice7_BeginScene(device
);
4232 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4234 memset(&strided
, 0x55, sizeof(strided
));
4235 strided
.position
.lpvData
= position
;
4236 strided
.position
.dwStride
= sizeof(*position
);
4237 strided
.diffuse
.lpvData
= diffuse
;
4238 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
4239 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
4240 &strided
, 4, indices
, 6, 0);
4241 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4243 hr
= IDirect3DDevice7_EndScene(device
);
4244 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4246 color
= get_surface_color(rt
, 320, 240);
4247 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4249 IDirectDrawSurface7_Release(rt
);
4250 IDirect3DDevice7_Release(device
);
4251 DestroyWindow(window
);
4254 static void test_lighting(void)
4256 static D3DMATRIX mat
=
4258 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4259 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4260 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4261 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4265 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4266 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4267 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4268 0.0f
, 0.0f
, 0.5f
, 1.0f
,
4272 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4273 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4274 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
4275 10.f
, 10.0f
, 10.0f
, 1.0f
,
4279 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4280 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4281 0.0f
, 0.0f
, 1.0f
, -1.0f
,
4282 10.f
, 10.0f
, 10.0f
, 0.0f
,
4284 static struct vertex
4286 struct vec3 position
;
4291 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4292 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4293 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4294 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4298 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4299 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4300 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4301 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4303 static struct vertex_normal
4305 struct vec3 position
;
4311 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4312 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4313 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4314 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4318 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4319 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4320 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4321 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4325 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4326 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4327 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4328 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4332 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4333 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4334 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4335 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4339 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4340 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4341 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4342 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4344 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
4347 D3DMATRIX
*world_matrix
;
4349 DWORD expected
, expected_process_vertices
;
4350 const char *message
;
4351 BOOL process_vertices_todo
;
4355 {&mat
, nquad
, 0x000000ff, 0xff0000ff, "Lit quad with light"},
4356 {&mat_singular
, nquad
, 0x000000ff, 0xff000000, "Lit quad with singular world matrix", TRUE
},
4357 {&mat_transf
, rotatedquad
, 0x000000ff, 0xff0000ff, "Lit quad with transformation matrix"},
4358 {&mat_nonaffine
, translatedquad
, 0x00000000, 0xff000000, "Lit quad with non-affine matrix"},
4361 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
4362 IDirect3DVertexBuffer7
*src_vb1
, *src_vb2
, *dst_vb
;
4363 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
4364 struct vertex_normal
*src_data2
;
4365 D3DVERTEXBUFFERDESC vb_desc
;
4366 struct vertex
*src_data1
;
4367 IDirect3DDevice7
*device
;
4368 IDirectDrawSurface7
*rt
;
4369 IDirectDraw7
*ddraw
;
4379 struct vec4 position
;
4385 window
= create_window();
4386 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4388 skip("Failed to create a 3D device, skipping test.\n");
4389 DestroyWindow(window
);
4392 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
4393 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4394 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
4395 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4397 is_warp
= ddraw_is_warp(ddraw
);
4399 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
4400 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4402 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
4403 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4405 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4406 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4407 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4408 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4409 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4410 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4411 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
4412 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4413 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4414 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4415 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4416 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4417 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
4418 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4419 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
4420 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4422 hr
= IDirect3DDevice7_BeginScene(device
);
4423 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4425 memset(&vb_desc
, 0, sizeof(vb_desc
));
4426 vb_desc
.dwSize
= sizeof(vb_desc
);
4427 vb_desc
.dwFVF
= fvf
;
4428 vb_desc
.dwNumVertices
= 2;
4429 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb1
, 0);
4430 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4431 vb_desc
.dwSize
= sizeof(vb_desc
);
4432 vb_desc
.dwFVF
= nfvf
;
4433 vb_desc
.dwNumVertices
= 2;
4434 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb2
, 0);
4435 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4437 memset(&vb_desc
, 0, sizeof(vb_desc
));
4438 vb_desc
.dwSize
= sizeof(vb_desc
);
4439 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4440 vb_desc
.dwNumVertices
= 4;
4441 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
4442 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4444 hr
= IDirect3DVertexBuffer7_Lock(src_vb1
, 0, (void **)&src_data1
, NULL
);
4445 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4446 memcpy(src_data1
, unlitquad
, sizeof(*src_data1
));
4447 memcpy(&src_data1
[1], litquad
, sizeof(*src_data1
));
4448 hr
= IDirect3DVertexBuffer7_Unlock(src_vb1
);
4449 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4451 hr
= IDirect3DVertexBuffer7_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4452 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4453 memcpy(src_data2
, unlitnquad
, sizeof(*src_data2
));
4454 memcpy(&src_data2
[1], litnquad
, sizeof(*src_data2
));
4455 hr
= IDirect3DVertexBuffer7_Unlock(src_vb2
);
4456 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4458 /* No lights are defined... That means, lit vertices should be entirely black. */
4459 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4460 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4461 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0,
4462 1, src_vb1
, 0, device
, 0);
4463 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4464 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
4466 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4468 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4469 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4470 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 1,
4471 1, src_vb1
, 1, device
, 0);
4472 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4473 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4475 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4477 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4478 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4479 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 2,
4480 1, src_vb2
, 0, device
, 0);
4481 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4482 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4484 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4486 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4487 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4488 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 3,
4489 1, src_vb2
, 1, device
, 0);
4490 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4491 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4493 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4495 hr
= IDirect3DDevice7_EndScene(device
);
4496 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4498 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4499 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4501 color
= get_surface_color(rt
, 160, 360);
4502 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color
);
4503 ok(dst_data
[0].diffuse
== 0xffff0000,
4504 "Unlit quad without normals has color 0x%08x, expected 0xffff0000.\n", dst_data
[0].diffuse
);
4505 ok(!dst_data
[0].specular
,
4506 "Unexpected specular color 0x%08x.\n", dst_data
[0].specular
);
4507 color
= get_surface_color(rt
, 160, 120);
4508 /* Broken on some of WARP drivers. */
4509 ok(color
== 0x00000000 || broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4510 "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color
);
4511 ok(dst_data
[1].diffuse
== 0xff000000,
4512 "Lit quad without normals has color 0x%08x, expected 0xff000000.\n", dst_data
[1].diffuse
);
4513 ok(!dst_data
[1].specular
,
4514 "Unexpected specular color 0x%08x.\n", dst_data
[1].specular
);
4515 color
= get_surface_color(rt
, 480, 360);
4516 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color
);
4517 ok(dst_data
[2].diffuse
== 0xff0000ff,
4518 "Unlit quad with normals has color 0x%08x, expected 0xff0000ff.\n", dst_data
[2].diffuse
);
4519 ok(!dst_data
[2].specular
,
4520 "Unexpected specular color 0x%08x.\n", dst_data
[2].specular
);
4521 color
= get_surface_color(rt
, 480, 120);
4522 ok(color
== 0x00000000 || broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4523 "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color
);
4524 ok(dst_data
[3].diffuse
== 0xff000000,
4525 "Lit quad with normals has color 0x%08x, expected 0xff000000.\n", dst_data
[3].diffuse
);
4526 ok(!dst_data
[3].specular
,
4527 "Unexpected specular color 0x%08x.\n", dst_data
[3].specular
);
4529 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
4530 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4532 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
4533 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4535 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4537 hr
= IDirect3DVertexBuffer7_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4538 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4539 memcpy(src_data2
, tests
[i
].quad
, sizeof(*src_data2
));
4540 hr
= IDirect3DVertexBuffer7_Unlock(src_vb2
);
4541 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4543 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
4544 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4546 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
4547 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4549 hr
= IDirect3DDevice7_BeginScene(device
);
4550 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4552 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
4553 1, src_vb2
, 0, device
, 0);
4554 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4556 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
4558 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4560 hr
= IDirect3DDevice7_EndScene(device
);
4561 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4563 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4564 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4566 color
= get_surface_color(rt
, 320, 240);
4567 ok(color
== tests
[i
].expected
|| broken(is_warp
&& (color
== 0x000000ff || color
== 0x00ff00ff)),
4568 "%s has color 0x%08x.\n", tests
[i
].message
, color
);
4569 todo_wine_if(tests
[i
].process_vertices_todo
)
4570 ok(dst_data
[0].diffuse
== tests
[i
].expected_process_vertices
,
4571 "%s has color 0x%08x.\n", tests
[i
].message
, dst_data
[0].diffuse
);
4572 ok(!dst_data
[0].specular
,
4573 "%s has specular color 0x%08x.\n", tests
[i
].message
, dst_data
[0].specular
);
4575 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
4576 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4579 IDirect3DVertexBuffer7_Release(src_vb1
);
4580 IDirect3DVertexBuffer7_Release(src_vb2
);
4581 IDirect3DVertexBuffer7_Release(dst_vb
);
4583 IDirectDrawSurface7_Release(rt
);
4585 IDirectDraw7_Release(ddraw
);
4586 IDirect3D7_Release(d3d
);
4587 refcount
= IDirect3DDevice7_Release(device
);
4588 ok(!refcount
, "Device has %u references left.\n", refcount
);
4589 DestroyWindow(window
);
4592 static void test_specular_lighting(void)
4594 static const unsigned int vertices_side
= 5;
4595 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
4596 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
4597 static D3DMATRIX mat
=
4599 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4600 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4601 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4602 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4604 static const struct vertex
4606 struct vec3 position
;
4611 {{-0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4612 {{ 0.0f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4613 {{ 0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4614 {{-0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4615 {{ 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4616 {{ 0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4617 {{-0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4618 {{ 0.0f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4619 {{ 0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4622 static D3DLIGHT7 directional
=
4624 D3DLIGHT_DIRECTIONAL
,
4625 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4626 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4627 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4628 {{0.0f
}, {0.0f
}, {0.0f
}},
4629 {{0.0f
}, {0.0f
}, {1.0f
}},
4634 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4635 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4636 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4637 {{0.0f
}, {0.0f
}, {0.0f
}},
4638 {{0.0f
}, {0.0f
}, {0.0f
}},
4646 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4647 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4648 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4649 {{0.0f
}, {0.0f
}, {0.0f
}},
4650 {{0.0f
}, {0.0f
}, {1.0f
}},
4654 M_PI
/ 12.0f
, M_PI
/ 3.0f
4656 /* The chosen range value makes the test fail when using a manhattan
4657 * distance metric vs the correct euclidean distance. */
4661 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4662 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4663 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4664 {{0.0f
}, {0.0f
}, {0.0f
}},
4665 {{0.0f
}, {0.0f
}, {0.0f
}},
4673 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4674 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4675 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
4676 {{-1.1f
}, {0.0f
}, {1.1f
}},
4677 {{0.0f
}, {0.0f
}, {0.0f
}},
4682 static const struct expected_color
4687 expected_directional
[] =
4689 {160, 120, 0x00ffffff},
4690 {320, 120, 0x00ffffff},
4691 {480, 120, 0x00ffffff},
4692 {160, 240, 0x00ffffff},
4693 {320, 240, 0x00ffffff},
4694 {480, 240, 0x00ffffff},
4695 {160, 360, 0x00ffffff},
4696 {320, 360, 0x00ffffff},
4697 {480, 360, 0x00ffffff},
4699 expected_directional_local
[] =
4701 {160, 120, 0x003c3c3c},
4702 {320, 120, 0x00717171},
4703 {480, 120, 0x003c3c3c},
4704 {160, 240, 0x00717171},
4705 {320, 240, 0x00ffffff},
4706 {480, 240, 0x00717171},
4707 {160, 360, 0x003c3c3c},
4708 {320, 360, 0x00717171},
4709 {480, 360, 0x003c3c3c},
4713 {160, 120, 0x00282828},
4714 {320, 120, 0x005a5a5a},
4715 {480, 120, 0x00282828},
4716 {160, 240, 0x005a5a5a},
4717 {320, 240, 0x00ffffff},
4718 {480, 240, 0x005a5a5a},
4719 {160, 360, 0x00282828},
4720 {320, 360, 0x005a5a5a},
4721 {480, 360, 0x00282828},
4723 expected_point_local
[] =
4725 {160, 120, 0x00000000},
4726 {320, 120, 0x00070707},
4727 {480, 120, 0x00000000},
4728 {160, 240, 0x00070707},
4729 {320, 240, 0x00ffffff},
4730 {480, 240, 0x00070707},
4731 {160, 360, 0x00000000},
4732 {320, 360, 0x00070707},
4733 {480, 360, 0x00000000},
4737 {160, 120, 0x00000000},
4738 {320, 120, 0x00141414},
4739 {480, 120, 0x00000000},
4740 {160, 240, 0x00141414},
4741 {320, 240, 0x00ffffff},
4742 {480, 240, 0x00141414},
4743 {160, 360, 0x00000000},
4744 {320, 360, 0x00141414},
4745 {480, 360, 0x00000000},
4747 expected_spot_local
[] =
4749 {160, 120, 0x00000000},
4750 {320, 120, 0x00020202},
4751 {480, 120, 0x00000000},
4752 {160, 240, 0x00020202},
4753 {320, 240, 0x00ffffff},
4754 {480, 240, 0x00020202},
4755 {160, 360, 0x00000000},
4756 {320, 360, 0x00020202},
4757 {480, 360, 0x00000000},
4759 expected_point_range
[] =
4761 {160, 120, 0x00000000},
4762 {320, 120, 0x005a5a5a},
4763 {480, 120, 0x00000000},
4764 {160, 240, 0x005a5a5a},
4765 {320, 240, 0x00ffffff},
4766 {480, 240, 0x005a5a5a},
4767 {160, 360, 0x00000000},
4768 {320, 360, 0x005a5a5a},
4769 {480, 360, 0x00000000},
4771 expected_point_side
[] =
4773 {160, 120, 0x00000000},
4774 {320, 120, 0x00000000},
4775 {480, 120, 0x00000000},
4776 {160, 240, 0x00000000},
4777 {320, 240, 0x00000000},
4778 {480, 240, 0x00000000},
4779 {160, 360, 0x00000000},
4780 {320, 360, 0x00000000},
4781 {480, 360, 0x00000000},
4783 expected_directional_local_0
[] =
4785 {160, 120, 0x00ffffff},
4786 {320, 120, 0x00ffffff},
4787 {480, 120, 0x00ffffff},
4788 {160, 240, 0x00ffffff},
4789 {320, 240, 0x00ffffff},
4790 {480, 240, 0x00ffffff},
4791 {160, 360, 0x00ffffff},
4792 {320, 360, 0x00ffffff},
4793 {480, 360, 0x00ffffff},
4795 expected_point_0
[] =
4797 {160, 120, 0x00aaaaaa},
4798 {320, 120, 0x00cccccc},
4799 {480, 120, 0x00aaaaaa},
4800 {160, 240, 0x00cccccc},
4801 {320, 240, 0x00ffffff},
4802 {480, 240, 0x00cccccc},
4803 {160, 360, 0x00aaaaaa},
4804 {320, 360, 0x00cccccc},
4805 {480, 360, 0x00aaaaaa},
4809 {160, 120, 0x00000000},
4810 {320, 120, 0x002e2e2e},
4811 {480, 120, 0x00000000},
4812 {160, 240, 0x002e2e2e},
4813 {320, 240, 0x00ffffff},
4814 {480, 240, 0x002e2e2e},
4815 {160, 360, 0x00000000},
4816 {320, 360, 0x002e2e2e},
4817 {480, 360, 0x00000000},
4819 expected_point_range_0
[] =
4821 {160, 120, 0x00000000},
4822 {320, 120, 0x00cccccc},
4823 {480, 120, 0x00000000},
4824 {160, 240, 0x00cccccc},
4825 {320, 240, 0x00ffffff},
4826 {480, 240, 0x00cccccc},
4827 {160, 360, 0x00000000},
4828 {320, 360, 0x00cccccc},
4829 {480, 360, 0x00000000},
4835 float specular_power
;
4836 const struct expected_color
*expected
, *expected_process_vertices
;
4837 unsigned int expected_count
;
4838 BOOL todo_process_vertices
;
4842 {&directional
, FALSE
, 30.0f
, expected_directional
, expected_directional
,
4843 ARRAY_SIZE(expected_directional
)},
4844 {&directional
, TRUE
, 30.0f
, expected_directional_local
, expected_directional_local
,
4845 ARRAY_SIZE(expected_directional_local
)},
4846 {&point
, FALSE
, 30.0f
, expected_point
, expected_point
, ARRAY_SIZE(expected_point
)},
4847 {&point
, TRUE
, 30.0f
, expected_point_local
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
4848 {&spot
, FALSE
, 30.0f
, expected_spot
, expected_spot
, ARRAY_SIZE(expected_spot
)},
4849 {&spot
, TRUE
, 30.0f
, expected_spot_local
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
4850 {&point_range
, FALSE
, 30.0f
, expected_point_range
, expected_point_range
,
4851 ARRAY_SIZE(expected_point_range
)},
4853 /* For zero material shininess _ProcessVertices() seem to keep non-zero material shininess set previously. */
4854 {&point_side
, TRUE
, 0.0f
, expected_point_side
, expected_point_side
, ARRAY_SIZE(expected_point_side
), TRUE
},
4855 {&directional
, FALSE
, 0.0f
, expected_directional
, expected_directional
,
4856 ARRAY_SIZE(expected_directional
), TRUE
},
4857 {&directional
, TRUE
, 0.0f
, expected_directional_local_0
, expected_directional_local
,
4858 ARRAY_SIZE(expected_directional_local_0
), TRUE
},
4859 {&point
, FALSE
, 0.0f
, expected_point_0
, expected_point
, ARRAY_SIZE(expected_point_0
), TRUE
},
4860 {&point
, TRUE
, 0.0f
, expected_point_0
, expected_point_local
, ARRAY_SIZE(expected_point_0
), TRUE
},
4861 {&spot
, FALSE
, 0.0f
, expected_spot_0
, expected_spot
, ARRAY_SIZE(expected_spot_0
), TRUE
},
4862 {&spot
, TRUE
, 0.0f
, expected_spot_0
, expected_spot_local
, ARRAY_SIZE(expected_spot_0
), TRUE
},
4863 {&point_range
, FALSE
, 0.0f
, expected_point_range_0
, expected_point_range
, ARRAY_SIZE(expected_point_range_0
), TRUE
},
4866 IDirect3DVertexBuffer7
*src_vb
, *dst_vb
;
4867 D3DCOLOR color
, expected_color
;
4868 D3DVERTEXBUFFERDESC vb_desc
;
4869 IDirect3DDevice7
*device
;
4870 unsigned int i
, j
, x
, y
;
4871 IDirectDrawSurface7
*rt
;
4872 D3DMATERIAL7 material
;
4873 struct vec3
*src_data
;
4874 struct vertex
*quad
;
4882 struct vec4 position
;
4887 window
= create_window();
4888 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4890 skip("Failed to create a 3D device, skipping test.\n");
4891 DestroyWindow(window
);
4894 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
4895 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4897 quad
= heap_alloc(vertices_side
* vertices_side
* sizeof(*quad
));
4898 indices
= heap_alloc(indices_count
* sizeof(*indices
));
4899 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
4901 for (x
= 0; x
< vertices_side
; ++x
)
4903 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4904 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4905 quad
[i
].position
.z
= 1.0f
;
4906 quad
[i
].normal
.x
= 0.0f
;
4907 quad
[i
].normal
.y
= 0.0f
;
4908 quad
[i
++].normal
.z
= -1.0f
;
4911 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
4913 for (x
= 0; x
< (vertices_side
- 1); ++x
)
4915 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4916 indices
[i
++] = y
* vertices_side
+ x
;
4917 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4918 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4919 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4920 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
4924 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
4925 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4927 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4928 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4929 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4930 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4931 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4932 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4933 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
4934 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4935 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4936 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4937 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4938 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4940 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
4941 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4942 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
4943 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4945 memset(&vb_desc
, 0, sizeof(vb_desc
));
4946 vb_desc
.dwSize
= sizeof(vb_desc
);
4947 vb_desc
.dwFVF
= fvf
;
4948 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
4949 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0);
4950 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4951 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
4952 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4953 memcpy(src_data
, vertices
, sizeof(vertices
));
4954 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
4955 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4957 memset(&vb_desc
, 0, sizeof(vb_desc
));
4958 vb_desc
.dwSize
= sizeof(vb_desc
);
4959 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4960 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
4961 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
4962 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4964 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4966 hr
= IDirect3DDevice7_SetLight(device
, 0, tests
[i
].light
);
4967 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4969 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
4970 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4972 memset(&material
, 0, sizeof(material
));
4973 U1(U2(material
).specular
).r
= 1.0f
;
4974 U2(U2(material
).specular
).g
= 1.0f
;
4975 U3(U2(material
).specular
).b
= 1.0f
;
4976 U4(U2(material
).specular
).a
= 0.5f
;
4977 U4(material
).power
= tests
[i
].specular_power
;
4978 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
4979 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4981 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
4982 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4984 hr
= IDirect3DDevice7_BeginScene(device
);
4985 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4987 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4988 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4989 memset(dst_data
, 0, sizeof(*dst_data
) * ARRAY_SIZE(vertices
));
4990 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
4991 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4993 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
4994 ARRAY_SIZE(vertices
), src_vb
, 0, device
, 0);
4995 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4997 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
4998 vertices_side
* vertices_side
, indices
, indices_count
, 0);
4999 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5001 hr
= IDirect3DDevice7_EndScene(device
);
5002 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5004 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5005 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5007 ok(tests
[i
].expected_count
== ARRAY_SIZE(vertices
), "Array size mismatch.\n");
5008 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
5010 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
5011 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
5012 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
5013 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
5014 tests
[i
].expected
[j
].y
, color
, i
);
5015 ok(!dst_data
[j
].diffuse
, "Expected color 0x00000000 for vertex %u, got 0x%08x, case %u.\n",
5016 j
, dst_data
[j
].diffuse
, i
);
5017 expected_color
= tests
[i
].expected_process_vertices
[j
].color
| 0x80000000;
5018 todo_wine_if(tests
[i
].todo_process_vertices
&& dst_data
[j
].specular
!= expected_color
)
5019 ok(compare_color(dst_data
[j
].specular
, expected_color
, 1),
5020 "Expected color 0x%08x for vertex %u, got 0x%08x, case %u.\n",
5021 expected_color
, j
, dst_data
[j
].specular
, i
);
5023 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
5024 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
5027 IDirect3DVertexBuffer7_Release(dst_vb
);
5028 IDirect3DVertexBuffer7_Release(src_vb
);
5029 IDirectDrawSurface7_Release(rt
);
5031 IDirect3D7_Release(d3d
);
5032 refcount
= IDirect3DDevice7_Release(device
);
5033 ok(!refcount
, "Device has %u references left.\n", refcount
);
5034 DestroyWindow(window
);
5039 static void test_clear_rect_count(void)
5041 IDirectDrawSurface7
*rt
;
5042 IDirect3DDevice7
*device
;
5046 D3DRECT rect
= {{0}, {0}, {640}, {480}};
5048 window
= create_window();
5049 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5051 skip("Failed to create a 3D device, skipping test.\n");
5052 DestroyWindow(window
);
5056 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5057 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5059 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
5060 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5061 hr
= IDirect3DDevice7_Clear(device
, 0, &rect
, D3DCLEAR_TARGET
, 0x00ff0000, 1.0f
, 0);
5062 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5064 color
= get_surface_color(rt
, 320, 240);
5065 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x00ff0000, 1)),
5066 "Clear with count = 0, rect != NULL has color %#08x.\n", color
);
5068 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00ffffff, 1.0f
, 0);
5069 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5070 hr
= IDirect3DDevice7_Clear(device
, 1, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
5071 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5073 color
= get_surface_color(rt
, 320, 240);
5074 ok(compare_color(color
, 0x0000ff00, 1),
5075 "Clear with count = 1, rect = NULL has color %#08x.\n", color
);
5077 IDirectDrawSurface7_Release(rt
);
5078 IDirect3DDevice7_Release(device
);
5079 DestroyWindow(window
);
5082 static BOOL
test_mode_restored(IDirectDraw7
*ddraw
, HWND window
)
5084 DDSURFACEDESC2 ddsd1
, ddsd2
;
5087 memset(&ddsd1
, 0, sizeof(ddsd1
));
5088 ddsd1
.dwSize
= sizeof(ddsd1
);
5089 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd1
);
5090 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
5092 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5093 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5094 hr
= set_display_mode(ddraw
, 640, 480);
5095 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
5096 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5097 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5099 memset(&ddsd2
, 0, sizeof(ddsd2
));
5100 ddsd2
.dwSize
= sizeof(ddsd2
);
5101 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &ddsd2
);
5102 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
5103 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
5104 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
5106 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
5109 static void test_coop_level_versions(void)
5115 IDirectDrawSurface
*surface
;
5116 IDirectDraw7
*ddraw7
;
5119 window
= create_window();
5120 ddraw7
= create_ddraw();
5121 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5122 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
5123 restored
= test_mode_restored(ddraw7
, window
);
5124 ok(restored
, "Display mode not restored in new ddraw object\n");
5126 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
5127 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5128 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5130 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5131 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
5132 restored
= test_mode_restored(ddraw7
, window
);
5133 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
5135 /* A successful one does */
5136 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5137 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5138 restored
= test_mode_restored(ddraw7
, window
);
5139 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
5141 IDirectDraw_Release(ddraw
);
5142 IDirectDraw7_Release(ddraw7
);
5144 ddraw7
= create_ddraw();
5145 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5146 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5147 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5149 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
5150 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5151 restored
= test_mode_restored(ddraw7
, window
);
5152 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
5154 IDirectDraw_Release(ddraw
);
5155 IDirectDraw7_Release(ddraw7
);
5157 /* A failing call does not restore the ddraw2+ behavior */
5158 ddraw7
= create_ddraw();
5159 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5160 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5161 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5163 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5164 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5165 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5166 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
5167 restored
= test_mode_restored(ddraw7
, window
);
5168 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
5170 IDirectDraw_Release(ddraw
);
5171 IDirectDraw7_Release(ddraw7
);
5173 /* Neither does a sequence of successful calls with the new interface */
5174 ddraw7
= create_ddraw();
5175 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5176 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5177 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5179 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5180 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5181 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5182 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5183 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
5184 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5186 restored
= test_mode_restored(ddraw7
, window
);
5187 ok(!restored
, "Display mode restored after ddraw1-ddraw7 SetCooperativeLevel() call sequence\n");
5188 IDirectDraw_Release(ddraw
);
5189 IDirectDraw7_Release(ddraw7
);
5191 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
5192 ddraw7
= create_ddraw();
5193 ok(!!ddraw7
, "Failed to create a ddraw object.\n");
5194 hr
= IDirectDraw7_QueryInterface(ddraw7
, &IID_IDirectDraw
, (void **)&ddraw
);
5195 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
5197 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, window
, DDSCL_NORMAL
);
5198 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
5200 memset(&ddsd
, 0, sizeof(ddsd
));
5201 ddsd
.dwSize
= sizeof(ddsd
);
5202 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5203 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5204 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
5205 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5206 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
5207 IDirectDrawSurface_Release(surface
);
5208 restored
= test_mode_restored(ddraw7
, window
);
5209 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
5211 IDirectDraw_Release(ddraw
);
5212 IDirectDraw7_Release(ddraw7
);
5213 DestroyWindow(window
);
5216 static void test_fog_special(void)
5220 struct vec3 position
;
5225 {{ -1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
5226 {{ 1.0f
, 1.0f
, 1.0f
}, 0xff00ff00},
5227 {{ -1.0f
, -1.0f
, 0.0f
}, 0xff00ff00},
5228 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
5232 DWORD vertexmode
, tablemode
;
5233 D3DCOLOR color_left
, color_right
;
5237 {D3DFOG_LINEAR
, D3DFOG_NONE
, 0x00ff0000, 0x00ff0000},
5238 {D3DFOG_NONE
, D3DFOG_LINEAR
, 0x0000ff00, 0x00ff0000},
5249 IDirect3DDevice7
*device
;
5250 IDirectDrawSurface7
*rt
;
5252 window
= create_window();
5253 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5255 skip("Failed to create a 3D device, skipping test.\n");
5256 DestroyWindow(window
);
5260 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5261 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5263 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
5264 ok(SUCCEEDED(hr
), "Failed to enable fog, hr %#x.\n", hr
);
5265 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0xffff0000);
5266 ok(SUCCEEDED(hr
), "Failed to set fog color, hr %#x.\n", hr
);
5267 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
5268 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
5269 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5270 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
5273 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGSTART
, conv
.d
);
5274 ok(SUCCEEDED(hr
), "Failed to set fog start, hr %#x.\n", hr
);
5275 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGEND
, conv
.d
);
5276 ok(SUCCEEDED(hr
), "Failed to set fog end, hr %#x.\n", hr
);
5278 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5280 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 1.0f
, 0);
5281 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
5283 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vertexmode
);
5284 ok(SUCCEEDED(hr
), "Failed to set fogvertexmode, hr %#x.\n", hr
);
5285 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tablemode
);
5286 ok(SUCCEEDED(hr
), "Failed to set fogtablemode, hr %#x.\n", hr
);
5288 hr
= IDirect3DDevice7_BeginScene(device
);
5289 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5290 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
5291 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5292 hr
= IDirect3DDevice7_EndScene(device
);
5293 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5295 color
= get_surface_color(rt
, 310, 240);
5296 ok(compare_color(color
, tests
[i
].color_left
, 1),
5297 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_left
, color
, i
);
5298 color
= get_surface_color(rt
, 330, 240);
5299 ok(compare_color(color
, tests
[i
].color_right
, 1),
5300 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests
[i
].color_right
, color
, i
);
5303 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
5304 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
5306 IDirectDrawSurface7_Release(rt
);
5307 IDirect3DDevice7_Release(device
);
5308 DestroyWindow(window
);
5311 static void test_lighting_interface_versions(void)
5313 IDirect3DDevice7
*device
;
5314 IDirectDrawSurface7
*rt
;
5321 D3DMATERIAL7 material
;
5322 static D3DVERTEX quad
[] =
5324 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5325 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5326 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5327 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5330 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
5333 struct vec3 position
;
5335 DWORD diffuse
, specular
;
5339 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5340 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5341 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5342 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5345 static D3DLVERTEX lquad
[] =
5347 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5348 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5349 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5350 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5353 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
5356 struct vec3 position
;
5357 DWORD diffuse
, specular
;
5358 struct vec2 texcoord
;
5362 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5363 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5364 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5365 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5368 static D3DTLVERTEX tlquad
[] =
5370 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5371 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5372 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5373 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5380 DWORD d3drs_lighting
, d3drs_specular
;
5386 /* Lighting is enabled when D3DFVF_XYZ is used and D3DRENDERSTATE_LIGHTING is
5387 * enabled. D3DDP_DONOTLIGHT is ignored. Lighting is also enabled when normals
5390 * Note that the specular result is 0x00000000 when lighting is on even if the
5391 * input vertex has specular color because D3DRENDERSTATE_COLORVERTEX is not
5395 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x00ffffff},
5396 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
5397 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5398 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5399 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x00ffffff},
5400 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
5401 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5402 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5405 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5406 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5407 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5408 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5409 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5410 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5411 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5412 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5415 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
5416 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x0000ff00},
5417 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5418 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5419 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
5420 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x0000ff00},
5421 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5422 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5425 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5426 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5427 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5428 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5429 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5430 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5431 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5432 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x0000ff00},
5435 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
5436 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
5437 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5438 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5439 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
5440 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
5441 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5442 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5445 window
= create_window();
5446 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5448 skip("Failed to create a 3D device, skipping test.\n");
5449 DestroyWindow(window
);
5453 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
5454 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5456 memset(&material
, 0, sizeof(material
));
5457 U2(U3(material
).emissive
).g
= 1.0f
;
5458 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
5459 ok(SUCCEEDED(hr
), "Failed set material, hr %#x.\n", hr
);
5460 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5461 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
5463 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &rs
);
5464 ok(SUCCEEDED(hr
), "Failed to get lighting render state, hr %#x.\n", hr
);
5465 ok(rs
== TRUE
, "Initial D3DRENDERSTATE_LIGHTING is %#x, expected TRUE.\n", rs
);
5466 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
5467 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
5468 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected FALSE.\n", rs
);
5470 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5472 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
5473 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5475 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
5476 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
5477 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
5478 tests
[i
].d3drs_specular
);
5479 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
5481 hr
= IDirect3DDevice7_BeginScene(device
);
5482 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5483 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
5484 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
5485 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5486 hr
= IDirect3DDevice7_EndScene(device
);
5487 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5489 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &rs
);
5490 ok(SUCCEEDED(hr
), "Failed to get lighting render state, hr %#x.\n", hr
);
5491 ok(rs
== tests
[i
].d3drs_lighting
, "D3DRENDERSTATE_LIGHTING is %#x, expected %#x.\n",
5492 rs
, tests
[i
].d3drs_lighting
);
5494 color
= get_surface_color(rt
, 320, 240);
5495 ok(compare_color(color
, tests
[i
].color
, 1),
5496 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
5497 color
, tests
[i
].color
, i
);
5500 IDirectDrawSurface7_Release(rt
);
5501 ref
= IDirect3DDevice7_Release(device
);
5502 ok(ref
== 0, "Device not properly released, refcount %u.\n", ref
);
5503 DestroyWindow(window
);
5509 IDirectDraw7
*ddraw
;
5512 } activateapp_testdata
;
5514 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
5516 if (message
== WM_ACTIVATEAPP
)
5518 if (activateapp_testdata
.ddraw
)
5521 activateapp_testdata
.received
= FALSE
;
5522 hr
= IDirectDraw7_SetCooperativeLevel(activateapp_testdata
.ddraw
,
5523 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
5524 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
5525 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
5527 activateapp_testdata
.received
= TRUE
;
5530 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
5533 static void test_coop_level_activateapp(void)
5535 IDirectDraw7
*ddraw
;
5539 DDSURFACEDESC2 ddsd
;
5540 IDirectDrawSurface7
*surface
;
5542 ddraw
= create_ddraw();
5543 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5545 wc
.lpfnWndProc
= activateapp_test_proc
;
5546 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
5547 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
5549 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
5550 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
5552 /* Exclusive with window already active. */
5553 SetForegroundWindow(window
);
5554 activateapp_testdata
.received
= FALSE
;
5555 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5556 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5557 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
5558 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5559 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5561 /* Exclusive with window not active. */
5562 SetForegroundWindow(GetDesktopWindow());
5563 activateapp_testdata
.received
= FALSE
;
5564 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5565 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5566 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5567 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5568 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5570 /* Normal with window not active, then exclusive with the same window. */
5571 SetForegroundWindow(GetDesktopWindow());
5572 activateapp_testdata
.received
= FALSE
;
5573 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5574 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5575 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
5576 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5577 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5578 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5579 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5580 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5582 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
5583 SetForegroundWindow(GetDesktopWindow());
5584 activateapp_testdata
.received
= FALSE
;
5585 activateapp_testdata
.ddraw
= ddraw
;
5586 activateapp_testdata
.window
= window
;
5587 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
5588 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5589 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5590 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5591 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5592 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5594 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
5595 * succeeding. Another switch to exclusive and back to normal is needed to release the
5596 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
5597 * WM_ACTIVATEAPP messages. */
5598 activateapp_testdata
.ddraw
= NULL
;
5599 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5600 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5601 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5602 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5604 /* Setting DDSCL_NORMAL with recursive invocation. */
5605 SetForegroundWindow(GetDesktopWindow());
5606 activateapp_testdata
.received
= FALSE
;
5607 activateapp_testdata
.ddraw
= ddraw
;
5608 activateapp_testdata
.window
= window
;
5609 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
5610 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5611 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5612 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5614 /* DDraw is in exclusive mode now. */
5615 memset(&ddsd
, 0, sizeof(ddsd
));
5616 ddsd
.dwSize
= sizeof(ddsd
);
5617 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5618 U5(ddsd
).dwBackBufferCount
= 1;
5619 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5620 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5621 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5622 IDirectDrawSurface7_Release(surface
);
5624 /* Recover again, just to be sure. */
5625 activateapp_testdata
.ddraw
= NULL
;
5626 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5627 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5628 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5629 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5631 DestroyWindow(window
);
5632 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
5633 IDirectDraw7_Release(ddraw
);
5636 static void test_texturemanage(void)
5638 IDirectDraw7
*ddraw
;
5640 DDSURFACEDESC2 ddsd
;
5641 IDirectDrawSurface7
*surface
;
5643 DDCAPS hal_caps
, hel_caps
;
5644 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
5647 DWORD caps_in
, caps2_in
;
5649 DWORD caps_out
, caps2_out
;
5653 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5655 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5657 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5659 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5661 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
5662 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
5663 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
5664 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
5665 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5666 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
5667 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5668 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
5670 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5672 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5674 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5676 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5678 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5680 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5682 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
5683 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
5684 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
5685 DDSCAPS_SYSTEMMEMORY
, 0},
5688 ddraw
= create_ddraw();
5689 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5690 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5691 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5693 memset(&hal_caps
, 0, sizeof(hal_caps
));
5694 hal_caps
.dwSize
= sizeof(hal_caps
);
5695 memset(&hel_caps
, 0, sizeof(hel_caps
));
5696 hel_caps
.dwSize
= sizeof(hel_caps
);
5697 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
5698 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5699 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
5701 skip("Managed textures not supported, skipping managed texture test.\n");
5702 IDirectDraw7_Release(ddraw
);
5706 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5708 memset(&ddsd
, 0, sizeof(ddsd
));
5709 ddsd
.dwSize
= sizeof(ddsd
);
5710 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5711 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
5712 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
5716 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5717 if (tests
[i
].hr
== DD_OK
&& is_ddraw64
&& (tests
[i
].caps_in
& DDSCAPS_TEXTURE
))
5718 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5720 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, tests
[i
].hr
);
5724 memset(&ddsd
, 0, sizeof(ddsd
));
5725 ddsd
.dwSize
= sizeof(ddsd
);
5726 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
5727 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5729 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
5730 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5731 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
5732 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
5733 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5734 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
5736 IDirectDrawSurface7_Release(surface
);
5739 IDirectDraw7_Release(ddraw
);
5742 #define SUPPORT_DXT1 0x01
5743 #define SUPPORT_DXT2 0x02
5744 #define SUPPORT_DXT3 0x04
5745 #define SUPPORT_DXT4 0x08
5746 #define SUPPORT_DXT5 0x10
5747 #define SUPPORT_YUY2 0x20
5748 #define SUPPORT_UYVY 0x40
5750 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5752 DWORD
*supported_fmts
= ctx
;
5754 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
5755 return DDENUMRET_OK
;
5757 switch (fmt
->dwFourCC
)
5759 case MAKEFOURCC('D','X','T','1'):
5760 *supported_fmts
|= SUPPORT_DXT1
;
5762 case MAKEFOURCC('D','X','T','2'):
5763 *supported_fmts
|= SUPPORT_DXT2
;
5765 case MAKEFOURCC('D','X','T','3'):
5766 *supported_fmts
|= SUPPORT_DXT3
;
5768 case MAKEFOURCC('D','X','T','4'):
5769 *supported_fmts
|= SUPPORT_DXT4
;
5771 case MAKEFOURCC('D','X','T','5'):
5772 *supported_fmts
|= SUPPORT_DXT5
;
5774 case MAKEFOURCC('Y','U','Y','2'):
5775 *supported_fmts
|= SUPPORT_YUY2
;
5777 case MAKEFOURCC('U','Y','V','Y'):
5778 *supported_fmts
|= SUPPORT_UYVY
;
5784 return DDENUMRET_OK
;
5787 static void test_block_formats_creation(void)
5789 HRESULT hr
, expect_hr
;
5790 unsigned int i
, j
, w
, h
;
5792 IDirectDraw7
*ddraw
;
5794 IDirect3DDevice7
*device
;
5795 IDirectDrawSurface7
*surface
;
5796 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
5797 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
5798 DDSURFACEDESC2 ddsd
;
5807 unsigned int block_width
;
5808 unsigned int block_height
;
5809 unsigned int block_size
;
5810 BOOL create_size_checked
, overlay
;
5814 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
5815 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
5816 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
5817 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
5818 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
5819 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
5820 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
5830 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
5831 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
5833 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
5834 * Other hw / drivers successfully create those surfaces. Ignore them, this
5835 * suggests that no game uses this, otherwise Nvidia would support it. */
5837 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
5838 "videomemory texture", FALSE
5841 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
5842 "videomemory overlay", TRUE
5845 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
5846 "systemmemory texture", FALSE
5849 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
5850 "managed texture", FALSE
5862 enum size_type size_type
;
5868 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5869 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5870 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5871 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5872 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5873 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5874 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
5875 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5876 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
5877 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
5878 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5879 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
5880 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DDERR_INVALIDPARAMS
},
5881 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DDERR_INVALIDPARAMS
},
5884 window
= create_window();
5885 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5887 skip("Failed to create a 3D device, skipping test.\n");
5888 DestroyWindow(window
);
5892 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
5893 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5894 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **) &ddraw
);
5895 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5896 IDirect3D7_Release(d3d
);
5898 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
5900 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5902 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
5903 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5904 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
5905 num_fourcc_codes
* sizeof(*fourcc_codes
));
5908 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
5909 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5910 for (i
= 0; i
< num_fourcc_codes
; i
++)
5912 for (j
= 0; j
< ARRAY_SIZE(formats
); ++j
)
5914 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
5915 supported_overlay_fmts
|= formats
[j
].support_flag
;
5918 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
5920 memset(&hal_caps
, 0, sizeof(hal_caps
));
5921 hal_caps
.dwSize
= sizeof(hal_caps
);
5922 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
5923 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5925 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
5927 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
5929 for (j
= 0; j
< ARRAY_SIZE(types
); ++j
)
5933 if (formats
[i
].overlay
!= types
[j
].overlay
5934 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
5937 if (formats
[i
].overlay
)
5938 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
5940 support
= supported_fmts
& formats
[i
].support_flag
;
5942 for (w
= 1; w
<= 8; w
++)
5944 for (h
= 1; h
<= 8; h
++)
5946 BOOL block_aligned
= TRUE
;
5949 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
5950 block_aligned
= FALSE
;
5952 memset(&ddsd
, 0, sizeof(ddsd
));
5953 ddsd
.dwSize
= sizeof(ddsd
);
5954 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5955 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
5956 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
5957 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5958 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5959 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5963 /* TODO: Handle power of two limitations. I cannot test the pow2
5964 * behavior on windows because I have no hardware that doesn't at
5965 * least support np2_conditional. There's probably no HW that
5966 * supports DXTN textures but no conditional np2 textures. */
5967 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
5968 expect_hr
= DDERR_INVALIDPARAMS
;
5969 else if (formats
[i
].create_size_checked
&& !block_aligned
)
5971 expect_hr
= DDERR_INVALIDPARAMS
;
5972 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
5978 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5981 "Got unexpected hr %#x for format %s, resource type %s, size %ux%u, expected %#x.\n",
5982 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
5985 IDirectDrawSurface7_Release(surface
);
5990 if (formats
[i
].overlay
)
5993 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
5995 memset(&ddsd
, 0, sizeof(ddsd
));
5996 ddsd
.dwSize
= sizeof(ddsd
);
5997 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
5998 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
6000 switch (user_mem_tests
[j
].size_type
)
6002 case SIZE_TYPE_ZERO
:
6003 U1(ddsd
).dwLinearSize
= 0;
6006 case SIZE_TYPE_PITCH
:
6007 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
6010 case SIZE_TYPE_SIZE
:
6011 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
6014 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
6016 ddsd
.lpSurface
= mem
;
6017 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6018 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
6019 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
6023 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6024 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#x, format %s.\n", j
, hr
, formats
[i
].name
);
6029 memset(&ddsd
, 0, sizeof(ddsd
));
6030 ddsd
.dwSize
= sizeof(ddsd
);
6031 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
6032 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", j
, hr
);
6033 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
6034 "Test %u: Got unexpected flags %#x.\n", j
, ddsd
.dwFlags
);
6035 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
6036 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#x.\n",
6037 j
, U1(ddsd
).dwLinearSize
);
6039 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
6040 "Test %u: Got unexpected linear size %#x, expected %#x.\n",
6041 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
6042 IDirectDrawSurface7_Release(surface
);
6046 HeapFree(GetProcessHeap(), 0, mem
);
6048 IDirectDraw7_Release(ddraw
);
6049 IDirect3DDevice7_Release(device
);
6050 DestroyWindow(window
);
6053 struct format_support_check
6055 const DDPIXELFORMAT
*format
;
6059 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
6061 struct format_support_check
*format
= ctx
;
6063 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
6065 format
->supported
= TRUE
;
6066 return DDENUMRET_CANCEL
;
6069 return DDENUMRET_OK
;
6072 static void test_unsupported_formats(void)
6075 BOOL expect_success
;
6077 IDirectDraw7
*ddraw
;
6079 IDirect3DDevice7
*device
;
6080 IDirectDrawSurface7
*surface
;
6081 DDSURFACEDESC2 ddsd
;
6083 DWORD expected_caps
;
6094 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
6095 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
6101 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6102 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
6106 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
6108 window
= create_window();
6109 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6111 skip("Failed to create a 3D device, skipping test.\n");
6112 DestroyWindow(window
);
6116 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
6117 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6118 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **) &ddraw
);
6119 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6120 IDirect3D7_Release(d3d
);
6122 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
6124 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
6125 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
6126 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
6128 for (j
= 0; j
< ARRAY_SIZE(caps
); ++j
)
6130 memset(&ddsd
, 0, sizeof(ddsd
));
6131 ddsd
.dwSize
= sizeof(ddsd
);
6132 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6133 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
6136 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
6138 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
6139 expect_success
= FALSE
;
6141 expect_success
= TRUE
;
6143 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6144 ok(SUCCEEDED(hr
) == expect_success
,
6145 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
6146 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
6150 memset(&ddsd
, 0, sizeof(ddsd
));
6151 ddsd
.dwSize
= sizeof(ddsd
);
6152 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
6153 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6155 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
6156 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6157 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
6158 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6159 else if (check
.supported
)
6160 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6162 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6164 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
6165 "Expected capability %#x, format %s, input cap %#x.\n",
6166 expected_caps
, formats
[i
].name
, caps
[j
]);
6168 IDirectDrawSurface7_Release(surface
);
6172 IDirectDraw7_Release(ddraw
);
6173 IDirect3DDevice7_Release(device
);
6174 DestroyWindow(window
);
6177 static void test_rt_caps(const GUID
*device_guid
)
6179 PALETTEENTRY palette_entries
[256];
6180 IDirectDrawPalette
*palette
;
6181 BOOL software_device
;
6182 IDirectDraw7
*ddraw
;
6183 DDPIXELFORMAT z_fmt
;
6191 static const DDPIXELFORMAT p8_fmt
=
6193 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6194 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
6199 const DDPIXELFORMAT
*pf
;
6202 HRESULT create_device_hr
;
6203 HRESULT set_rt_hr
, alternative_set_rt_hr
;
6209 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6217 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6225 DDSCAPS_OFFSCREENPLAIN
,
6233 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6235 D3DERR_SURFACENOTINVIDMEM
,
6236 DDERR_INVALIDPARAMS
,
6241 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6249 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6273 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6275 D3DERR_SURFACENOTINVIDMEM
,
6276 DDERR_INVALIDPARAMS
,
6281 DDSCAPS_SYSTEMMEMORY
,
6289 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6290 DDSCAPS2_TEXTUREMANAGE
,
6291 D3DERR_SURFACENOTINVIDMEM
,
6292 DDERR_INVALIDPARAMS
,
6297 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6298 DDSCAPS2_D3DTEXTUREMANAGE
,
6299 D3DERR_SURFACENOTINVIDMEM
,
6300 DDERR_INVALIDPARAMS
,
6313 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6315 DDERR_NOPALETTEATTACHED
,
6321 DDSCAPS_OFFSCREENPLAIN
,
6329 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6331 DDERR_NOPALETTEATTACHED
,
6337 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6345 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
6348 DDERR_INVALIDPIXELFORMAT
,
6349 DDERR_INVALIDPIXELFORMAT
,
6353 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6356 DDERR_INVALIDPIXELFORMAT
,
6357 DDERR_INVALIDPIXELFORMAT
,
6369 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6372 DDERR_INVALIDPARAMS
,
6373 DDERR_INVALIDPIXELFORMAT
,
6377 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
6385 software_device
= is_software_device_type(device_guid
);
6387 window
= create_window();
6388 ddraw
= create_ddraw();
6389 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6390 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6391 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6393 if (FAILED(IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
)))
6395 skip("D3D interface is not available, skipping test.\n");
6399 memset(&z_fmt
, 0, sizeof(z_fmt
));
6400 hr
= IDirect3D7_EnumZBufferFormats(d3d
, device_guid
, enum_z_fmt
, &z_fmt
);
6401 if (FAILED(hr
) || !z_fmt
.dwSize
)
6403 skip("No depth buffer formats available, software_device %u, skipping test.\n", software_device
);
6404 IDirect3D7_Release(d3d
);
6408 memset(palette_entries
, 0, sizeof(palette_entries
));
6409 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6410 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6412 memset(&hal_caps
, 0, sizeof(hal_caps
));
6413 hal_caps
.dwSize
= sizeof(hal_caps
);
6414 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
6415 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6417 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6419 IDirectDrawSurface7
*surface
, *rt
, *expected_rt
, *tmp
;
6420 DDSURFACEDESC2 surface_desc
;
6421 DWORD caps_in
, expected_caps
;
6422 IDirect3DDevice7
*device
;
6423 HRESULT expected_hr
;
6425 caps_in
= test_data
[i
].caps_in
;
6427 memset(&surface_desc
, 0, sizeof(surface_desc
));
6428 surface_desc
.dwSize
= sizeof(surface_desc
);
6429 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6430 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
6431 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6432 if (test_data
[i
].pf
)
6434 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6435 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6437 surface_desc
.dwWidth
= 640;
6438 surface_desc
.dwHeight
= 480;
6439 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6440 expected_hr
= DDERR_NODIRECTDRAWHW
;
6442 expected_hr
= DD_OK
;
6443 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6444 ok(hr
== expected_hr
|| (software_device
&& (surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
))
6445 == (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
) && hr
== DDERR_UNSUPPORTED
)
6446 || broken(software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
),
6447 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6451 memset(&surface_desc
, 0, sizeof(surface_desc
));
6452 surface_desc
.dwSize
= sizeof(surface_desc
);
6453 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
6454 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6456 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || (test_data
[i
].caps2_in
& (DDSCAPS2_D3DTEXTUREMANAGE
6457 | DDSCAPS2_TEXTUREMANAGE
)) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6458 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
6460 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
6462 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
6463 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
6464 || (software_device
&& test_data
[i
].pf
== &z_fmt
6465 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
6466 "Got unexpected caps %#x, expected %#x, test %u, software_device %u.\n",
6467 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
6469 ok(surface_desc
.ddsCaps
.dwCaps2
== test_data
[i
].caps2_in
,
6470 "Got unexpected caps2 %#x, expected %#x, test %u, software_device %u.\n",
6471 surface_desc
.ddsCaps
.dwCaps2
, test_data
[i
].caps2_in
, i
, software_device
);
6473 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6474 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
6475 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
6476 ? DD_OK
: test_data
[i
].create_device_hr
))),
6477 "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6480 if (hr
== DDERR_NOPALETTEATTACHED
)
6482 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
6483 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6484 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6485 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6486 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6487 hr
, i
, software_device
);
6488 else if (software_device
)
6490 ok(hr
== E_FAIL
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6491 hr
, i
, software_device
);
6493 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#x, test %u, software_device %u.\n",
6494 hr
, i
, software_device
);
6496 IDirectDrawSurface7_Release(surface
);
6498 memset(&surface_desc
, 0, sizeof(surface_desc
));
6499 surface_desc
.dwSize
= sizeof(surface_desc
);
6500 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6501 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6502 surface_desc
.dwWidth
= 640;
6503 surface_desc
.dwHeight
= 480;
6504 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6505 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6507 hr
= IDirect3D7_CreateDevice(d3d
, device_guid
, surface
, &device
);
6508 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6511 memset(&surface_desc
, 0, sizeof(surface_desc
));
6512 surface_desc
.dwSize
= sizeof(surface_desc
);
6513 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6514 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6515 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6516 if (test_data
[i
].pf
)
6518 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6519 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6521 surface_desc
.dwWidth
= 640;
6522 surface_desc
.dwHeight
= 480;
6523 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
6524 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6526 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
6527 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
6528 || hr
== test_data
[i
].alternative_set_rt_hr
,
6529 "Got unexpected hr %#x, test %u, software_device %u.\n",
6530 hr
, i
, software_device
);
6531 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
6534 expected_rt
= surface
;
6536 hr
= IDirect3DDevice7_GetRenderTarget(device
, &tmp
);
6537 ok(hr
== DD_OK
, "Got unexpected hr %#x, test %u, software_device %u.\n", hr
, i
, software_device
);
6538 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
6540 IDirectDrawSurface7_Release(tmp
);
6541 IDirectDrawSurface7_Release(rt
);
6542 refcount
= IDirect3DDevice7_Release(device
);
6543 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
6544 refcount
= IDirectDrawSurface7_Release(surface
);
6545 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
6548 refcount
= IDirectDrawPalette_Release(palette
);
6549 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6550 IDirect3D7_Release(d3d
);
6553 refcount
= IDirectDraw7_Release(ddraw
);
6554 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6555 DestroyWindow(window
);
6558 static void test_primary_caps(void)
6560 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6561 IDirectDrawSurface7
*surface
;
6562 DDSURFACEDESC2 surface_desc
;
6563 IDirectDraw7
*ddraw
;
6573 DWORD back_buffer_count
;
6581 DDSCAPS_PRIMARYSURFACE
,
6584 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
6588 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
6595 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
6602 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
6609 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
6616 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
6623 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6630 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6637 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6639 DDERR_NOEXCLUSIVEMODE
,
6643 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6644 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6650 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6651 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6654 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
6657 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6658 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
6664 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6665 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
6672 window
= create_window();
6673 ddraw
= create_ddraw();
6674 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6676 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6678 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
6679 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6681 memset(&surface_desc
, 0, sizeof(surface_desc
));
6682 surface_desc
.dwSize
= sizeof(surface_desc
);
6683 surface_desc
.dwFlags
= DDSD_CAPS
;
6684 if (test_data
[i
].back_buffer_count
!= ~0u)
6685 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6686 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6687 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
6688 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6689 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
6693 memset(&surface_desc
, 0, sizeof(surface_desc
));
6694 surface_desc
.dwSize
= sizeof(surface_desc
);
6695 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
6696 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6697 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
6698 "Test %u: Got unexpected caps %#x, expected %#x.\n",
6699 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
6701 IDirectDrawSurface7_Release(surface
);
6704 refcount
= IDirectDraw7_Release(ddraw
);
6705 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6706 DestroyWindow(window
);
6709 static void test_surface_lock(void)
6711 IDirectDraw7
*ddraw
;
6712 IDirect3D7
*d3d
= NULL
;
6713 IDirectDrawSurface7
*surface
;
6714 IDirect3DDevice7
*device
;
6715 HRESULT hr
, expected_hr
;
6718 DDSURFACEDESC2 ddsd
;
6720 DDPIXELFORMAT z_fmt
;
6721 BOOL hal_ok
= FALSE
;
6722 const GUID
*devtype
= &IID_IDirect3DHALDevice
;
6723 D3DDEVICEDESC7 device_desc
;
6724 BOOL cubemap_supported
;
6734 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
6736 "videomemory offscreenplain"
6739 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6741 "systemmemory offscreenplain"
6744 DDSCAPS_PRIMARYSURFACE
,
6749 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6751 "videomemory texture"
6754 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6756 "opaque videomemory texture"
6759 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
6761 "systemmemory texture"
6765 DDSCAPS2_TEXTUREMANAGE
,
6770 DDSCAPS2_D3DTEXTUREMANAGE
,
6775 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6776 "opaque managed texture"
6780 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6781 "opaque managed texture"
6784 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6794 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_VIDEOMEMORY
,
6795 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6799 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_VIDEOMEMORY
,
6800 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6801 "opaque videomemory cube"
6804 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_SYSTEMMEMORY
,
6805 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6809 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6810 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6814 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6815 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
,
6819 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6820 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6821 "opaque managed cube"
6824 DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
,
6825 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_OPAQUE
,
6826 "opaque managed cube"
6830 window
= create_window();
6831 ddraw
= create_ddraw();
6832 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6833 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6834 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6836 if (FAILED(IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
)))
6838 skip("D3D interface is not available, skipping test.\n");
6842 hr
= IDirect3D7_EnumDevices(d3d
, enum_devtype_cb
, &hal_ok
);
6843 ok(SUCCEEDED(hr
), "Failed to enumerate devices, hr %#x.\n", hr
);
6845 devtype
= &IID_IDirect3DTnLHalDevice
;
6847 memset(&z_fmt
, 0, sizeof(z_fmt
));
6848 hr
= IDirect3D7_EnumZBufferFormats(d3d
, devtype
, enum_z_fmt
, &z_fmt
);
6849 if (FAILED(hr
) || !z_fmt
.dwSize
)
6851 skip("No depth buffer formats available, skipping test.\n");
6855 memset(&ddsd
, 0, sizeof(ddsd
));
6856 ddsd
.dwSize
= sizeof(ddsd
);
6857 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6860 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6861 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6862 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6864 hr
= IDirect3D7_CreateDevice(d3d
, devtype
, surface
, &device
);
6865 ok(SUCCEEDED(hr
), "Failed to create device, hr %#x.\n", hr
);
6866 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
6867 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
6868 cubemap_supported
= !!(device_desc
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
);
6869 IDirect3DDevice7_Release(device
);
6871 IDirectDrawSurface7_Release(surface
);
6873 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6875 if (!cubemap_supported
&& tests
[i
].caps2
& DDSCAPS2_CUBEMAP
)
6878 memset(&ddsd
, 0, sizeof(ddsd
));
6879 ddsd
.dwSize
= sizeof(ddsd
);
6880 ddsd
.dwFlags
= DDSD_CAPS
;
6881 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6883 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6887 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
6889 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
6890 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
6892 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6893 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6895 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6896 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6898 memset(&ddsd
, 0, sizeof(ddsd
));
6899 ddsd
.dwSize
= sizeof(ddsd
);
6900 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6901 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6904 ok(ddsd
.dwSize
== sizeof(ddsd
), "Got unexpected dwSize %u, type %s.\n", ddsd
.dwSize
, tests
[i
].name
);
6905 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
6906 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6909 memset(&ddsd
, 0, sizeof(ddsd
));
6910 expected_hr
= tests
[i
].caps
& DDSCAPS_TEXTURE
&& !(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
6911 ? DD_OK
: DDERR_INVALIDPARAMS
;
6912 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6913 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, type %s.\n", hr
, expected_hr
, tests
[i
].name
);
6916 ok(!ddsd
.dwSize
, "Got unexpected dwSize %u, type %s.\n", ddsd
.dwSize
, tests
[i
].name
);
6917 ok(!!ddsd
.lpSurface
, "Got NULL lpSurface, type %s.\n", tests
[i
].name
);
6918 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
6919 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6922 IDirectDrawSurface7_Release(surface
);
6927 IDirect3D7_Release(d3d
);
6928 refcount
= IDirectDraw7_Release(ddraw
);
6929 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6930 DestroyWindow(window
);
6933 static void test_surface_discard(void)
6935 IDirect3DDevice7
*device
;
6937 IDirectDraw7
*ddraw
;
6940 DDSURFACEDESC2 ddsd
;
6941 IDirectDrawSurface7
*surface
, *target
;
6950 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6951 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6952 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6953 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6954 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
6955 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6956 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
6957 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6961 window
= create_window();
6963 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6967 /* Sigh. Anything other than the first run of the loop randomly fails with
6968 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
6969 * the blit fails, but with sleeps added between surface creation and lock
6970 * the lock can fail too. Interestingly ddraw claims the render target has
6971 * been lost, not the test surface.
6973 * Recreating ddraw every iteration seems to fix this. */
6974 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6976 skip("Failed to create a 3D device, skipping test.\n");
6977 DestroyWindow(window
);
6980 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
6981 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6982 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
6983 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6984 hr
= IDirect3DDevice7_GetRenderTarget(device
, &target
);
6985 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6987 memset(&ddsd
, 0, sizeof(ddsd
));
6988 ddsd
.dwSize
= sizeof(ddsd
);
6989 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6990 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6991 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6994 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6995 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#x, case %u.\n", hr
, i
);
6997 memset(&ddsd
, 0, sizeof(ddsd
));
6998 ddsd
.dwSize
= sizeof(ddsd
);
6999 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7000 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7001 addr
= ddsd
.lpSurface
;
7002 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7003 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7005 memset(&ddsd
, 0, sizeof(ddsd
));
7006 ddsd
.dwSize
= sizeof(ddsd
);
7007 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7008 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7009 discarded
= ddsd
.lpSurface
!= addr
;
7010 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7011 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7013 hr
= IDirectDrawSurface7_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
7014 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
7016 memset(&ddsd
, 0, sizeof(ddsd
));
7017 ddsd
.dwSize
= sizeof(ddsd
);
7018 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7019 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7020 discarded
|= ddsd
.lpSurface
!= addr
;
7021 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7022 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7024 IDirectDrawSurface7_Release(surface
);
7026 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
7027 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
7028 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
7030 IDirectDrawSurface7_Release(target
);
7031 IDirectDraw7_Release(ddraw
);
7032 IDirect3D7_Release(d3d
);
7033 IDirect3DDevice7_Release(device
);
7036 DestroyWindow(window
);
7039 static void test_flip(void)
7041 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
7042 IDirectDrawSurface7
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
7043 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
7044 DDSURFACEDESC2 surface_desc
;
7045 D3DDEVICEDESC7 device_desc
;
7046 IDirect3DDevice7
*device
;
7047 BOOL sysmem_primary
;
7048 IDirectDraw7
*ddraw
;
7049 DWORD expected_caps
;
7063 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
7064 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
7065 {"TEXTURE", DDSCAPS_TEXTURE
},
7068 window
= create_window();
7069 ddraw
= create_ddraw();
7070 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7072 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7073 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7075 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7077 /* Creating a flippable texture induces a BSoD on some versions of the
7078 * Intel graphics driver. At least Intel GMA 950 with driver version
7079 * 6.14.10.4926 on Windows XP SP3 is affected. */
7080 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
7082 win_skip("Skipping flippable texture test.\n");
7086 memset(&surface_desc
, 0, sizeof(surface_desc
));
7087 surface_desc
.dwSize
= sizeof(surface_desc
);
7088 surface_desc
.dwFlags
= DDSD_CAPS
;
7089 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7090 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
7091 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7092 surface_desc
.dwWidth
= 512;
7093 surface_desc
.dwHeight
= 512;
7094 U5(surface_desc
).dwBackBufferCount
= 3;
7095 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7096 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7098 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
7099 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7100 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7101 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7103 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
7104 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
7105 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7106 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7108 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
7109 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7110 if (is_ddraw64
&& test_data
[i
].caps
& DDSCAPS_TEXTURE
)
7111 todo_wine
ok(hr
== E_NOINTERFACE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7112 else todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
7113 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
7117 memset(&surface_desc
, 0, sizeof(surface_desc
));
7118 surface_desc
.dwSize
= sizeof(surface_desc
);
7119 hr
= IDirectDrawSurface7_GetSurfaceDesc(frontbuffer
, &surface_desc
);
7120 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7121 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7122 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7123 expected_caps
|= DDSCAPS_VISIBLE
;
7124 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7125 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7126 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
7128 hr
= IDirectDrawSurface7_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
7129 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7130 memset(&surface_desc
, 0, sizeof(surface_desc
));
7131 surface_desc
.dwSize
= sizeof(surface_desc
);
7132 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer1
, &surface_desc
);
7133 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7134 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7135 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7136 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
7137 expected_caps
|= DDSCAPS_BACKBUFFER
;
7138 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7139 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7141 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
7142 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7143 memset(&surface_desc
, 0, sizeof(surface_desc
));
7144 surface_desc
.dwSize
= sizeof(surface_desc
);
7145 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer2
, &surface_desc
);
7146 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7147 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7148 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7149 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
7150 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7151 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7153 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
7154 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7155 memset(&surface_desc
, 0, sizeof(surface_desc
));
7156 surface_desc
.dwSize
= sizeof(surface_desc
);
7157 hr
= IDirectDrawSurface7_GetSurfaceDesc(backbuffer3
, &surface_desc
);
7158 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
7159 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
7160 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7161 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7162 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7164 hr
= IDirectDrawSurface7_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
7165 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
7166 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
7167 test_data
[i
].name
, surface
, frontbuffer
);
7168 IDirectDrawSurface7_Release(surface
);
7170 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
7171 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
7172 hr
= IDirectDrawSurface7_IsLost(frontbuffer
);
7173 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7174 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7175 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7176 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7178 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7179 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7180 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
7181 hr
= IDirectDrawSurface7_IsLost(frontbuffer
);
7182 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7183 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
7184 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
7186 memset(&surface_desc
, 0, sizeof(surface_desc
));
7187 surface_desc
.dwSize
= sizeof(surface_desc
);
7188 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7189 surface_desc
.ddsCaps
.dwCaps
= 0;
7190 surface_desc
.dwWidth
= 640;
7191 surface_desc
.dwHeight
= 480;
7192 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7193 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
7194 hr
= IDirectDrawSurface7_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
7195 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7196 IDirectDrawSurface7_Release(surface
);
7198 hr
= IDirectDrawSurface7_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
7199 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7200 hr
= IDirectDrawSurface7_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
7201 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7202 hr
= IDirectDrawSurface7_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
7203 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7204 hr
= IDirectDrawSurface7_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
7205 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
7207 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
7208 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
7209 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
7210 fill_surface(backbuffer1
, 0xffff0000);
7211 fill_surface(backbuffer2
, 0xff00ff00);
7212 fill_surface(backbuffer3
, 0xff0000ff);
7214 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7215 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7216 color
= get_surface_color(backbuffer1
, 320, 240);
7217 /* The testbot seems to just copy the contents of one surface to all the
7218 * others, instead of properly flipping. */
7219 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7220 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7221 color
= get_surface_color(backbuffer2
, 320, 240);
7222 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7223 fill_surface(backbuffer3
, 0xffff0000);
7225 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7226 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7227 color
= get_surface_color(backbuffer1
, 320, 240);
7228 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7229 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7230 color
= get_surface_color(backbuffer2
, 320, 240);
7231 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7232 fill_surface(backbuffer3
, 0xff00ff00);
7234 hr
= IDirectDrawSurface7_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7235 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7236 color
= get_surface_color(backbuffer1
, 320, 240);
7237 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7238 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7239 color
= get_surface_color(backbuffer2
, 320, 240);
7240 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7241 fill_surface(backbuffer3
, 0xff0000ff);
7243 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
7244 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7245 color
= get_surface_color(backbuffer2
, 320, 240);
7246 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7247 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7248 color
= get_surface_color(backbuffer3
, 320, 240);
7249 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7250 fill_surface(backbuffer1
, 0xffff0000);
7252 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
7253 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7254 color
= get_surface_color(backbuffer1
, 320, 240);
7255 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7256 color
= get_surface_color(backbuffer3
, 320, 240);
7257 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7258 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7259 fill_surface(backbuffer2
, 0xff00ff00);
7261 hr
= IDirectDrawSurface7_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
7262 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
7263 color
= get_surface_color(backbuffer1
, 320, 240);
7264 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7265 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7266 color
= get_surface_color(backbuffer2
, 320, 240);
7267 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7269 IDirectDrawSurface7_Release(backbuffer3
);
7270 IDirectDrawSurface7_Release(backbuffer2
);
7271 IDirectDrawSurface7_Release(backbuffer1
);
7272 IDirectDrawSurface7_Release(frontbuffer
);
7275 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
7277 skip("Failed to create 3D device.\n");
7280 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
7281 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
7282 IDirect3DDevice7_Release(device
);
7283 if (!(device_desc
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
))
7285 skip("Cubemaps are not supported.\n");
7289 memset(&surface_desc
, 0, sizeof(surface_desc
));
7290 surface_desc
.dwSize
= sizeof(surface_desc
);
7291 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7292 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_TEXTURE
;
7293 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
7294 surface_desc
.dwWidth
= 128;
7295 surface_desc
.dwHeight
= 128;
7296 U5(surface_desc
).dwBackBufferCount
= 3;
7297 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7298 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7300 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
7301 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7302 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7303 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7305 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
7306 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
7307 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7308 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7310 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
7311 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7312 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7314 U5(surface_desc
).dwBackBufferCount
= 1;
7315 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7316 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7318 U5(surface_desc
).dwBackBufferCount
= 0;
7319 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7320 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7323 refcount
= IDirectDraw7_Release(ddraw
);
7324 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
7325 DestroyWindow(window
);
7328 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
7330 memset(ddsd
, 0, sizeof(*ddsd
));
7331 ddsd
->dwSize
= sizeof(*ddsd
);
7334 static void test_set_surface_desc(void)
7336 IDirectDraw7
*ddraw
;
7339 DDSURFACEDESC2 ddsd
;
7340 IDirectDrawSurface7
*surface
;
7350 invalid_caps_tests
[] =
7352 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
7353 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
7354 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
7355 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
7356 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
7359 window
= create_window();
7360 ddraw
= create_ddraw();
7361 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7362 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7363 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7366 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7369 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7370 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7371 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7372 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7373 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7374 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7375 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7377 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7378 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7381 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7382 ddsd
.lpSurface
= data
;
7383 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7384 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7386 /* Redundantly setting the same lpSurface is not an error. */
7387 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7388 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7390 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7391 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7392 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7393 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
7395 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7396 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
7397 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7398 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
7399 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
7400 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
7403 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7404 ddsd
.lpSurface
= data
;
7405 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 1);
7406 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
7408 ddsd
.lpSurface
= NULL
;
7409 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7410 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
7412 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, NULL
, 0);
7413 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
7415 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7416 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7417 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7418 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
7419 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
7421 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
7422 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7423 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
7425 ddsd
.dwFlags
= DDSD_CAPS
;
7426 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7427 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7429 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
7430 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
7431 ddsd
.lpSurface
= data
;
7432 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7433 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7434 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7435 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7436 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
7437 ddsd
.ddsCaps
.dwCaps
= 0;
7438 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
7439 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7440 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7442 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7443 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7444 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7445 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
7446 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
7448 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
7450 ddsd
.dwFlags
= DDSD_HEIGHT
;
7452 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7453 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
7455 ddsd
.lpSurface
= data
;
7456 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
7457 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7458 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7461 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7462 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
7465 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7466 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
7467 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
7468 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
7470 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0. */
7472 ddsd
.dwFlags
= DDSD_PITCH
;
7473 U1(ddsd
).lPitch
= 8 * 4;
7474 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7475 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
7477 ddsd
.dwFlags
= DDSD_WIDTH
;
7479 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7480 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
7482 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
7483 ddsd
.lpSurface
= data
;
7484 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7485 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
7487 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
7488 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7489 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
7491 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7492 U1(ddsd
).lPitch
= 16 * 4;
7494 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7495 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7498 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &ddsd
);
7499 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7500 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
7501 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
7502 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
7504 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
7506 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
7507 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7508 U1(ddsd
).lPitch
= 4 * 4;
7509 ddsd
.lpSurface
= data
;
7510 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7511 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
7513 U1(ddsd
).lPitch
= 4;
7514 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7515 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
7517 U1(ddsd
).lPitch
= 16 * 4 + 1;
7518 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7519 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
7521 U1(ddsd
).lPitch
= 16 * 4 + 3;
7522 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7523 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
7525 U1(ddsd
).lPitch
= -4;
7526 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7527 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
7529 U1(ddsd
).lPitch
= 16 * 4;
7530 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7531 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7534 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7535 U1(ddsd
).lPitch
= 0;
7537 ddsd
.lpSurface
= data
;
7538 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7539 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
7541 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7542 U1(ddsd
).lPitch
= 16 * 4;
7544 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7545 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
7547 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
7548 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
7549 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7550 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7551 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7552 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7553 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7554 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7555 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7556 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
7558 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
7559 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7560 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7562 /* Can't set color keys. */
7564 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
7565 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
7566 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
7567 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7568 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7570 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
7571 ddsd
.lpSurface
= data
;
7572 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7573 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7575 IDirectDrawSurface7_Release(surface
);
7577 /* Test mipmap texture. */
7579 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7582 U2(ddsd
).dwMipMapCount
= 3;
7583 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7585 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7586 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
7590 skip("Mipmaps are not supported.\n");
7594 /* Changing surface desc for mipmap fails even without changing any
7596 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7597 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
7600 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7601 ddsd
.lpSurface
= data
;
7602 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7603 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
7604 IDirectDrawSurface7_Release(surface
);
7608 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7611 U2(ddsd
).dwMipMapCount
= 3;
7612 ddsd
.lpSurface
= data
;
7613 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7615 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7616 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
7620 static DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7621 void *surface2_system_mem
;
7622 IDirectDrawSurface7
*surface2
;
7624 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
7625 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7627 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface2
, &ddsd
);
7628 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7629 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %u.\n", ddsd
.dwWidth
);
7631 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7632 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7633 surface2_system_mem
= ddsd
.lpSurface
;
7634 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7637 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7640 U1(ddsd
).lPitch
= 16 * 4;
7641 ddsd
.lpSurface
= data
;
7642 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7643 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7646 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7649 U1(ddsd
).lPitch
= 8 * 4;
7650 ddsd
.lpSurface
= data
;
7651 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7652 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7655 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7656 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7657 ok(ddsd
.lpSurface
== surface2_system_mem
, "Got unexpected lpSurface %p.\n", ddsd
.lpSurface
);
7658 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7661 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7664 U1(ddsd
).lPitch
= 4 * 4;
7665 ddsd
.lpSurface
= data
;
7666 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface2
, &ddsd
, 0);
7667 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7670 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &ddsd
, 0, NULL
);
7671 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7672 ok(ddsd
.lpSurface
== data
, "Got unexpected lpSurface %p.\n", ddsd
.lpSurface
);
7673 IDirectDrawSurface7_Unlock(surface2
, NULL
);
7676 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7679 U1(ddsd
).lPitch
= 16 * 4;
7680 ddsd
.lpSurface
= data
;
7681 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface2
, &ddsd
, 0);
7682 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7684 IDirectDrawSurface7_Release(surface2
);
7685 IDirectDrawSurface7_Release(surface
);
7688 /* Test surface created with DDSD_LPSURFACE. */
7690 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
7693 ddsd
.lpSurface
= data
;
7694 U1(ddsd
).lPitch
= 8 * 4;
7695 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7696 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7697 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7699 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7700 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x.\n", hr
);
7703 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
7706 /* Cannot reset lpSurface. */
7707 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7708 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7711 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_LPSURFACE
| DDSD_PITCH
;
7714 ddsd
.lpSurface
= data
;
7715 U1(ddsd
).lPitch
= 8 * 4;
7716 /* Can change the parameters of surface created with DDSD_LPSURFACE. */
7717 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7718 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7720 IDirectDrawSurface7_Release(surface
);
7722 /* SetSurfaceDesc needs systemmemory surfaces.
7724 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing
7725 * DDSD_LINEARSIZE is moot. */
7726 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); ++i
)
7729 ddsd
.dwFlags
= DDSD_CAPS
;
7730 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
7731 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
7732 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7734 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7737 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7738 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7739 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7740 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7741 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7742 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7745 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7746 if (is_ddraw64
&& (invalid_caps_tests
[i
].caps
& DDSCAPS_TEXTURE
))
7747 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7749 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7754 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7755 ddsd
.lpSurface
= data
;
7756 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7757 if (invalid_caps_tests
[i
].supported
)
7759 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7763 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7764 invalid_caps_tests
[i
].name
, hr
);
7766 /* Check priority of error conditions. */
7767 ddsd
.dwFlags
= DDSD_WIDTH
;
7768 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7769 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7770 invalid_caps_tests
[i
].name
, hr
);
7773 IDirectDrawSurface7_Release(surface
);
7776 ref
= IDirectDraw7_Release(ddraw
);
7777 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7778 DestroyWindow(window
);
7781 static void test_user_memory_getdc(void)
7783 IDirectDraw7
*ddraw
;
7786 DDSURFACEDESC2 ddsd
;
7787 IDirectDrawSurface7
*surface
;
7796 window
= create_window();
7797 ddraw
= create_ddraw();
7798 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7799 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7800 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7803 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7806 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7807 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7808 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7809 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7810 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7811 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7812 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7813 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7814 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7816 memset(data
, 0xaa, sizeof(data
));
7818 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7819 ddsd
.lpSurface
= data
;
7820 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7821 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7823 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
7824 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7825 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
7826 ok(!!bitmap
, "Failed to get bitmap.\n");
7827 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
7828 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
7829 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
7830 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
7831 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
7832 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
7833 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7835 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
7836 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
7838 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
7839 ddsd
.lpSurface
= data
;
7842 U1(ddsd
).lPitch
= sizeof(*data
);
7843 hr
= IDirectDrawSurface7_SetSurfaceDesc(surface
, &ddsd
, 0);
7844 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7846 memset(data
, 0xaa, sizeof(data
));
7847 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
7848 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7849 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
7850 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
7851 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
7852 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7854 for (y
= 0; y
< 4; y
++)
7856 for (x
= 0; x
< 4; x
++)
7858 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
7859 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
7862 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
7866 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
7868 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
7870 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
7872 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
7875 IDirectDrawSurface7_Release(surface
);
7876 ref
= IDirectDraw7_Release(ddraw
);
7877 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7878 DestroyWindow(window
);
7881 static void test_sysmem_overlay(void)
7883 IDirectDraw7
*ddraw
;
7886 DDSURFACEDESC2 ddsd
;
7887 IDirectDrawSurface7
*surface
;
7890 window
= create_window();
7891 ddraw
= create_ddraw();
7892 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7893 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7894 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7897 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
7900 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
7901 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7902 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7903 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7904 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7905 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7906 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7907 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7908 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
7910 ref
= IDirectDraw7_Release(ddraw
);
7911 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7912 DestroyWindow(window
);
7915 static void test_primary_palette(void)
7917 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
7918 IDirectDrawSurface7
*primary
, *backbuffer
;
7919 PALETTEENTRY palette_entries
[256];
7920 IDirectDrawPalette
*palette
, *tmp
;
7921 DDSURFACEDESC2 surface_desc
;
7922 IDirectDraw7
*ddraw
;
7928 window
= create_window();
7929 ddraw
= create_ddraw();
7930 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7931 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7933 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7934 IDirectDraw7_Release(ddraw
);
7935 DestroyWindow(window
);
7938 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7939 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7941 memset(&surface_desc
, 0, sizeof(surface_desc
));
7942 surface_desc
.dwSize
= sizeof(surface_desc
);
7943 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
7944 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
7945 U5(surface_desc
).dwBackBufferCount
= 1;
7946 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7947 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7948 hr
= IDirectDrawSurface7_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
7949 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
7951 memset(palette_entries
, 0, sizeof(palette_entries
));
7952 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
7953 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7954 refcount
= get_refcount((IUnknown
*)palette
);
7955 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7957 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7958 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7959 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
7961 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
7962 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7964 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
7965 * and is generally somewhat broken with respect to 8 bpp / palette
7967 if (SUCCEEDED(IDirectDrawSurface7_GetPalette(backbuffer
, &tmp
)))
7969 win_skip("Broken palette handling detected, skipping tests.\n");
7970 IDirectDrawPalette_Release(tmp
);
7971 IDirectDrawPalette_Release(palette
);
7972 /* The Windows 8 testbot keeps extra references to the primary and
7973 * backbuffer while in 8 bpp mode. */
7974 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
7975 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
7979 refcount
= get_refcount((IUnknown
*)palette
);
7980 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7982 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7983 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7984 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
7985 "Got unexpected palette caps %#x.\n", palette_caps
);
7987 hr
= IDirectDrawSurface7_SetPalette(primary
, NULL
);
7988 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7989 refcount
= get_refcount((IUnknown
*)palette
);
7990 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7992 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7993 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7994 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
7996 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
7997 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7998 refcount
= get_refcount((IUnknown
*)palette
);
7999 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8001 hr
= IDirectDrawSurface7_GetPalette(primary
, &tmp
);
8002 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
8003 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
8004 IDirectDrawPalette_Release(tmp
);
8005 hr
= IDirectDrawSurface7_GetPalette(backbuffer
, &tmp
);
8006 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
8008 refcount
= IDirectDrawPalette_Release(palette
);
8009 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8010 refcount
= IDirectDrawPalette_Release(palette
);
8011 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8013 /* Note that this only seems to work when the palette is attached to the
8014 * primary surface. When attached to a regular surface, attempting to get
8015 * the palette here will cause an access violation. */
8016 hr
= IDirectDrawSurface7_GetPalette(primary
, &tmp
);
8017 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
8019 hr
= IDirectDrawSurface7_IsLost(primary
);
8020 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8022 memset(&surface_desc
, 0, sizeof(surface_desc
));
8023 surface_desc
.dwSize
= sizeof(surface_desc
);
8024 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8025 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8026 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8027 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8028 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
8029 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8031 hr
= set_display_mode(ddraw
, 640, 480);
8032 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8034 memset(&surface_desc
, 0, sizeof(surface_desc
));
8035 surface_desc
.dwSize
= sizeof(surface_desc
);
8036 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8037 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8038 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8039 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8040 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8041 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8042 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8044 hr
= IDirectDrawSurface7_IsLost(primary
);
8045 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8046 hr
= IDirectDrawSurface7_Restore(primary
);
8047 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
8048 hr
= IDirectDrawSurface7_IsLost(primary
);
8049 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8051 memset(&surface_desc
, 0, sizeof(surface_desc
));
8052 surface_desc
.dwSize
= sizeof(surface_desc
);
8053 hr
= IDirectDrawSurface7_GetSurfaceDesc(primary
, &surface_desc
);
8054 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
8055 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
8056 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
8057 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8058 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8059 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8062 refcount
= IDirectDrawSurface7_Release(backbuffer
);
8063 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8064 refcount
= IDirectDrawSurface7_Release(primary
);
8065 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8066 refcount
= IDirectDraw7_Release(ddraw
);
8067 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8068 DestroyWindow(window
);
8071 static HRESULT WINAPI
surface_counter(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
8073 UINT
*surface_count
= context
;
8076 IDirectDrawSurface_Release(surface
);
8078 return DDENUMRET_OK
;
8081 static void test_surface_attachment(void)
8083 IDirectDrawSurface7
*surface1
, *surface2
, *surface3
, *surface4
;
8084 IDirectDrawSurface
*surface1v1
, *surface2v1
;
8085 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
8086 DDSURFACEDESC2 surface_desc
;
8087 IDirectDraw7
*ddraw
;
8093 window
= create_window();
8094 ddraw
= create_ddraw();
8095 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8096 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8097 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8099 memset(&surface_desc
, 0, sizeof(surface_desc
));
8100 surface_desc
.dwSize
= sizeof(surface_desc
);
8101 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
8102 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8103 U2(surface_desc
).dwMipMapCount
= 3;
8104 surface_desc
.dwWidth
= 128;
8105 surface_desc
.dwHeight
= 128;
8106 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
)))
8108 skip("Failed to create a texture, skipping tests.\n");
8109 IDirectDraw7_Release(ddraw
);
8110 DestroyWindow(window
);
8114 hr
= IDirectDrawSurface7_GetAttachedSurface(surface1
, &caps
, &surface2
);
8115 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
8116 hr
= IDirectDrawSurface7_GetAttachedSurface(surface2
, &caps
, &surface3
);
8117 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
8118 hr
= IDirectDrawSurface7_GetAttachedSurface(surface3
, &caps
, &surface4
);
8119 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8122 IDirectDrawSurface7_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
8123 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8125 IDirectDrawSurface7_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
8126 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8128 IDirectDrawSurface7_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
8129 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
8131 memset(&surface_desc
, 0, sizeof(surface_desc
));
8132 surface_desc
.dwSize
= sizeof(surface_desc
);
8133 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8134 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8135 surface_desc
.dwWidth
= 16;
8136 surface_desc
.dwHeight
= 16;
8137 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8138 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8140 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8141 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8142 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8143 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8144 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface4
);
8145 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8146 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface3
);
8147 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8148 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface4
);
8149 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8150 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface2
);
8151 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8153 IDirectDrawSurface7_Release(surface4
);
8155 memset(&surface_desc
, 0, sizeof(surface_desc
));
8156 surface_desc
.dwSize
= sizeof(surface_desc
);
8157 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8158 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8159 surface_desc
.dwWidth
= 16;
8160 surface_desc
.dwHeight
= 16;
8161 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8162 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8164 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8165 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8166 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8167 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8168 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface4
);
8169 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8170 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface3
);
8171 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8172 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface4
);
8173 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8174 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface2
);
8175 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8177 IDirectDrawSurface7_Release(surface4
);
8178 IDirectDrawSurface7_Release(surface3
);
8179 IDirectDrawSurface7_Release(surface2
);
8180 IDirectDrawSurface7_Release(surface1
);
8182 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8183 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8185 /* Try a single primary and two offscreen plain surfaces. */
8186 memset(&surface_desc
, 0, sizeof(surface_desc
));
8187 surface_desc
.dwSize
= sizeof(surface_desc
);
8188 surface_desc
.dwFlags
= DDSD_CAPS
;
8189 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8190 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8191 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8193 memset(&surface_desc
, 0, sizeof(surface_desc
));
8194 surface_desc
.dwSize
= sizeof(surface_desc
);
8195 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8196 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8197 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8198 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8199 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8200 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8202 memset(&surface_desc
, 0, sizeof(surface_desc
));
8203 surface_desc
.dwSize
= sizeof(surface_desc
);
8204 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8205 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8206 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8207 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8208 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8209 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8211 /* This one has a different size. */
8212 memset(&surface_desc
, 0, sizeof(surface_desc
));
8213 surface_desc
.dwSize
= sizeof(surface_desc
);
8214 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8215 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8216 surface_desc
.dwWidth
= 128;
8217 surface_desc
.dwHeight
= 128;
8218 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8219 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8221 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8222 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8223 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface1
);
8224 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8225 hr
= IDirectDrawSurface7_AddAttachedSurface(surface2
, surface3
);
8226 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8227 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface4
);
8228 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8229 hr
= IDirectDrawSurface7_AddAttachedSurface(surface4
, surface1
);
8230 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8232 IDirectDrawSurface7_Release(surface4
);
8233 IDirectDrawSurface7_Release(surface3
);
8234 IDirectDrawSurface7_Release(surface2
);
8235 IDirectDrawSurface7_Release(surface1
);
8237 /* Test depth surfaces of different sizes. */
8238 memset(&surface_desc
, 0, sizeof(surface_desc
));
8239 surface_desc
.dwSize
= sizeof(surface_desc
);
8240 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8241 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8242 surface_desc
.dwWidth
= 64;
8243 surface_desc
.dwHeight
= 64;
8244 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8245 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8247 memset(&surface_desc
, 0, sizeof(surface_desc
));
8248 surface_desc
.dwSize
= sizeof(surface_desc
);
8249 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
8250 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8251 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8252 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8253 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8254 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8255 surface_desc
.dwWidth
= 32;
8256 surface_desc
.dwHeight
= 32;
8257 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8258 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8259 surface_desc
.dwWidth
= 64;
8260 surface_desc
.dwHeight
= 64;
8261 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8262 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8263 surface_desc
.dwWidth
= 128;
8264 surface_desc
.dwHeight
= 128;
8265 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8266 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
8268 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
8269 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8271 IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8272 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
8273 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#x.\n", hr
);
8274 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface3
);
8275 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#x.\n", hr
);
8276 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
8277 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8279 IDirectDrawSurface7_Release(surface4
);
8280 IDirectDrawSurface7_Release(surface3
);
8281 IDirectDrawSurface7_Release(surface2
);
8282 IDirectDrawSurface7_Release(surface1
);
8284 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
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
| DDSD_PIXELFORMAT
;
8288 surface_desc
.dwWidth
= 64;
8289 surface_desc
.dwHeight
= 64;
8290 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8291 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8292 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
8293 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
8294 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
8295 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8296 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
8297 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8298 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8299 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8300 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8302 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8303 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8304 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8305 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8306 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8307 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8309 hr
= IDirectDrawSurface7_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
8310 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
8311 hr
= IDirectDrawSurface7_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
8312 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
8314 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8315 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8316 refcount
= get_refcount((IUnknown
*)surface2
);
8317 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8318 refcount
= get_refcount((IUnknown
*)surface2v1
);
8319 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8320 hr
= IDirectDrawSurface7_AddAttachedSurface(surface1
, surface2
);
8321 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
8322 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8323 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
8324 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8325 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
8327 /* Attaching while already attached to other surface. */
8328 hr
= IDirectDrawSurface7_AddAttachedSurface(surface3
, surface2
);
8329 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8330 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface3
, 0, surface2
);
8331 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8332 IDirectDrawSurface7_Release(surface3
);
8334 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8335 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8336 refcount
= get_refcount((IUnknown
*)surface2
);
8337 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8338 refcount
= get_refcount((IUnknown
*)surface2v1
);
8339 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
8341 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
8342 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8343 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8344 hr
= IDirectDrawSurface7_DeleteAttachedSurface(surface1
, 0, surface2
);
8345 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
8346 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8347 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
8348 refcount
= IDirectDrawSurface7_Release(surface2
);
8349 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8350 refcount
= IDirectDrawSurface7_Release(surface1
);
8351 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8353 /* Automatic detachment on release. */
8354 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8355 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
8356 refcount
= get_refcount((IUnknown
*)surface2v1
);
8357 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
8358 refcount
= IDirectDrawSurface_Release(surface1v1
);
8359 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8360 refcount
= IDirectDrawSurface_Release(surface2v1
);
8361 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8362 refcount
= IDirectDraw7_Release(ddraw
);
8363 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8364 DestroyWindow(window
);
8367 static void test_private_data(void)
8369 IDirectDraw7
*ddraw
;
8370 IDirectDrawSurface7
*surface
, *surface2
;
8371 DDSURFACEDESC2 surface_desc
;
8372 ULONG refcount
, refcount2
, refcount3
;
8374 DWORD size
= sizeof(ptr
);
8377 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8378 DWORD data
[] = {1, 2, 3, 4};
8380 static const GUID ddraw_private_data_test_guid
=
8385 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
8387 static const GUID ddraw_private_data_test_guid2
=
8392 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
8395 window
= create_window();
8396 ddraw
= create_ddraw();
8397 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8398 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8399 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8401 reset_ddsd(&surface_desc
);
8402 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
8403 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
8404 surface_desc
.dwHeight
= 4;
8405 surface_desc
.dwWidth
= 4;
8406 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8407 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8409 /* NULL pointers are not valid, but don't cause a crash. */
8410 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
8411 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
8412 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8413 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
8414 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8415 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
8416 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8418 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
8419 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8420 0, DDSPD_IUNKNOWNPOINTER
);
8421 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8422 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8423 5, DDSPD_IUNKNOWNPOINTER
);
8424 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8425 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8426 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
8427 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8429 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
8430 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
8431 * erases the old content and returns an error. This behavior has
8432 * been fixed in d3d8 and d3d9. Unless an application is found
8433 * that depends on this we don't care about this behavior. */
8434 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8435 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8436 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8437 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8438 0, DDSPD_IUNKNOWNPOINTER
);
8439 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8441 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8442 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
8443 hr
= IDirectDrawSurface7_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8444 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
8446 refcount
= get_refcount((IUnknown
*)ddraw
);
8447 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8448 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8449 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8450 refcount2
= get_refcount((IUnknown
*)ddraw
);
8451 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
8453 hr
= IDirectDrawSurface7_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8454 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
8455 refcount2
= get_refcount((IUnknown
*)ddraw
);
8456 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
8458 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8459 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8460 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8461 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
8462 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
8463 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8464 refcount2
= get_refcount((IUnknown
*)ddraw
);
8465 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
8467 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8468 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8469 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8470 size
= 2 * sizeof(ptr
);
8471 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8472 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
8473 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8474 refcount2
= get_refcount(ptr
);
8475 /* Object is NOT addref'ed by the getter. */
8476 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
8477 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
8479 ptr
= (IUnknown
*)0xdeadbeef;
8481 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8482 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
8483 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8484 size
= 2 * sizeof(ptr
);
8485 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8486 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8487 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %u.\n", size
);
8489 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8490 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
8491 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
8492 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8493 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
8494 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8496 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
8497 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8498 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8499 ok(size
== 0xdeadbabe, "Got unexpected size %u.\n", size
);
8500 hr
= IDirectDrawSurface7_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8501 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8503 refcount3
= IDirectDrawSurface7_Release(surface
);
8504 ok(!refcount3
, "Got unexpected refcount %u.\n", refcount3
);
8506 /* Destroying the surface frees the reference held on the private data. It also frees
8507 * the reference the surface is holding on its creating object. */
8508 refcount2
= get_refcount((IUnknown
*)ddraw
);
8509 ok(refcount2
== refcount
- 1, "Got unexpected refcount %u.\n", refcount2
);
8511 memset(&hal_caps
, 0, sizeof(hal_caps
));
8512 hal_caps
.dwSize
= sizeof(hal_caps
);
8513 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
8514 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8515 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
8518 reset_ddsd(&surface_desc
);
8519 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
8520 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8521 surface_desc
.dwHeight
= 4;
8522 surface_desc
.dwWidth
= 4;
8523 U2(surface_desc
).dwMipMapCount
= 2;
8524 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8525 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8526 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
8527 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
8529 hr
= IDirectDrawSurface7_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
8530 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
8531 hr
= IDirectDrawSurface7_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8532 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8534 IDirectDrawSurface7_Release(surface2
);
8535 IDirectDrawSurface7_Release(surface
);
8538 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
8540 refcount
= IDirectDraw7_Release(ddraw
);
8541 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8542 DestroyWindow(window
);
8545 static void test_pixel_format(void)
8547 HWND window
, window2
= NULL
;
8548 HDC hdc
, hdc2
= NULL
;
8550 int format
, test_format
;
8551 PIXELFORMATDESCRIPTOR pfd
;
8552 IDirectDraw7
*ddraw
= NULL
;
8553 IDirectDrawClipper
*clipper
= NULL
;
8554 DDSURFACEDESC2 ddsd
;
8555 IDirectDrawSurface7
*primary
= NULL
, *offscreen
;
8559 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8560 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8563 skip("Failed to create window\n");
8567 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8568 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8570 hdc
= GetDC(window
);
8573 skip("Failed to get DC\n");
8578 hdc2
= GetDC(window2
);
8580 gl
= LoadLibraryA("opengl32.dll");
8581 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8583 format
= GetPixelFormat(hdc
);
8584 ok(format
== 0, "new window has pixel format %d\n", format
);
8586 ZeroMemory(&pfd
, sizeof(pfd
));
8587 pfd
.nSize
= sizeof(pfd
);
8589 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
8590 pfd
.iPixelType
= PFD_TYPE_RGBA
;
8591 pfd
.iLayerType
= PFD_MAIN_PLANE
;
8592 format
= ChoosePixelFormat(hdc
, &pfd
);
8595 skip("no pixel format available\n");
8599 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
8601 skip("failed to set pixel format\n");
8605 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
8607 skip("failed to set pixel format on second window\n");
8610 ReleaseDC(window2
, hdc2
);
8615 ddraw
= create_ddraw();
8616 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8618 test_format
= GetPixelFormat(hdc
);
8619 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8621 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8624 skip("Failed to set cooperative level, hr %#x.\n", hr
);
8628 test_format
= GetPixelFormat(hdc
);
8629 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8633 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
8634 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
8635 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
8636 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
8638 test_format
= GetPixelFormat(hdc
);
8639 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8641 test_format
= GetPixelFormat(hdc2
);
8642 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8645 memset(&ddsd
, 0, sizeof(ddsd
));
8646 ddsd
.dwSize
= sizeof(ddsd
);
8647 ddsd
.dwFlags
= DDSD_CAPS
;
8648 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8650 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
8651 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8653 test_format
= GetPixelFormat(hdc
);
8654 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8658 test_format
= GetPixelFormat(hdc2
);
8659 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8664 hr
= IDirectDrawSurface7_SetClipper(primary
, clipper
);
8665 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
8667 test_format
= GetPixelFormat(hdc
);
8668 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8670 test_format
= GetPixelFormat(hdc2
);
8671 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8674 memset(&ddsd
, 0, sizeof(ddsd
));
8675 ddsd
.dwSize
= sizeof(ddsd
);
8676 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8677 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8678 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
8679 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
8680 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
8682 memset(&fx
, 0, sizeof(fx
));
8683 fx
.dwSize
= sizeof(fx
);
8684 hr
= IDirectDrawSurface7_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
8685 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
8687 test_format
= GetPixelFormat(hdc
);
8688 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8690 hr
= IDirectDrawSurface7_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
8691 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#x.\n", hr
);
8693 test_format
= GetPixelFormat(hdc
);
8694 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8698 test_format
= GetPixelFormat(hdc2
);
8699 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8702 IDirectDrawSurface7_Release(offscreen
);
8705 if (primary
) IDirectDrawSurface7_Release(primary
);
8706 if (clipper
) IDirectDrawClipper_Release(clipper
);
8707 if (ddraw
) IDirectDraw7_Release(ddraw
);
8708 if (gl
) FreeLibrary(gl
);
8709 if (hdc
) ReleaseDC(window
, hdc
);
8710 if (hdc2
) ReleaseDC(window2
, hdc2
);
8711 DestroyWindow(window
);
8712 if (window2
) DestroyWindow(window2
);
8715 static void test_create_surface_pitch(void)
8717 IDirectDrawSurface7
*surface
;
8718 DDSURFACEDESC2 surface_desc
;
8719 IDirectDraw7
*ddraw
;
8739 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8741 DDSD_PITCH
, 0x100, 0x100},
8742 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8743 DDSD_PITCH
, 0x104, DD_OK
,
8744 DDSD_PITCH
, 0x100, 0x100},
8745 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8746 DDSD_PITCH
, 0x0f8, DD_OK
,
8747 DDSD_PITCH
, 0x100, 0x100},
8748 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8749 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8751 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8753 DDSD_PITCH
, 0x100, 0x0fc},
8755 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8756 DDSD_PITCH
, 0x104, DD_OK
,
8757 DDSD_PITCH
, 0x100, 0x0fc},
8758 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8759 DDSD_PITCH
, 0x0f8, DD_OK
,
8760 DDSD_PITCH
, 0x100, 0x0fc},
8761 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8762 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
8763 DDSD_PITCH
, 0x100, 0x0fc},
8764 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8765 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
8767 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8768 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8769 DDSD_PITCH
, 0x100, 0x100},
8771 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8772 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
8774 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8775 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
8776 DDSD_PITCH
, 0x0fc, 0x0fc},
8777 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8778 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
8780 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8781 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
8783 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8784 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
8787 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8788 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
8789 DDSD_PITCH
, 0x100, 0x100},
8790 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8791 0, 0, DDERR_INVALIDCAPS
,
8793 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8795 DDSD_PITCH
, 0x100, 0 },
8796 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8797 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8799 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8800 0, 0, DDERR_INVALIDCAPS
,
8803 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8805 DDSD_PITCH
, 0x100, 0 },
8806 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8807 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8808 DDSD_PITCH
, 0x100, 0 },
8810 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
8812 window
= create_window();
8813 ddraw
= create_ddraw();
8814 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8815 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8816 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8818 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
8820 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8822 memset(&surface_desc
, 0, sizeof(surface_desc
));
8823 surface_desc
.dwSize
= sizeof(surface_desc
);
8824 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
8825 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8826 surface_desc
.dwWidth
= 63;
8827 surface_desc
.dwHeight
= 63;
8828 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
8829 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8830 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8831 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8832 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8833 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8834 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8835 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8836 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
8838 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
8839 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
8840 surface_desc
.lpSurface
= mem
;
8841 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8843 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
8845 if (is_ddraw64
&& (test_data
[i
].caps
& DDSCAPS_TEXTURE
) && SUCCEEDED(test_data
[i
].hr
))
8846 todo_wine
ok(hr
== E_NOINTERFACE
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
8848 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
8852 memset(&surface_desc
, 0, sizeof(surface_desc
));
8853 surface_desc
.dwSize
= sizeof(surface_desc
);
8854 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
8855 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
8856 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
8857 "Test %u: Got unexpected flags %#x, expected %#x.\n",
8858 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
8859 /* The pitch for textures seems to be implementation specific. */
8860 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
8862 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
8863 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
8864 "Test %u: Got unexpected pitch %u, expected %u.\n",
8865 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
8867 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
8868 "Test %u: Got unexpected pitch %u, expected %u.\n",
8869 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
8871 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
8873 IDirectDrawSurface7_Release(surface
);
8876 HeapFree(GetProcessHeap(), 0, mem
);
8877 refcount
= IDirectDraw7_Release(ddraw
);
8878 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8879 DestroyWindow(window
);
8882 static void test_mipmap(void)
8884 IDirectDrawSurface7
*surface
, *surface_base
, *surface_mip
;
8885 unsigned int i
, mipmap_count
;
8886 DDSURFACEDESC2 surface_desc
;
8887 IDirectDraw7
*ddraw
;
8891 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8900 DWORD mipmap_count_in
;
8902 DWORD mipmap_count_out
;
8906 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
8907 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
8908 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
8909 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
8910 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 8},
8911 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 7},
8914 window
= create_window();
8915 ddraw
= create_ddraw();
8916 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8917 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8918 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8920 memset(&hal_caps
, 0, sizeof(hal_caps
));
8921 hal_caps
.dwSize
= sizeof(hal_caps
);
8922 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
8923 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8924 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
8927 skip("Mipmapped textures not supported, skipping tests.\n");
8928 IDirectDraw7_Release(ddraw
);
8929 DestroyWindow(window
);
8933 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8935 memset(&surface_desc
, 0, sizeof(surface_desc
));
8936 surface_desc
.dwSize
= sizeof(surface_desc
);
8937 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
8938 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
8939 surface_desc
.dwWidth
= tests
[i
].width
;
8940 surface_desc
.dwHeight
= tests
[i
].height
;
8941 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
8942 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
8943 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8944 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
8948 memset(&surface_desc
, 0, sizeof(surface_desc
));
8949 surface_desc
.dwSize
= sizeof(surface_desc
);
8950 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
8951 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
8952 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
8953 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
8954 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
8955 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
8957 surface_base
= surface
;
8958 IDirectDrawSurface7_AddRef(surface_base
);
8959 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
8960 while (mipmap_count
> 1)
8962 hr
= IDirectDrawSurface7_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
8963 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#x.\n", i
, mipmap_count
, hr
);
8965 memset(&surface_desc
, 0, sizeof(surface_desc
));
8966 surface_desc
.dwSize
= sizeof(surface_desc
);
8967 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface_base
, &surface_desc
);
8968 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#x.\n", i
, mipmap_count
, hr
);
8969 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
8970 "Test %u, %u: Got unexpected flags %#x.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
8971 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
8972 "Test %u, %u: Got unexpected mipmap count %u.\n",
8973 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
8975 memset(&surface_desc
, 0, sizeof(surface_desc
));
8976 surface_desc
.dwSize
= sizeof(surface_desc
);
8977 hr
= IDirectDrawSurface7_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
8978 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
8979 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
8980 "Test %u, %u: unexpected change of mipmap count %u.\n",
8981 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
8982 memset(&surface_desc
, 0, sizeof(surface_desc
));
8983 surface_desc
.dwSize
= sizeof(surface_desc
);
8984 hr
= IDirectDrawSurface7_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
8985 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
8986 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
8987 "Test %u, %u: Child mipmap count unexpected %u\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
8988 IDirectDrawSurface7_Unlock(surface_mip
, NULL
);
8989 IDirectDrawSurface7_Unlock(surface_base
, NULL
);
8991 IDirectDrawSurface7_Release(surface_base
);
8992 surface_base
= surface_mip
;
8995 IDirectDrawSurface7_Release(surface_base
);
8997 IDirectDrawSurface7_Release(surface
);
9000 refcount
= IDirectDraw7_Release(ddraw
);
9001 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9002 DestroyWindow(window
);
9005 static void test_palette_complex(void)
9007 IDirectDrawSurface7
*surface
, *mipmap
, *tmp
;
9008 DDSURFACEDESC2 surface_desc
;
9009 IDirectDraw7
*ddraw
;
9010 IDirectDrawPalette
*palette
, *palette2
;
9014 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
9016 PALETTEENTRY palette_entries
[256];
9019 window
= create_window();
9020 ddraw
= create_ddraw();
9021 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9022 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9023 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9025 memset(&hal_caps
, 0, sizeof(hal_caps
));
9026 hal_caps
.dwSize
= sizeof(hal_caps
);
9027 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
9028 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9029 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)
9032 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
9033 IDirectDraw7_Release(ddraw
);
9034 DestroyWindow(window
);
9038 memset(&surface_desc
, 0, sizeof(surface_desc
));
9039 surface_desc
.dwSize
= sizeof(surface_desc
);
9040 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9041 surface_desc
.dwWidth
= 128;
9042 surface_desc
.dwHeight
= 128;
9043 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9044 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9045 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9046 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9047 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9048 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9050 memset(palette_entries
, 0, sizeof(palette_entries
));
9051 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9052 palette_entries
, &palette
, NULL
);
9053 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9055 palette2
= (void *)0xdeadbeef;
9056 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette2
);
9057 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
9058 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
9059 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9060 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9061 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette2
);
9062 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
9063 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
9064 IDirectDrawPalette_Release(palette2
);
9067 IDirectDrawSurface7_AddRef(mipmap
);
9068 for (i
= 0; i
< 7; ++i
)
9070 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9071 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
9072 palette2
= (void *)0xdeadbeef;
9073 hr
= IDirectDrawSurface7_GetPalette(tmp
, &palette2
);
9074 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9075 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
9077 hr
= IDirectDrawSurface7_SetPalette(tmp
, palette
);
9078 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9080 hr
= IDirectDrawSurface7_GetPalette(tmp
, &palette2
);
9081 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
9082 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
9084 /* Ddraw7 uses the palette of the mipmap for GetDC, just like previous
9085 * ddraw versions. Combined with the test results above this means no
9086 * palette is available. So depending on the driver either GetDC fails
9087 * or the DIB color table contains random data. */
9089 IDirectDrawSurface7_Release(mipmap
);
9093 hr
= IDirectDrawSurface7_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9094 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
9095 IDirectDrawSurface7_Release(mipmap
);
9096 refcount
= IDirectDrawSurface7_Release(surface
);
9097 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9099 /* Test DDERR_INVALIDPIXELFORMAT vs DDERR_NOTONMIPMAPSUBLEVEL. */
9100 memset(&surface_desc
, 0, sizeof(surface_desc
));
9101 surface_desc
.dwSize
= sizeof(surface_desc
);
9102 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9103 surface_desc
.dwWidth
= 128;
9104 surface_desc
.dwHeight
= 128;
9105 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9106 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9107 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9108 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9109 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9110 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9111 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9112 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9113 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9115 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
9116 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
9117 hr
= IDirectDrawSurface7_SetPalette(mipmap
, palette
);
9118 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
9120 IDirectDrawSurface7_Release(mipmap
);
9121 refcount
= IDirectDrawSurface7_Release(surface
);
9122 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9123 refcount
= IDirectDrawPalette_Release(palette
);
9124 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9126 refcount
= IDirectDraw7_Release(ddraw
);
9127 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9128 DestroyWindow(window
);
9131 static void test_p8_blit(void)
9133 IDirectDrawSurface7
*src
, *dst
, *dst_p8
;
9134 DDSURFACEDESC2 surface_desc
;
9135 IDirectDraw7
*ddraw
;
9136 IDirectDrawPalette
*palette
, *palette2
;
9140 PALETTEENTRY palette_entries
[256];
9144 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
9145 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
9146 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
9147 static const D3DCOLOR expected
[] =
9149 0x00101010, 0x00010101, 0x00020202, 0x00030303,
9150 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
9154 window
= create_window();
9155 ddraw
= create_ddraw();
9156 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9157 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9158 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9159 is_warp
= ddraw_is_warp(ddraw
);
9161 memset(palette_entries
, 0, sizeof(palette_entries
));
9162 palette_entries
[1].peGreen
= 0xff;
9163 palette_entries
[2].peBlue
= 0xff;
9164 palette_entries
[3].peFlags
= 0xff;
9165 palette_entries
[4].peRed
= 0xff;
9166 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9167 palette_entries
, &palette
, NULL
);
9168 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9169 palette_entries
[1].peBlue
= 0xff;
9170 palette_entries
[2].peGreen
= 0xff;
9171 palette_entries
[3].peRed
= 0xff;
9172 palette_entries
[4].peFlags
= 0x0;
9173 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9174 palette_entries
, &palette2
, NULL
);
9175 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9177 memset(&surface_desc
, 0, sizeof(surface_desc
));
9178 surface_desc
.dwSize
= sizeof(surface_desc
);
9179 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9180 surface_desc
.dwWidth
= 8;
9181 surface_desc
.dwHeight
= 1;
9182 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9183 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9184 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9185 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9186 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9187 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9188 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
9189 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9190 hr
= IDirectDrawSurface7_SetPalette(dst_p8
, palette2
);
9191 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9193 memset(&surface_desc
, 0, sizeof(surface_desc
));
9194 surface_desc
.dwSize
= sizeof(surface_desc
);
9195 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9196 surface_desc
.dwWidth
= 8;
9197 surface_desc
.dwHeight
= 1;
9198 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9199 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9200 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9201 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9202 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9203 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9204 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9205 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9206 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9207 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9209 memset(&surface_desc
, 0, sizeof(surface_desc
));
9210 surface_desc
.dwSize
= sizeof(surface_desc
);
9211 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9212 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
9213 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
9214 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
9215 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
9217 hr
= IDirectDrawSurface7_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9218 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
9219 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
9220 hr
= IDirectDrawSurface7_Unlock(dst_p8
, NULL
);
9221 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
9223 fx
.dwSize
= sizeof(fx
);
9224 fx
.dwFillColor
= 0xdeadbeef;
9225 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
9226 ok(SUCCEEDED(hr
), "Failed to color fill %#x.\n", hr
);
9228 hr
= IDirectDrawSurface7_SetPalette(src
, palette
);
9229 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9230 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9231 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
9232 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
9233 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
9234 "Failed to blit, hr %#x.\n", hr
);
9238 for (x
= 0; x
< ARRAY_SIZE(expected
); ++x
)
9240 color
= get_surface_color(dst
, x
, 0);
9241 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
9242 * blits see below. */
9243 todo_wine
ok(compare_color(color
, expected
[x
], 0)
9244 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
9245 "Pixel %u: Got color %#x, expected %#x.\n",
9246 x
, color
, expected
[x
]);
9250 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
9251 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
9252 hr
= IDirectDrawSurface7_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
9253 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
9255 hr
= IDirectDrawSurface7_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9256 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
9257 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
9258 * surface untouched. Error checking (DDBLT_KEYSRC without a key
9259 * for example) also works as expected.
9261 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
9262 * the display mode set to P8 doesn't help either. */
9263 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
9264 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
9265 "Got unexpected P8 color key blit result.\n");
9266 hr
= IDirectDrawSurface7_Unlock(dst_p8
, NULL
);
9267 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
9269 IDirectDrawSurface7_Release(src
);
9270 IDirectDrawSurface7_Release(dst
);
9271 IDirectDrawSurface7_Release(dst_p8
);
9272 IDirectDrawPalette_Release(palette
);
9273 IDirectDrawPalette_Release(palette2
);
9275 refcount
= IDirectDraw7_Release(ddraw
);
9276 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9277 DestroyWindow(window
);
9280 static void test_material(void)
9282 static const D3DCOLORVALUE null_color
;
9283 IDirect3DDevice7
*device
;
9284 D3DMATERIAL7 material
;
9289 window
= create_window();
9290 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9292 skip("Failed to create a 3D device, skipping test.\n");
9293 DestroyWindow(window
);
9297 hr
= IDirect3DDevice7_GetMaterial(device
, &material
);
9298 ok(SUCCEEDED(hr
), "Failed to get material, hr %#x.\n", hr
);
9299 ok(!memcmp(&U(material
).diffuse
, &null_color
, sizeof(null_color
)),
9300 "Got unexpected diffuse color {%.8e, %.8e, %.8e, %.8e}.\n",
9301 U1(U(material
).diffuse
).r
, U2(U(material
).diffuse
).g
,
9302 U3(U(material
).diffuse
).b
, U4(U(material
).diffuse
).a
);
9303 ok(!memcmp(&U1(material
).ambient
, &null_color
, sizeof(null_color
)),
9304 "Got unexpected ambient color {%.8e, %.8e, %.8e, %.8e}.\n",
9305 U1(U1(material
).ambient
).r
, U2(U1(material
).ambient
).g
,
9306 U3(U1(material
).ambient
).b
, U4(U1(material
).ambient
).a
);
9307 ok(!memcmp(&U2(material
).specular
, &null_color
, sizeof(null_color
)),
9308 "Got unexpected specular color {%.8e, %.8e, %.8e, %.8e}.\n",
9309 U1(U2(material
).specular
).r
, U2(U2(material
).specular
).g
,
9310 U3(U2(material
).specular
).b
, U4(U2(material
).specular
).a
);
9311 ok(!memcmp(&U3(material
).emissive
, &null_color
, sizeof(null_color
)),
9312 "Got unexpected emissive color {%.8e, %.8e, %.8e, %.8e}.\n",
9313 U1(U3(material
).emissive
).r
, U2(U3(material
).emissive
).g
,
9314 U3(U3(material
).emissive
).b
, U4(U3(material
).emissive
).a
);
9315 ok(U4(material
).power
== 0.0f
, "Got unexpected power %.8e.\n", U4(material
).power
);
9317 refcount
= IDirect3DDevice7_Release(device
);
9318 ok(!refcount
, "Device has %u references left.\n", refcount
);
9319 DestroyWindow(window
);
9322 static void test_palette_gdi(void)
9324 IDirectDrawSurface7
*surface
, *primary
;
9325 DDSURFACEDESC2 surface_desc
;
9326 IDirectDraw7
*ddraw
;
9327 IDirectDrawPalette
*palette
, *palette2
;
9331 PALETTEENTRY palette_entries
[256];
9337 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
9338 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
9339 * not the point of this test. */
9340 static const RGBQUAD expected1
[] =
9342 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9343 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
9345 static const RGBQUAD expected2
[] =
9347 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9348 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
9350 static const RGBQUAD expected3
[] =
9352 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
9353 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
9355 HPALETTE ddraw_palette_handle
;
9356 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
9357 RGBQUAD rgbquad
[255];
9358 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
9360 window
= create_window();
9361 ddraw
= create_ddraw();
9362 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9363 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9364 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9366 memset(&surface_desc
, 0, sizeof(surface_desc
));
9367 surface_desc
.dwSize
= sizeof(surface_desc
);
9368 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9369 surface_desc
.dwWidth
= 16;
9370 surface_desc
.dwHeight
= 16;
9371 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9372 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9373 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9374 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9375 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9376 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9378 /* Avoid colors from the Windows default palette. */
9379 memset(palette_entries
, 0, sizeof(palette_entries
));
9380 palette_entries
[1].peRed
= 0x01;
9381 palette_entries
[2].peGreen
= 0x02;
9382 palette_entries
[3].peBlue
= 0x03;
9383 palette_entries
[4].peRed
= 0x13;
9384 palette_entries
[4].peGreen
= 0x14;
9385 palette_entries
[4].peBlue
= 0x15;
9386 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9387 palette_entries
, &palette
, NULL
);
9388 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9390 /* If there is no palette assigned and the display mode is not 8 bpp, some
9391 * drivers refuse to create a DC while others allow it. If a DC is created,
9392 * the DIB color table is uninitialized and contains random colors. No error
9393 * is generated when trying to read pixels and random garbage is returned.
9395 * The most likely explanation is that if the driver creates a DC, it (or
9396 * the higher-level runtime) uses GetSystemPaletteEntries to find the
9397 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
9398 * contains uninitialized garbage. See comments below for the P8 case. */
9400 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9401 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9402 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9403 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9404 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9405 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9406 "Got unexpected palette %p, expected %p.\n",
9407 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9409 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9410 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9411 for (i
= 0; i
< ARRAY_SIZE(expected1
); ++i
)
9413 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
9414 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9415 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9416 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
9418 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9420 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9421 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9422 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9425 /* Update the palette while the DC is in use. This does not modify the DC. */
9426 palette_entries
[4].peRed
= 0x23;
9427 palette_entries
[4].peGreen
= 0x24;
9428 palette_entries
[4].peBlue
= 0x25;
9429 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
9430 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
9432 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9433 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9434 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9435 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9436 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9437 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9439 /* Neither does re-setting the palette. */
9440 hr
= IDirectDrawSurface7_SetPalette(surface
, NULL
);
9441 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9442 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9443 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9445 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9446 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9447 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9448 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9449 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9450 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9452 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9453 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9455 /* Refresh the DC. This updates the palette. */
9456 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9457 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9458 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9459 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9460 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9462 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9463 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9464 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9465 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9467 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9469 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9470 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9471 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9473 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9474 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9476 refcount
= IDirectDrawSurface7_Release(surface
);
9477 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9479 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
9480 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9481 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9483 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9484 IDirectDrawPalette_Release(palette
);
9485 IDirectDraw7_Release(ddraw
);
9486 DestroyWindow(window
);
9489 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
9491 memset(&surface_desc
, 0, sizeof(surface_desc
));
9492 surface_desc
.dwSize
= sizeof(surface_desc
);
9493 surface_desc
.dwFlags
= DDSD_CAPS
;
9494 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9495 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9496 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9498 memset(&fx
, 0, sizeof(fx
));
9499 fx
.dwSize
= sizeof(fx
);
9500 U5(fx
).dwFillColor
= 3;
9501 SetRect(&r
, 0, 0, 319, 479);
9502 hr
= IDirectDrawSurface7_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9503 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
9504 SetRect(&r
, 320, 0, 639, 479);
9505 U5(fx
).dwFillColor
= 4;
9506 hr
= IDirectDrawSurface7_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9507 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
9509 hr
= IDirectDrawSurface7_SetPalette(primary
, palette
);
9510 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9511 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
9512 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9514 color
= GetPixel(dc
, 160, 240);
9515 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
9516 color
= GetPixel(dc
, 480, 240);
9517 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
9519 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9520 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9521 "Got unexpected palette %p, expected %p.\n",
9522 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9523 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
9525 /* The primary uses the system palette. In exclusive mode, the system palette matches
9526 * the ddraw palette attached to the primary, so the result is what you would expect
9527 * from a regular surface. Tests for the interaction between the ddraw palette and
9528 * the system palette are not included pending an application that depends on this.
9529 * The relation between those causes problems on Windows Vista and newer for games
9530 * like Age of Empires or StarcCaft. Don't emulate it without a real need. */
9531 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9532 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9533 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9535 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9536 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9537 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9538 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9540 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9542 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9543 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9544 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9546 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
9547 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9549 memset(&surface_desc
, 0, sizeof(surface_desc
));
9550 surface_desc
.dwSize
= sizeof(surface_desc
);
9551 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9552 surface_desc
.dwWidth
= 16;
9553 surface_desc
.dwHeight
= 16;
9554 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9555 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9556 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9558 /* Here the offscreen surface appears to use the primary's palette,
9559 * but in all likelihood it is actually the system palette. */
9560 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9561 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9562 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9563 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9564 for (i
= 0; i
< ARRAY_SIZE(expected2
); ++i
)
9566 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9567 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9568 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9569 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9571 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9573 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9574 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9575 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9577 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9578 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9580 /* On real hardware a change to the primary surface's palette applies immediately,
9581 * even on device contexts from offscreen surfaces that do not have their own
9582 * palette. On the testbot VMs this is not the case. Don't test this until we
9583 * know of an application that depends on this. */
9585 memset(palette_entries
, 0, sizeof(palette_entries
));
9586 palette_entries
[1].peBlue
= 0x40;
9587 palette_entries
[2].peRed
= 0x40;
9588 palette_entries
[3].peGreen
= 0x40;
9589 palette_entries
[4].peRed
= 0x12;
9590 palette_entries
[4].peGreen
= 0x34;
9591 palette_entries
[4].peBlue
= 0x56;
9592 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9593 palette_entries
, &palette2
, NULL
);
9594 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9595 hr
= IDirectDrawSurface7_SetPalette(surface
, palette2
);
9596 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
9598 /* A palette assigned to the offscreen surface overrides the primary / system
9600 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9601 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9602 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9603 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9604 for (i
= 0; i
< ARRAY_SIZE(expected3
); ++i
)
9606 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
9607 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9608 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9609 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
9611 for (; i
< ARRAY_SIZE(rgbquad
); ++i
)
9613 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9614 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9615 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9617 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9618 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9620 refcount
= IDirectDrawSurface7_Release(surface
);
9621 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9623 /* The Windows 8 testbot keeps extra references to the primary and
9624 * backbuffer while in 8 bpp mode. */
9625 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
9626 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9628 refcount
= IDirectDrawSurface7_Release(primary
);
9629 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9630 refcount
= IDirectDrawPalette_Release(palette2
);
9631 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9632 refcount
= IDirectDrawPalette_Release(palette
);
9633 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9634 refcount
= IDirectDraw7_Release(ddraw
);
9635 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9636 DestroyWindow(window
);
9639 static void test_palette_alpha(void)
9641 IDirectDrawSurface7
*surface
;
9642 DDSURFACEDESC2 surface_desc
;
9643 IDirectDraw7
*ddraw
;
9644 IDirectDrawPalette
*palette
;
9648 PALETTEENTRY palette_entries
[256];
9653 BOOL attach_allowed
;
9658 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
9659 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
9660 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
9663 window
= create_window();
9664 ddraw
= create_ddraw();
9665 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9666 if (FAILED(IDirectDraw7_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9668 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9669 IDirectDraw7_Release(ddraw
);
9670 DestroyWindow(window
);
9673 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9674 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9676 memset(palette_entries
, 0, sizeof(palette_entries
));
9677 palette_entries
[1].peFlags
= 0x42;
9678 palette_entries
[2].peFlags
= 0xff;
9679 palette_entries
[3].peFlags
= 0x80;
9680 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
9681 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9683 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9684 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9685 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9686 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9687 palette_entries
[0].peFlags
);
9688 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9689 palette_entries
[1].peFlags
);
9690 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9691 palette_entries
[2].peFlags
);
9692 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9693 palette_entries
[3].peFlags
);
9695 IDirectDrawPalette_Release(palette
);
9697 memset(palette_entries
, 0, sizeof(palette_entries
));
9698 palette_entries
[1].peFlags
= 0x42;
9699 palette_entries
[1].peRed
= 0xff;
9700 palette_entries
[2].peFlags
= 0xff;
9701 palette_entries
[3].peFlags
= 0x80;
9702 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
9703 palette_entries
, &palette
, NULL
);
9704 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9706 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9707 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9708 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9709 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9710 palette_entries
[0].peFlags
);
9711 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9712 palette_entries
[1].peFlags
);
9713 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9714 palette_entries
[2].peFlags
);
9715 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9716 palette_entries
[3].peFlags
);
9718 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
9720 memset(&surface_desc
, 0, sizeof(surface_desc
));
9721 surface_desc
.dwSize
= sizeof(surface_desc
);
9722 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
9723 surface_desc
.dwWidth
= 128;
9724 surface_desc
.dwHeight
= 128;
9725 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
9726 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9727 if (is_ddraw64
&& test_data
[i
].caps
& DDSCAPS_TEXTURE
)
9728 todo_wine
ok(hr
== E_NOINTERFACE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
9730 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
9734 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9735 if (test_data
[i
].attach_allowed
)
9736 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
9738 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9746 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
9747 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9748 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
9749 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
9750 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
9751 rgbquad
.rgbRed
, test_data
[i
].name
);
9752 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
9753 rgbquad
.rgbGreen
, test_data
[i
].name
);
9754 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
9755 rgbquad
.rgbBlue
, test_data
[i
].name
);
9756 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
9757 rgbquad
.rgbReserved
, test_data
[i
].name
);
9758 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
9759 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9761 IDirectDrawSurface7_Release(surface
);
9764 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
9765 memset(&surface_desc
, 0, sizeof(surface_desc
));
9766 surface_desc
.dwSize
= sizeof(surface_desc
);
9767 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9768 surface_desc
.dwWidth
= 128;
9769 surface_desc
.dwHeight
= 128;
9770 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9771 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9772 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9773 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9774 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9775 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9776 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9777 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9778 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9779 hr
= IDirectDrawSurface7_SetPalette(surface
, palette
);
9780 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
9781 IDirectDrawSurface7_Release(surface
);
9783 /* The Windows 8 testbot keeps extra references to the primary
9784 * while in 8 bpp mode. */
9785 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
9786 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9788 refcount
= IDirectDrawPalette_Release(palette
);
9789 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9790 refcount
= IDirectDraw7_Release(ddraw
);
9791 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9792 DestroyWindow(window
);
9795 static void test_vb_writeonly(void)
9797 IDirect3DDevice7
*device
;
9799 IDirect3DVertexBuffer7
*buffer
;
9802 D3DVERTEXBUFFERDESC desc
;
9804 static const struct vec4 quad
[] =
9806 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
9807 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
9808 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
9809 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
9812 window
= create_window();
9813 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9815 skip("Failed to create a 3D device, skipping test.\n");
9816 DestroyWindow(window
);
9820 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
9821 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9823 memset(&desc
, 0, sizeof(desc
));
9824 desc
.dwSize
= sizeof(desc
);
9825 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
9826 desc
.dwFVF
= D3DFVF_XYZRHW
;
9827 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
9828 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0);
9829 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
9831 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
9832 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9833 memcpy(ptr
, quad
, sizeof(quad
));
9834 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9835 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9837 hr
= IDirect3DDevice7_BeginScene(device
);
9838 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9839 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
9840 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9841 hr
= IDirect3DDevice7_EndScene(device
);
9842 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9844 hr
= IDirect3DVertexBuffer7_Lock(buffer
, 0, &ptr
, NULL
);
9845 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9846 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9847 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9848 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9850 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
9851 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9852 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9853 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
9854 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9856 IDirect3DVertexBuffer7_Release(buffer
);
9857 IDirect3D7_Release(d3d
);
9858 IDirect3DDevice7_Release(device
);
9859 DestroyWindow(window
);
9862 static void test_lost_device(void)
9864 IDirectDrawSurface7
*sysmem_surface
, *vidmem_surface
;
9865 IDirectDrawSurface7
*surface
, *back_buffer
;
9866 DDSURFACEDESC2 surface_desc
;
9867 HWND window1
, window2
;
9868 IDirectDraw7
*ddraw
;
9874 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9875 0, 0, 640, 480, 0, 0, 0, 0);
9876 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9877 0, 0, 640, 480, 0, 0, 0, 0);
9878 ddraw
= create_ddraw();
9879 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9880 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9881 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9883 memset(&surface_desc
, 0, sizeof(surface_desc
));
9884 surface_desc
.dwSize
= sizeof(surface_desc
);
9885 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9886 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9887 U5(surface_desc
).dwBackBufferCount
= 1;
9888 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9889 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9891 memset(&surface_desc
, 0, sizeof(surface_desc
));
9892 surface_desc
.dwSize
= sizeof(surface_desc
);
9893 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9894 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9895 surface_desc
.dwWidth
= 100;
9896 surface_desc
.dwHeight
= 100;
9897 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
9898 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9900 memset(&surface_desc
, 0, sizeof(surface_desc
));
9901 surface_desc
.dwSize
= sizeof(surface_desc
);
9902 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9903 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
9904 surface_desc
.dwWidth
= 64;
9905 surface_desc
.dwHeight
= 64;
9906 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9907 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9908 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9909 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9910 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9911 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9912 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
9914 skip("Failed to create video memory surface, skipping related tests.\n");
9915 vidmem_surface
= NULL
;
9918 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
9919 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9920 hr
= IDirectDrawSurface7_IsLost(surface
);
9921 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9922 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
9923 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9924 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
9925 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9928 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
9929 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9932 ret
= SetForegroundWindow(GetDesktopWindow());
9933 ok(ret
, "Failed to set foreground window.\n");
9934 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
9935 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9936 hr
= IDirectDrawSurface7_IsLost(surface
);
9937 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9938 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
9939 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9940 hr
= IDirectDrawSurface7_Restore(surface
);
9941 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
9942 hr
= IDirectDrawSurface7_IsLost(surface
);
9943 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9944 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
9945 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9946 hr
= IDirectDrawSurface7_Restore(sysmem_surface
);
9947 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9948 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
9949 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9952 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
9953 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9954 hr
= IDirectDrawSurface7_Restore(vidmem_surface
);
9955 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
9956 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
9957 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9960 ret
= SetForegroundWindow(window1
);
9961 ok(ret
, "Failed to set foreground window.\n");
9962 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
9963 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9964 hr
= IDirectDrawSurface7_IsLost(surface
);
9965 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9966 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
9967 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9968 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
9969 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9972 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
9973 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9976 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
9977 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9978 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
9979 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9980 hr
= IDirectDrawSurface7_IsLost(surface
);
9981 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9982 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
9983 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9984 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
9985 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9988 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
9989 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9992 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9993 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9994 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
9995 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9996 hr
= IDirectDrawSurface7_IsLost(surface
);
9997 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9998 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
9999 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10000 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10001 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10002 if (vidmem_surface
)
10004 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10005 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10008 /* Trying to restore the primary will crash, probably because flippable
10009 * surfaces can't exist in DDSCL_NORMAL. */
10010 IDirectDrawSurface7_Release(surface
);
10011 memset(&surface_desc
, 0, sizeof(surface_desc
));
10012 surface_desc
.dwSize
= sizeof(surface_desc
);
10013 surface_desc
.dwFlags
= DDSD_CAPS
;
10014 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10015 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10016 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10017 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10018 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10019 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
10020 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10022 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10023 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10024 hr
= IDirectDrawSurface7_IsLost(surface
);
10025 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10026 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10027 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10028 if (vidmem_surface
)
10030 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10031 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10034 ret
= SetForegroundWindow(GetDesktopWindow());
10035 ok(ret
, "Failed to set foreground window.\n");
10036 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10037 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10038 hr
= IDirectDrawSurface7_IsLost(surface
);
10039 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10040 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10041 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10042 if (vidmem_surface
)
10044 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10045 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10048 ret
= SetForegroundWindow(window1
);
10049 ok(ret
, "Failed to set foreground window.\n");
10050 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10051 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10052 hr
= IDirectDrawSurface7_IsLost(surface
);
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 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10063 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10064 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10065 ok(hr
== DD_OK
, "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_IsLost(sysmem_surface
);
10069 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10070 if (vidmem_surface
)
10072 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10073 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10076 hr
= IDirectDraw7_RestoreAllSurfaces(ddraw
);
10077 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10078 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10079 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10080 hr
= IDirectDrawSurface7_IsLost(surface
);
10081 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10082 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10083 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10084 if (vidmem_surface
)
10086 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10087 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10090 IDirectDrawSurface7_Release(surface
);
10091 memset(&surface_desc
, 0, sizeof(surface_desc
));
10092 surface_desc
.dwSize
= sizeof(surface_desc
);
10093 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10094 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
10095 U5(surface_desc
).dwBackBufferCount
= 1;
10096 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10097 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10099 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10100 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10101 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10102 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10103 hr
= IDirectDrawSurface7_IsLost(surface
);
10104 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10105 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10106 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10107 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10108 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10109 if (vidmem_surface
)
10111 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10112 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10115 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10116 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10117 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10118 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10119 hr
= IDirectDrawSurface7_IsLost(surface
);
10120 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10121 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10122 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10123 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10124 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10125 if (vidmem_surface
)
10127 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10128 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10131 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
10132 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10133 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10134 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10135 hr
= IDirectDrawSurface7_IsLost(surface
);
10136 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10137 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10138 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10139 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10140 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10141 if (vidmem_surface
)
10143 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10144 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10147 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
10148 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10149 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10150 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10151 hr
= IDirectDrawSurface7_IsLost(surface
);
10152 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10153 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10154 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10155 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10156 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10157 if (vidmem_surface
)
10159 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10160 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10163 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10164 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10165 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10166 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10167 hr
= IDirectDrawSurface7_IsLost(surface
);
10168 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10169 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10170 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
10171 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10172 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10173 if (vidmem_surface
)
10175 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10176 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10179 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10180 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10181 hr
= IDirectDraw7_TestCooperativeLevel(ddraw
);
10182 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10183 hr
= IDirectDrawSurface7_IsLost(surface
);
10184 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10185 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
10186 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10187 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
10188 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10189 if (vidmem_surface
)
10191 hr
= IDirectDrawSurface7_IsLost(vidmem_surface
);
10192 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10195 memset(&caps
, 0, sizeof(caps
));
10196 caps
.dwCaps
= DDSCAPS_FLIP
;
10198 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10199 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
10200 hr
= IDirectDrawSurface7_Restore(surface
);
10201 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10202 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10203 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10204 hr
= IDirectDrawSurface7_IsLost(back_buffer
);
10205 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
10207 IDirectDrawSurface7_Release(back_buffer
);
10209 if (vidmem_surface
)
10210 IDirectDrawSurface7_Release(vidmem_surface
);
10211 IDirectDrawSurface7_Release(sysmem_surface
);
10212 IDirectDrawSurface7_Release(surface
);
10213 refcount
= IDirectDraw7_Release(ddraw
);
10214 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10215 DestroyWindow(window2
);
10216 DestroyWindow(window1
);
10219 static void test_resource_priority(void)
10221 IDirectDrawSurface7
*surface
, *mipmap
;
10222 DDSURFACEDESC2 surface_desc
;
10223 IDirectDraw7
*ddraw
;
10227 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
10229 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_MIPMAP
;
10232 static const struct
10237 /* SetPriority on offscreenplain surfaces crashes on AMD GPUs on Win7. */
10242 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", DDERR_INVALIDPARAMS
, FALSE
},
10243 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", DDERR_INVALIDPARAMS
, FALSE
},
10244 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", DD_OK
, FALSE
},
10245 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, "managed texture", DD_OK
, FALSE
},
10246 {DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
,
10247 DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_TEXTUREMANAGE
,
10248 "cubemap", DD_OK
, FALSE
},
10249 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", DDERR_INVALIDOBJECT
, TRUE
},
10250 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", DDERR_INVALIDOBJECT
, TRUE
},
10253 window
= create_window();
10254 ddraw
= create_ddraw();
10255 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10256 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10257 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10259 memset(&hal_caps
, 0, sizeof(hal_caps
));
10260 hal_caps
.dwSize
= sizeof(hal_caps
);
10261 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
10262 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
10263 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
10264 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
10266 skip("Required surface types not supported, skipping test.\n");
10270 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10272 memset(&surface_desc
, 0, sizeof(surface_desc
));
10273 surface_desc
.dwSize
= sizeof(surface_desc
);
10274 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10275 surface_desc
.dwWidth
= 32;
10276 surface_desc
.dwHeight
= 32;
10277 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
10278 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2
;
10279 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10280 if (is_ddraw64
&& (test_data
[i
].caps
& DDSCAPS_TEXTURE
))
10282 todo_wine
ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10284 IDirectDrawSurface7_Release(surface
);
10287 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10289 /* Priority == NULL segfaults. */
10290 priority
= 0xdeadbeef;
10291 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10292 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10293 if (SUCCEEDED(test_data
[i
].hr
))
10294 ok(priority
== 0, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10296 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10298 if (!test_data
[i
].crash
)
10300 hr
= IDirectDrawSurface7_SetPriority(surface
, 1);
10301 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10302 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10303 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10304 if (SUCCEEDED(test_data
[i
].hr
))
10306 ok(priority
== 1, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10307 hr
= IDirectDrawSurface7_SetPriority(surface
, 2);
10308 ok(hr
== test_data
[i
].hr
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10311 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10314 if (test_data
[i
].caps2
& DDSCAPS2_CUBEMAP
)
10316 caps
.dwCaps2
= DDSCAPS2_CUBEMAP_NEGATIVEZ
;
10317 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
10318 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
10319 /* IDirectDrawSurface7_SetPriority crashes when called on non-positive X surfaces on Windows */
10320 priority
= 0xdeadbeef;
10321 hr
= IDirectDrawSurface7_GetPriority(mipmap
, &priority
);
10322 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, test_data
[i
].name
);
10323 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority
, test_data
[i
].name
);
10325 IDirectDrawSurface7_Release(mipmap
);
10328 IDirectDrawSurface7_Release(surface
);
10334 memset(&surface_desc
, 0, sizeof(surface_desc
));
10335 surface_desc
.dwSize
= sizeof(surface_desc
);
10336 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
10337 surface_desc
.dwWidth
= 32;
10338 surface_desc
.dwHeight
= 32;
10339 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
10340 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
10341 U2(surface_desc
).dwMipMapCount
= 2;
10342 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10343 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10345 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &mipmap
);
10346 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
10348 priority
= 0xdeadbeef;
10349 hr
= IDirectDrawSurface7_GetPriority(mipmap
, &priority
);
10350 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type managed mipmap.\n", hr
);
10351 ok(priority
== 0xdeadbeef, "Got unexpected priority %u, type managed mipmap.\n", priority
);
10352 /* SetPriority on the mipmap surface crashes. */
10353 hr
= IDirectDrawSurface7_GetPriority(surface
, &priority
);
10354 ok(SUCCEEDED(hr
), "Failed to get priority, hr %#x.\n", hr
);
10355 ok(priority
== 0, "Got unexpected priority %u, type managed mipmap.\n", priority
);
10357 IDirectDrawSurface7_Release(mipmap
);
10358 refcount
= IDirectDrawSurface7_Release(surface
);
10359 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10362 refcount
= IDirectDraw7_Release(ddraw
);
10363 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10364 DestroyWindow(window
);
10367 static void test_surface_desc_lock(void)
10369 IDirectDrawSurface7
*surface
;
10370 DDSURFACEDESC2 surface_desc
;
10371 IDirectDraw7
*ddraw
;
10376 window
= create_window();
10377 ddraw
= create_ddraw();
10378 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10379 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10380 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10382 memset(&surface_desc
, 0, sizeof(surface_desc
));
10383 surface_desc
.dwSize
= sizeof(surface_desc
);
10384 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
10385 surface_desc
.dwWidth
= 16;
10386 surface_desc
.dwHeight
= 16;
10387 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10388 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10389 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10391 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10392 surface_desc
.dwSize
= sizeof(surface_desc
);
10393 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10394 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10395 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10397 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10398 surface_desc
.dwSize
= sizeof(surface_desc
);
10399 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
10400 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10401 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10402 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10403 surface_desc
.dwSize
= sizeof(surface_desc
);
10404 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10405 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10406 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10407 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
10408 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10410 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10411 surface_desc
.dwSize
= sizeof(surface_desc
);
10412 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
10413 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10414 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10416 IDirectDrawSurface7_Release(surface
);
10417 refcount
= IDirectDraw7_Release(ddraw
);
10418 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10419 DestroyWindow(window
);
10422 static void test_fog_interpolation(void)
10425 IDirect3DDevice7
*device
;
10426 IDirectDrawSurface7
*rt
;
10432 struct vec3 position
;
10438 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
10439 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff000000},
10440 {{ 1.0f
, -1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
10441 {{ 1.0f
, 1.0f
, 1.0f
}, 0xffff0000, 0x00000000},
10449 static const struct
10451 D3DFOGMODE vfog
, tfog
;
10452 D3DSHADEMODE shade
;
10453 D3DCOLOR middle_color
;
10458 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, FALSE
},
10459 {D3DFOG_NONE
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, FALSE
},
10460 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_FLAT
, 0x00007f80, TRUE
},
10461 {D3DFOG_EXP
, D3DFOG_NONE
, D3DSHADE_GOURAUD
, 0x00007f80, TRUE
},
10462 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
10463 {D3DFOG_NONE
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
10464 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_FLAT
, 0x0000ea15, FALSE
},
10465 {D3DFOG_EXP
, D3DFOG_EXP
, D3DSHADE_GOURAUD
, 0x0000ea15, FALSE
},
10467 D3DDEVICEDESC7 caps
;
10469 window
= create_window();
10470 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10472 skip("Failed to create a 3D device, skipping test.\n");
10473 DestroyWindow(window
);
10477 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
10478 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10479 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
10480 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10481 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
10482 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
10484 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10485 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10486 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10487 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10488 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10489 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10490 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
10491 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10493 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGDENSITY
, conv
.d
);
10494 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10496 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10497 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10498 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
10499 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10500 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x000000ff);
10501 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10503 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10505 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
10508 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00808080, 0.0f
, 0);
10509 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10511 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shade
);
10512 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10513 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vfog
);
10514 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10515 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tfog
);
10516 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10517 hr
= IDirect3DDevice7_BeginScene(device
);
10518 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10519 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10520 D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, quad
, 4, 0);
10521 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10522 hr
= IDirect3DDevice7_EndScene(device
);
10523 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10525 color
= get_surface_color(rt
, 0, 240);
10526 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10527 color
= get_surface_color(rt
, 320, 240);
10528 todo_wine_if (tests
[i
].todo
)
10529 ok(compare_color(color
, tests
[i
].middle_color
, 2),
10530 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10531 color
= get_surface_color(rt
, 639, 240);
10532 ok(compare_color(color
, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10535 IDirectDrawSurface7_Release(rt
);
10536 refcount
= IDirect3DDevice7_Release(device
);
10537 ok(!refcount
, "Device has %u references left.\n", refcount
);
10538 DestroyWindow(window
);
10541 static void test_fog_process_vertices(void)
10543 static D3DMATRIX view_matrix
=
10545 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10546 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10547 0.0f
, 0.0f
, 0.5f
, 0.0f
,
10548 0.0f
, 0.0f
, 0.0f
, 1.0f
10550 static D3DMATRIX model_matrix
=
10552 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10553 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10554 0.0f
, 0.0f
, 0.75f
, 0.0f
,
10555 0.0f
, 0.0f
, 0.0f
, 1.0f
10557 static D3DMATRIX identity_matrix
=
10559 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10560 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10561 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10562 0.0f
, 0.0f
, 0.0f
, 1.0f
10565 static D3DLIGHT7 directional_light
=
10567 D3DLIGHT_DIRECTIONAL
,
10568 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
10569 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
10570 {{0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
10571 {{0.0f
}, {0.0f
}, {0.0f
}},
10572 {{0.0f
}, {0.0f
}, {1.0f
}},
10577 struct vec3 position
;
10578 struct vec3 normal
;
10580 static const struct
10582 struct vertex vertex
;
10583 D3DFOGMODE fog_vertex_mode
, fog_table_mode
;
10585 D3DCOLOR expected_color
, expected_broken
;
10589 /* Some drivers ignore ranged fog state without an obvious reason, even with D3DPRASTERCAPS_FOGRANGE
10590 * set, while some others (including WARP driver on Windows 10) favour it.
10591 * Vertex fog result does not depend on table fog settings. */
10592 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_NONE
, FALSE
, 0x8000ff00},
10593 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_LINEAR
, FALSE
, 0x8000ff00},
10594 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_NONE
, FALSE
, 0xaf00ff00},
10595 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP2
, D3DFOG_NONE
, FALSE
, 0xde00ff00},
10596 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_NONE
, FALSE
, 0x9f00ff00},
10597 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_LINEAR
, FALSE
, 0x9f00ff00},
10598 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_NONE
, D3DFOG_NONE
, TRUE
, 0x8000ff00},
10599 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_NONE
, TRUE
, 0x8800ff00, 0xaf00ff00},
10600 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP2
, D3DFOG_NONE
, TRUE
, 0xad00ff00, 0xde00ff00},
10601 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_NONE
, TRUE
, 0x6000ff00, 0x9f00ff00},
10602 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_LINEAR
, D3DFOG_EXP
, TRUE
, 0x6000ff00, 0x9f00ff00},
10603 {{{0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}}, D3DFOG_EXP
, D3DFOG_LINEAR
, TRUE
, 0x8800ff00, 0xaf00ff00},
10608 struct vec4 position
;
10609 D3DCOLOR diffuse
, specular
;
10613 IDirect3DVertexBuffer7
*src_vb
, *dst_vb
;
10614 D3DVERTEXBUFFERDESC vb_desc
;
10615 IDirect3DDevice7
*device
;
10616 struct vertex
*src_data
;
10617 D3DMATERIAL7 material
;
10624 window
= create_window();
10625 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10627 skip("Failed to create a 3D device, skipping test.\n");
10628 DestroyWindow(window
);
10631 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
10632 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10634 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &model_matrix
);
10635 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10636 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &view_matrix
);
10637 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10638 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity_matrix
);
10639 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10641 memset(&vb_desc
, 0, sizeof(vb_desc
));
10642 vb_desc
.dwSize
= sizeof(vb_desc
);
10643 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
10644 vb_desc
.dwNumVertices
= 1;
10645 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0);
10646 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10648 memset(&vb_desc
, 0, sizeof(vb_desc
));
10649 vb_desc
.dwSize
= sizeof(vb_desc
);
10650 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
10651 vb_desc
.dwNumVertices
= 1;
10652 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0);
10653 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10655 hr
= IDirect3DDevice7_LightEnable(device
, 0, TRUE
);
10656 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10657 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
10658 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10659 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
10660 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10661 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10662 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10663 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10664 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10666 hr
= IDirect3DDevice7_SetLight(device
, 0, &directional_light
);
10667 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10669 memset(&material
, 0, sizeof(material
));
10670 U1(U2(material
).specular
).r
= 0.0f
;
10671 U2(U2(material
).specular
).g
= 1.0f
;
10672 U3(U2(material
).specular
).b
= 0.0f
;
10673 U4(U2(material
).specular
).a
= 0.5f
;
10674 U4(material
).power
= 5.0f
;
10675 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
10676 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10678 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10680 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
,
10681 tests
[i
].fog_vertex_mode
);
10682 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
,
10683 tests
[i
].fog_table_mode
);
10684 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10685 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_RANGEFOGENABLE
, tests
[i
].range_fog
);
10686 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10688 hr
= IDirect3DVertexBuffer7_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
10689 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10690 *src_data
= tests
[i
].vertex
;
10691 hr
= IDirect3DVertexBuffer7_Unlock(src_vb
);
10692 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10694 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
10695 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10696 memset(dst_data
, 0, sizeof(*dst_data
));
10697 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
10698 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10699 hr
= IDirect3DVertexBuffer7_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
10700 1, src_vb
, 0, device
, 0);
10701 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10703 hr
= IDirect3DVertexBuffer7_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
10704 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10706 ok(compare_color(dst_data
->specular
, tests
[i
].expected_color
, 1)
10707 || broken(tests
[i
].expected_broken
10708 && compare_color(dst_data
->specular
, tests
[i
].expected_broken
, 1)),
10709 "Expected color 0x%08x, got 0x%08x, test %u.\n",
10710 tests
[i
].expected_color
, dst_data
->specular
, i
);
10712 hr
= IDirect3DVertexBuffer7_Unlock(dst_vb
);
10713 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
10716 IDirect3DVertexBuffer7_Release(dst_vb
);
10717 IDirect3DVertexBuffer7_Release(src_vb
);
10718 IDirect3D7_Release(d3d
);
10719 refcount
= IDirect3DDevice7_Release(device
);
10720 ok(!refcount
, "Device has %u references left.\n", refcount
);
10721 DestroyWindow(window
);
10724 static void test_negative_fixedfunction_fog(void)
10727 IDirect3DDevice7
*device
;
10728 IDirectDrawSurface7
*rt
;
10734 struct vec3 position
;
10739 {{-1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
10740 {{-1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
10741 {{ 1.0f
, -1.0f
, -0.5f
}, 0xffff0000},
10742 {{ 1.0f
, 1.0f
, -0.5f
}, 0xffff0000},
10746 struct vec4 position
;
10751 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10752 {{640.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10753 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10754 {{640.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xffff0000},
10757 static D3DMATRIX zero
=
10759 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10760 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10761 0.0f
, 0.0f
, 0.0f
, 0.0f
,
10762 0.0f
, 0.0f
, 0.0f
, 1.0f
10764 static D3DMATRIX identity
=
10766 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10767 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10768 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10769 0.0f
, 0.0f
, 0.0f
, 1.0f
10771 static const struct
10781 D3DFOGMODE vfog
, tfog
;
10782 DWORD color
, color_broken
, color_broken2
;
10786 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
10788 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
10789 {D3DFVF_XYZRHW
, tquad
, &identity
, { 0.0f
}, {1.0f
}, D3DFOG_NONE
, D3DFOG_LINEAR
,
10790 0x00ff0000, 0x00808000, 0x00808000},
10791 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
10792 * parameters to 0.0 and 1.0 in the table fog case. */
10793 {D3DFVF_XYZRHW
, tquad
, &identity
, {-1.0f
}, {0.0f
}, D3DFOG_NONE
, D3DFOG_LINEAR
,
10794 0x00808000, 0x00ff0000, 0x0000ff00},
10795 /* test_fog_interpolation shows that vertex fog evaluates the fog
10796 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
10797 * that the abs happens before the fog equation is evaluated.
10799 * Vertex fog abs() behavior is the same on all GPUs. */
10800 {D3DFVF_XYZ
, quad
, &zero
, { 0.0f
}, {1.0f
}, D3DFOG_LINEAR
, D3DFOG_NONE
,
10801 0x00808000, 0x00808000, 0x00808000},
10802 {D3DFVF_XYZ
, quad
, &zero
, {-1.0f
}, {0.0f
}, D3DFOG_LINEAR
, D3DFOG_NONE
,
10803 0x0000ff00, 0x0000ff00, 0x0000ff00},
10804 {D3DFVF_XYZ
, quad
, &zero
, { 0.0f
}, {1.0f
}, D3DFOG_EXP
, D3DFOG_NONE
,
10805 0x009b6400, 0x009b6400, 0x009b6400},
10807 D3DDEVICEDESC7 caps
;
10809 window
= create_window();
10810 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10812 skip("Failed to create a 3D device, skipping test.\n");
10813 DestroyWindow(window
);
10817 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
10818 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10819 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
10820 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10821 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
10822 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
10824 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10825 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10826 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10827 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10828 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10829 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10830 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
10831 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10832 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10833 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
10835 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10837 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
) && tests
[i
].tfog
)
10840 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
10841 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10843 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].matrix
);
10844 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
10845 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGSTART
, tests
[i
].start
.d
);
10846 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10847 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGEND
, tests
[i
].end
.d
);
10848 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10849 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGVERTEXMODE
, tests
[i
].vfog
);
10850 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10851 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, tests
[i
].tfog
);
10852 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10854 hr
= IDirect3DDevice7_BeginScene(device
);
10855 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10856 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10857 tests
[i
].pos_type
| D3DFVF_DIFFUSE
, tests
[i
].quad
, 4, 0);
10858 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10859 hr
= IDirect3DDevice7_EndScene(device
);
10860 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10862 color
= get_surface_color(rt
, 0, 240);
10863 ok(compare_color(color
, tests
[i
].color
, 2) || broken(compare_color(color
, tests
[i
].color_broken
, 2))
10864 || broken(compare_color(color
, tests
[i
].color_broken2
, 2)),
10865 "Got unexpected color 0x%08x, case %u.\n", color
, i
);
10868 IDirectDrawSurface7_Release(rt
);
10869 refcount
= IDirect3DDevice7_Release(device
);
10870 ok(!refcount
, "Device has %u references left.\n", refcount
);
10871 DestroyWindow(window
);
10874 static void test_table_fog_zw(void)
10877 IDirect3DDevice7
*device
;
10878 IDirectDrawSurface7
*rt
;
10884 struct vec4 position
;
10889 {{ 0.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
10890 {{640.0f
, 0.0f
, 0.0f
, 0.0f
}, 0xffff0000},
10891 {{ 0.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
10892 {{640.0f
, 480.0f
, 0.0f
, 0.0f
}, 0xffff0000},
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 D3DDEVICEDESC7 caps
;
10902 static const struct
10905 D3DZBUFFERTYPE z_test
;
10910 {0.7f
, 0.0f
, D3DZB_TRUE
, 0x004cb200},
10911 {0.7f
, 0.0f
, D3DZB_FALSE
, 0x004cb200},
10912 {0.7f
, 0.3f
, D3DZB_TRUE
, 0x004cb200},
10913 {0.7f
, 0.3f
, D3DZB_FALSE
, 0x004cb200},
10914 {0.7f
, 3.0f
, D3DZB_TRUE
, 0x004cb200},
10915 {0.7f
, 3.0f
, D3DZB_FALSE
, 0x004cb200},
10916 {0.3f
, 0.0f
, D3DZB_TRUE
, 0x00b24c00},
10917 {0.3f
, 0.0f
, D3DZB_FALSE
, 0x00b24c00},
10921 window
= create_window();
10922 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10924 skip("Failed to create a 3D device, skipping test.\n");
10925 DestroyWindow(window
);
10929 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
10930 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10931 if (!(caps
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_FOGTABLE
))
10933 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
10936 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
10937 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10939 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10940 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10941 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, TRUE
);
10942 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10943 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGCOLOR
, 0x0000ff00);
10944 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10945 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
10946 ok(SUCCEEDED(hr
), "SetRenderState failed, hr %#x.\n", hr
);
10947 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
10948 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
10949 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
10950 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGTABLEMODE
, D3DFOG_LINEAR
);
10951 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10953 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10955 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0x000000ff, 1.0f
, 0);
10956 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10958 quad
[0].position
.z
= tests
[i
].z
;
10959 quad
[1].position
.z
= tests
[i
].z
;
10960 quad
[2].position
.z
= tests
[i
].z
;
10961 quad
[3].position
.z
= tests
[i
].z
;
10962 quad
[0].position
.w
= tests
[i
].w
;
10963 quad
[1].position
.w
= tests
[i
].w
;
10964 quad
[2].position
.w
= tests
[i
].w
;
10965 quad
[3].position
.w
= tests
[i
].w
;
10966 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, tests
[i
].z_test
);
10967 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10969 hr
= IDirect3DDevice7_BeginScene(device
);
10970 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10971 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10972 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, quad
, 4, 0);
10973 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10974 hr
= IDirect3DDevice7_EndScene(device
);
10975 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10977 color
= get_surface_color(rt
, 0, 240);
10978 ok(compare_color(color
, tests
[i
].color
, 2),
10979 "Got unexpected color 0x%08x, expected 0x%8x, case %u.\n", color
, tests
[i
].color
, i
);
10982 IDirectDrawSurface7_Release(rt
);
10984 refcount
= IDirect3DDevice7_Release(device
);
10985 ok(!refcount
, "Device has %u references left.\n", refcount
);
10986 DestroyWindow(window
);
10989 static void test_signed_formats(void)
10992 IDirect3DDevice7
*device
;
10994 IDirectDraw7
*ddraw
;
10995 IDirectDrawSurface7
*surface
, *rt
;
10996 DDSURFACEDESC2 surface_desc
;
10999 D3DCOLOR color
, expected_color
;
11002 struct vec3 position
;
11003 struct vec2 texcoord
;
11007 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11008 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
11009 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11010 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
11012 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
11013 * of these values. */
11014 static const USHORT content_v8u8
[4][4] =
11016 {0x0000, 0x7f7f, 0x8880, 0x0000},
11017 {0x0080, 0x8000, 0x7f00, 0x007f},
11018 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
11019 {0x4444, 0xc0c0, 0xa066, 0x22e0},
11021 static const DWORD content_x8l8v8u8
[4][4] =
11023 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
11024 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
11025 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
11026 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
11028 static const USHORT content_l6v5u5
[4][4] =
11030 {0x0000, 0xfdef, 0x0230, 0xfc00},
11031 {0x0010, 0x0200, 0x01e0, 0x000f},
11032 {0x4067, 0x53b9, 0x0421, 0xffff},
11033 {0x8108, 0x0318, 0xc28c, 0x909c},
11035 static const struct
11038 const void *content
;
11041 unsigned int slop
, slop_broken
;
11042 DDPIXELFORMAT format
;
11047 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
11049 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
11050 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
11054 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
11056 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11057 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
11061 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
11063 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11064 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
11068 /* No V16U16 or Q8W8V8U8 support in ddraw. */
11070 static const D3DCOLOR expected_colors
[4][4] =
11072 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
11073 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
11074 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
11075 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
11077 unsigned int i
, width
, x
, y
;
11078 D3DDEVICEDESC7 device_desc
;
11080 window
= create_window();
11081 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11083 skip("Failed to create a 3D device, skipping test.\n");
11084 DestroyWindow(window
);
11088 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
11089 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
11090 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
11092 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
11096 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11097 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
11098 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11099 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
11100 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
11101 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11103 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
11104 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11106 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
11107 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
11108 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11109 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
11110 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11111 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11112 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11113 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
11114 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
11116 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
11118 for (width
= 1; width
< 5; width
+= 3)
11120 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
11121 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
11123 memset(&surface_desc
, 0, sizeof(surface_desc
));
11124 surface_desc
.dwSize
= sizeof(surface_desc
);
11125 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
11126 surface_desc
.dwWidth
= width
;
11127 surface_desc
.dwHeight
= 4;
11128 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
11129 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
11130 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11133 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
11136 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11137 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
11138 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11140 memset(&surface_desc
, 0, sizeof(surface_desc
));
11141 surface_desc
.dwSize
= sizeof(surface_desc
);
11142 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
11143 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11144 for (y
= 0; y
< 4; y
++)
11146 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
11147 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
11148 width
* formats
[i
].pixel_size
);
11150 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11151 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
11153 hr
= IDirect3DDevice7_BeginScene(device
);
11154 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11155 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11156 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
11157 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11158 hr
= IDirect3DDevice7_EndScene(device
);
11159 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11161 for (y
= 0; y
< 4; y
++)
11163 for (x
= 0; x
< width
; x
++)
11165 expected_color
= expected_colors
[y
][x
];
11166 if (!formats
[i
].blue
)
11167 expected_color
|= 0x000000ff;
11169 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
11170 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
11171 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
11172 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
11173 expected_color
, color
, formats
[i
].name
, x
, y
);
11177 IDirectDrawSurface7_Release(surface
);
11182 IDirectDrawSurface7_Release(rt
);
11183 IDirectDraw7_Release(ddraw
);
11184 IDirect3D7_Release(d3d
);
11187 refcount
= IDirect3DDevice7_Release(device
);
11188 ok(!refcount
, "Device has %u references left.\n", refcount
);
11189 DestroyWindow(window
);
11192 static void test_color_fill(void)
11195 IDirect3DDevice7
*device
;
11197 IDirectDraw7
*ddraw
;
11198 IDirectDrawSurface7
*surface
, *surface2
;
11199 DDSURFACEDESC2 surface_desc
;
11200 DDPIXELFORMAT z_fmt
;
11205 RECT rect
= {5, 5, 7, 7};
11207 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
11209 static const struct
11212 HRESULT colorfill_hr
, depthfill_hr
;
11217 DDPIXELFORMAT format
;
11222 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11223 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11225 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11226 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11230 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11231 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11233 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11234 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11238 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11239 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
11241 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11242 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11246 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11247 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
11249 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11250 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11254 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
11255 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
11257 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11258 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11262 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
11263 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
11264 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11267 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
11268 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
11269 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11272 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
11273 * different afterwards. DX9+ GPUs set one of the two luminance values
11274 * in each block, but AMD and Nvidia GPUs disagree on which luminance
11275 * value they set. r200 (dx8) just sets the entire block to the clear
11277 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11278 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
11280 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11281 {0}, {0}, {0}, {0}, {0}
11285 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11286 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
11288 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11289 {0}, {0}, {0}, {0}, {0}
11293 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11294 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
11296 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11297 {0}, {0}, {0}, {0}, {0}
11301 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11302 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
11304 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11305 {0}, {0}, {0}, {0}, {0}
11309 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11310 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
11312 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11313 {0}, {0}, {0}, {0}, {0}
11317 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11318 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
11320 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11321 {0}, {0}, {0}, {0}, {0}
11325 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
11326 * surface works, presumably because it is handled by the runtime instead of
11328 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11329 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
11331 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11332 {8}, {0}, {0}, {0}, {0}
11336 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11337 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
11339 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11340 {8}, {0}, {0}, {0}, {0}
11344 static const struct
11352 {SRCCOPY
, "SRCCOPY", DD_OK
},
11353 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
11354 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
11355 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
11356 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
11357 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
11358 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
11359 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
11360 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
11361 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
11362 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
11363 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
11364 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
11365 {BLACKNESS
, "BLACKNESS", DD_OK
},
11366 {WHITENESS
, "WHITENESS", DD_OK
},
11367 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
11370 window
= create_window();
11371 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11373 skip("Failed to create a 3D device, skipping test.\n");
11374 DestroyWindow(window
);
11378 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11379 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
11380 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11381 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
11383 memset(&z_fmt
, 0, sizeof(z_fmt
));
11384 IDirect3D7_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
11386 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
11388 IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
11389 if (!(supported_fmts
& SUPPORT_DXT1
))
11390 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
11392 IDirect3D7_Release(d3d
);
11394 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
11395 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
11396 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
11397 num_fourcc_codes
* sizeof(*fourcc_codes
));
11400 hr
= IDirectDraw7_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
11401 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
11402 for (i
= 0; i
< num_fourcc_codes
; i
++)
11404 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
11405 supported_fmts
|= SUPPORT_YUY2
;
11406 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
11407 supported_fmts
|= SUPPORT_UYVY
;
11409 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
11411 memset(&hal_caps
, 0, sizeof(hal_caps
));
11412 hal_caps
.dwSize
= sizeof(hal_caps
);
11413 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
11414 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
11416 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11417 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
11419 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
11421 DWORD expected_broken
= tests
[i
].result
;
11423 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
11424 memset(&fx
, 0, sizeof(fx
));
11425 fx
.dwSize
= sizeof(fx
);
11426 U5(fx
).dwFillColor
= 0xdeadbeef;
11428 memset(&surface_desc
, 0, sizeof(surface_desc
));
11429 surface_desc
.dwSize
= sizeof(surface_desc
);
11430 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11431 surface_desc
.dwWidth
= 64;
11432 surface_desc
.dwHeight
= 64;
11433 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
11434 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
11435 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
11437 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
11439 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
11441 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
11443 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11446 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
11451 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11452 /* Some drivers seem to convert depth values incorrectly or not at
11453 * all. Affects at least AMD PALM, 8.17.10.1247. */
11454 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
11459 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
11460 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
11461 g
= (f
+ 1.0f
) / 2.0f
;
11463 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
11464 expected_broken
*= 0x01010101;
11468 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11469 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11471 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11472 todo_wine_if (tests
[i
].format
.dwFourCC
)
11473 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11474 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11476 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11477 todo_wine_if (tests
[i
].format
.dwFourCC
)
11478 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11479 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11481 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11483 memset(&surface_desc
, 0, sizeof(surface_desc
));
11484 surface_desc
.dwSize
= sizeof(surface_desc
);
11485 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11486 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11487 color
= surface_desc
.lpSurface
;
11488 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
11489 *color
, tests
[i
].result
, tests
[i
].name
);
11490 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11491 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11494 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11495 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11496 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11497 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11498 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
11499 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11501 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11503 memset(&surface_desc
, 0, sizeof(surface_desc
));
11504 surface_desc
.dwSize
= sizeof(surface_desc
);
11505 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11506 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11507 color
= surface_desc
.lpSurface
;
11508 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
11509 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
11510 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
11511 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
11512 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11513 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11516 U5(fx
).dwFillColor
= 0xdeadbeef;
11517 fx
.dwROP
= BLACKNESS
;
11518 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11519 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
11520 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11521 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
11522 U5(fx
).dwFillColor
, tests
[i
].name
);
11524 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11526 memset(&surface_desc
, 0, sizeof(surface_desc
));
11527 surface_desc
.dwSize
= sizeof(surface_desc
);
11528 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11529 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11530 color
= surface_desc
.lpSurface
;
11531 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
11532 *color
, tests
[i
].name
);
11533 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11534 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11537 fx
.dwROP
= WHITENESS
;
11538 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11539 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
11540 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11541 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
11542 U5(fx
).dwFillColor
, tests
[i
].name
);
11544 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11546 memset(&surface_desc
, 0, sizeof(surface_desc
));
11547 surface_desc
.dwSize
= sizeof(surface_desc
);
11548 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11549 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11550 color
= surface_desc
.lpSurface
;
11551 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
11552 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
11553 *color
, tests
[i
].name
);
11554 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
11555 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
11558 IDirectDrawSurface7_Release(surface
);
11561 memset(&fx
, 0, sizeof(fx
));
11562 fx
.dwSize
= sizeof(fx
);
11563 U5(fx
).dwFillColor
= 0xdeadbeef;
11564 fx
.dwROP
= WHITENESS
;
11566 memset(&surface_desc
, 0, sizeof(surface_desc
));
11567 surface_desc
.dwSize
= sizeof(surface_desc
);
11568 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11569 surface_desc
.dwWidth
= 64;
11570 surface_desc
.dwHeight
= 64;
11571 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11572 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11573 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11574 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11575 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11576 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11577 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11578 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11579 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11580 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11581 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11584 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
11585 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11586 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
11587 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11589 /* Unused source rectangle. */
11590 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11591 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11592 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11593 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11595 /* Unused source surface. */
11596 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11597 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11598 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11599 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11600 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11601 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11602 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11603 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11605 /* Inverted destination or source rectangle. */
11606 SetRect(&rect
, 5, 7, 7, 5);
11607 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11608 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11609 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11610 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11611 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11612 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11613 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11614 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11615 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11616 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11618 /* Negative rectangle. */
11619 SetRect(&rect
, -1, -1, 5, 5);
11620 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11621 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11622 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11623 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11624 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11625 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11626 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11627 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11628 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11629 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11631 /* Out of bounds rectangle. */
11632 SetRect(&rect
, 0, 0, 65, 65);
11633 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11634 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11635 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11636 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11638 /* Combine multiple flags. */
11639 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11640 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11641 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11642 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11643 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11644 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11646 for (i
= 0; i
< ARRAY_SIZE(rops
); ++i
)
11648 fx
.dwROP
= rops
[i
].rop
;
11649 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11650 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
11653 IDirectDrawSurface7_Release(surface2
);
11654 IDirectDrawSurface7_Release(surface
);
11659 memset(&surface_desc
, 0, sizeof(surface_desc
));
11660 surface_desc
.dwSize
= sizeof(surface_desc
);
11661 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11662 surface_desc
.dwWidth
= 64;
11663 surface_desc
.dwHeight
= 64;
11664 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11665 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
11666 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11667 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11668 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11669 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11672 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
11673 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11675 /* Unused source rectangle. */
11676 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11677 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11679 /* Unused source surface. */
11680 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11681 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11682 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11683 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11685 /* Inverted destination or source rectangle. */
11686 SetRect(&rect
, 5, 7, 7, 5);
11687 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11688 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11689 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11690 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11691 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11692 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11693 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11694 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11696 /* Negative rectangle. */
11697 SetRect(&rect
, -1, -1, 5, 5);
11698 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11699 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11700 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11701 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
11702 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11703 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11704 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11705 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11707 /* Out of bounds rectangle. */
11708 SetRect(&rect
, 0, 0, 65, 65);
11709 hr
= IDirectDrawSurface7_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11710 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
11712 /* Combine multiple flags. */
11713 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11714 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11716 IDirectDrawSurface7_Release(surface2
);
11717 IDirectDrawSurface7_Release(surface
);
11720 IDirectDraw7_Release(ddraw
);
11721 refcount
= IDirect3DDevice7_Release(device
);
11722 ok(!refcount
, "Device has %u references left.\n", refcount
);
11723 DestroyWindow(window
);
11726 static void test_texcoordindex(void)
11728 static D3DMATRIX mat
=
11730 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11731 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11732 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11733 0.0f
, 0.0f
, 0.0f
, 0.0f
,
11738 struct vec2 texcoord1
;
11739 struct vec2 texcoord2
;
11740 struct vec2 texcoord3
;
11744 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11745 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
11746 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11747 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
11749 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
11750 IDirect3DDevice7
*device
;
11752 IDirectDraw7
*ddraw
;
11753 IDirectDrawSurface7
*rt
;
11756 IDirectDrawSurface7
*texture1
, *texture2
;
11757 DDSURFACEDESC2 surface_desc
;
11762 window
= create_window();
11763 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11765 skip("Failed to create a 3D device, skipping test.\n");
11766 DestroyWindow(window
);
11770 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
11771 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
11772 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
11773 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
11774 IDirect3D7_Release(d3d
);
11776 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
11777 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11779 memset(&surface_desc
, 0, sizeof(surface_desc
));
11780 surface_desc
.dwSize
= sizeof(surface_desc
);
11781 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11782 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11783 surface_desc
.dwWidth
= 2;
11784 surface_desc
.dwHeight
= 2;
11785 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11786 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11787 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11788 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11789 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11790 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11791 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
11792 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture1
, NULL
);
11793 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11794 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture2
, NULL
);
11795 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11797 memset(&surface_desc
, 0, sizeof(surface_desc
));
11798 surface_desc
.dwSize
= sizeof(surface_desc
);
11799 hr
= IDirectDrawSurface7_Lock(texture1
, 0, &surface_desc
, 0, NULL
);
11800 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11801 ptr
= surface_desc
.lpSurface
;
11802 ptr
[0] = 0xff000000;
11803 ptr
[1] = 0xff00ff00;
11804 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
11805 ptr
[0] = 0xff0000ff;
11806 ptr
[1] = 0xff00ffff;
11807 hr
= IDirectDrawSurface7_Unlock(texture1
, NULL
);
11808 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11810 memset(&surface_desc
, 0, sizeof(surface_desc
));
11811 surface_desc
.dwSize
= sizeof(surface_desc
);
11812 hr
= IDirectDrawSurface7_Lock(texture2
, 0, &surface_desc
, 0, NULL
);
11813 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11814 ptr
= surface_desc
.lpSurface
;
11815 ptr
[0] = 0xff000000;
11816 ptr
[1] = 0xff0000ff;
11817 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
11818 ptr
[0] = 0xffff0000;
11819 ptr
[1] = 0xffff00ff;
11820 hr
= IDirectDrawSurface7_Unlock(texture2
, 0);
11821 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11823 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture1
);
11824 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
11825 hr
= IDirect3DDevice7_SetTexture(device
, 1, texture2
);
11826 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
11827 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
11828 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
11829 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
11830 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11831 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11832 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11833 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
11834 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11835 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11836 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11837 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
11838 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11839 hr
= IDirect3DDevice7_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
11840 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11842 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
11843 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
11844 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
11845 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
11847 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
11848 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
11850 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
11851 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11853 hr
= IDirect3DDevice7_BeginScene(device
);
11854 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11855 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
11856 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11857 hr
= IDirect3DDevice7_EndScene(device
);
11858 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11860 color
= get_surface_color(rt
, 160, 120);
11861 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11862 color
= get_surface_color(rt
, 480, 120);
11863 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
11864 color
= get_surface_color(rt
, 160, 360);
11865 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
11866 color
= get_surface_color(rt
, 480, 360);
11867 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
11869 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_COUNT2
);
11870 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
11871 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_TEXTURE1
, &mat
);
11872 ok(SUCCEEDED(hr
), "Failed to set transformation matrix, hr %#x.\n", hr
);
11874 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
11875 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11877 hr
= IDirect3DDevice7_BeginScene(device
);
11878 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11879 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
11880 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11881 hr
= IDirect3DDevice7_EndScene(device
);
11882 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11884 color
= get_surface_color(rt
, 160, 120);
11885 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11886 color
= get_surface_color(rt
, 480, 120);
11887 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
11888 color
= get_surface_color(rt
, 160, 360);
11889 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
11890 color
= get_surface_color(rt
, 480, 360);
11891 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
11893 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXTURETRANSFORMFLAGS
, D3DTTFF_DISABLE
);
11894 ok(SUCCEEDED(hr
), "Failed to set texture transform flags, hr %#x.\n", hr
);
11895 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
11896 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
11898 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
11899 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11901 hr
= IDirect3DDevice7_BeginScene(device
);
11902 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11903 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
11904 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11905 hr
= IDirect3DDevice7_EndScene(device
);
11906 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11908 color
= get_surface_color(rt
, 160, 120);
11909 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11910 color
= get_surface_color(rt
, 480, 120);
11911 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
11912 color
= get_surface_color(rt
, 160, 360);
11913 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
11914 color
= get_surface_color(rt
, 480, 360);
11915 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
11917 IDirectDrawSurface7_Release(texture1
);
11918 IDirectDrawSurface7_Release(texture2
);
11920 IDirectDrawSurface7_Release(rt
);
11921 IDirectDraw7_Release(ddraw
);
11922 refcount
= IDirect3DDevice7_Release(device
);
11923 ok(!refcount
, "Device has %u references left.\n", refcount
);
11924 DestroyWindow(window
);
11927 static void test_colorkey_precision(void)
11932 struct vec2 texcoord
;
11936 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11937 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
11938 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11939 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
11942 static const struct
11944 unsigned int max
, shift
, bpp
, clear
;
11952 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
11954 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
11955 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
11960 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
11962 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
11963 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
11968 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
11970 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
11971 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
11976 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
11978 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11979 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
11984 IDirectDrawSurface7
*src
, *dst
, *texture
;
11985 DDSURFACEDESC2 surface_desc
, lock_desc
;
11986 DWORD data
[4] = {0}, color_mask
;
11987 IDirect3DDevice7
*device
;
11988 IDirectDrawSurface7
*rt
;
11989 IDirectDraw7
*ddraw
;
12000 window
= create_window();
12001 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12003 skip("Failed to create a 3D device, skipping test.\n");
12004 DestroyWindow(window
);
12008 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
12009 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12010 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
12011 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12012 IDirect3D7_Release(d3d
);
12013 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
12014 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12016 is_nvidia
= ddraw_is_nvidia(ddraw
);
12017 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
12018 * (color key doesn't match although the values are equal), and a false
12019 * positive when the color key is 0 and the texture contains the value 1.
12020 * Also on random occasions 254 == 255 and 255 != 255.
12021 * Crashes on Windows 10 WARP. */
12022 if (ddraw_is_warp(ddraw
))
12024 win_skip("Skipping test on WARP driver.\n");
12028 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12029 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12030 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
12031 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12032 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
12033 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12034 /* Multiply the texture read result with 0, that way the result color if the key doesn't
12035 * match is constant. In theory color keying works without reading the texture result
12036 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
12038 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
12039 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12040 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
12041 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12042 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
12043 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12044 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
12045 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12047 memset(&fx
, 0, sizeof(fx
));
12048 fx
.dwSize
= sizeof(fx
);
12049 memset(&lock_desc
, 0, sizeof(lock_desc
));
12050 lock_desc
.dwSize
= sizeof(lock_desc
);
12052 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
12054 if (is_nvidia
&& tests
[t
].skip_nv
)
12056 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
12060 memset(&surface_desc
, 0, sizeof(surface_desc
));
12061 surface_desc
.dwSize
= sizeof(surface_desc
);
12062 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12063 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12064 surface_desc
.dwWidth
= 4;
12065 surface_desc
.dwHeight
= 1;
12066 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
12067 /* Windows XP (at least with the r200 driver, other drivers untested) produces
12068 * garbage when doing color keyed texture->texture blits. */
12069 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12070 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12071 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12072 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12074 U5(fx
).dwFillColor
= tests
[t
].clear
;
12075 /* On the w8 testbot (WARP driver) the blit result has different values in the
12077 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
12078 | U3(tests
[t
].fmt
).dwGBitMask
12079 | U4(tests
[t
].fmt
).dwBBitMask
;
12081 for (c
= 0; c
<= tests
[t
].max
; ++c
)
12083 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
12084 * texture after it has been set once... */
12085 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12086 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12087 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12088 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12089 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
12090 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12091 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
12092 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12094 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12095 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12097 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12098 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12099 switch (tests
[t
].bpp
)
12102 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12103 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12104 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12105 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
12109 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12110 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12111 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12112 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
12115 hr
= IDirectDrawSurface7_Unlock(src
, 0);
12116 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12117 hr
= IDirectDrawSurface7_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
12118 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12120 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12121 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12122 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12123 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12125 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
12126 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12128 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
12129 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12130 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12131 switch (tests
[t
].bpp
)
12134 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12135 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12136 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12137 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12141 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12142 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12143 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12144 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12147 hr
= IDirectDrawSurface7_Unlock(dst
, 0);
12148 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12152 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12153 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
12155 if (data
[3] == tests
[t
].clear
)
12157 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
12158 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
12159 * even when a different surface is used. The blit itself doesn't draw anything,
12160 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
12161 * never be masked out by the key.
12163 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
12164 * test is disabled on Nvidia.
12166 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
12167 * terrible on WARP. */
12168 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
12169 IDirectDrawSurface7_Release(texture
);
12170 IDirectDrawSurface7_Release(src
);
12171 IDirectDrawSurface7_Release(dst
);
12176 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12177 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
12179 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12180 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
12182 if (c
== tests
[t
].max
)
12183 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12184 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
12186 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12187 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
12189 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
12190 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12192 hr
= IDirect3DDevice7_BeginScene(device
);
12193 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12194 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
12195 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12196 hr
= IDirect3DDevice7_EndScene(device
);
12197 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12199 color
= get_surface_color(rt
, 80, 240);
12202 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12203 color
, tests
[t
].name
, c
);
12205 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12206 color
, tests
[t
].name
, c
);
12208 color
= get_surface_color(rt
, 240, 240);
12209 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12210 color
, tests
[t
].name
, c
);
12212 color
= get_surface_color(rt
, 400, 240);
12213 if (c
== tests
[t
].max
)
12214 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12215 color
, tests
[t
].name
, c
);
12217 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x, format %s, c=%u.\n",
12218 color
, tests
[t
].name
, c
);
12220 IDirectDrawSurface7_Release(texture
);
12222 IDirectDrawSurface7_Release(src
);
12223 IDirectDrawSurface7_Release(dst
);
12227 IDirectDrawSurface7_Release(rt
);
12228 IDirectDraw7_Release(ddraw
);
12229 refcount
= IDirect3DDevice7_Release(device
);
12230 ok(!refcount
, "Device has %u references left.\n", refcount
);
12231 DestroyWindow(window
);
12234 static void test_range_colorkey(void)
12236 IDirectDraw7
*ddraw
;
12239 IDirectDrawSurface7
*surface
;
12240 DDSURFACEDESC2 surface_desc
;
12244 window
= create_window();
12245 ddraw
= create_ddraw();
12246 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12247 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12248 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12250 memset(&surface_desc
, 0, sizeof(surface_desc
));
12251 surface_desc
.dwSize
= sizeof(surface_desc
);
12252 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
12253 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12254 surface_desc
.dwWidth
= 1;
12255 surface_desc
.dwHeight
= 1;
12256 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12257 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12258 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12259 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12260 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12261 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
12263 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
12264 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12265 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12266 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12267 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12269 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12270 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12271 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12272 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12274 /* Same for DDSCAPS_OFFSCREENPLAIN. */
12275 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12276 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12277 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12278 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12279 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12281 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12282 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12283 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12284 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12286 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12287 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12288 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12289 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12291 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
12292 ckey
.dwColorSpaceLowValue
= 0x00000000;
12293 ckey
.dwColorSpaceHighValue
= 0x00000001;
12294 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12295 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12297 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12298 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12299 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12300 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12302 ckey
.dwColorSpaceLowValue
= 0x00000001;
12303 ckey
.dwColorSpaceHighValue
= 0x00000000;
12304 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12305 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12307 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12308 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12309 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12310 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12312 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
12313 ckey
.dwColorSpaceLowValue
= 0x00000000;
12314 ckey
.dwColorSpaceHighValue
= 0x00000000;
12315 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12316 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
12318 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
12319 ckey
.dwColorSpaceLowValue
= 0x00000001;
12320 ckey
.dwColorSpaceHighValue
= 0x00000000;
12321 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12322 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12323 ckey
.dwColorSpaceLowValue
= 0x00000000;
12324 ckey
.dwColorSpaceHighValue
= 0x00000001;
12325 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12326 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12327 /* Range destination keys don't work either. */
12328 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
12329 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12331 /* Just to show it's not because of A, R, and G having equal values. */
12332 ckey
.dwColorSpaceLowValue
= 0x00000000;
12333 ckey
.dwColorSpaceHighValue
= 0x01010101;
12334 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12335 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
12337 /* None of these operations modified the key. */
12338 hr
= IDirectDrawSurface7_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12339 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
12340 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
12341 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
12343 IDirectDrawSurface7_Release(surface
);
12344 refcount
= IDirectDraw7_Release(ddraw
);
12345 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
12346 DestroyWindow(window
);
12349 static void test_shademode(void)
12351 IDirect3DVertexBuffer7
*vb_strip
, *vb_list
, *buffer
;
12352 IDirect3DDevice7
*device
;
12353 D3DVERTEXBUFFERDESC desc
;
12354 IDirectDrawSurface7
*rt
;
12355 DWORD color0
, color1
;
12362 static const struct
12364 struct vec3 position
;
12369 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12370 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12371 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12372 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12376 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12377 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12378 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12380 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12381 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12382 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12384 static const struct
12388 DWORD color0
, color1
;
12392 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
12393 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12394 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12395 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12396 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
12397 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12400 window
= create_window();
12401 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12403 skip("Failed to create a 3D device, skipping test.\n");
12404 DestroyWindow(window
);
12408 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
12409 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
12410 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
12411 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12413 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12414 ok(hr
== D3D_OK
, "Failed to disable lighting, hr %#x.\n", hr
);
12415 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12416 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12418 memset(&desc
, 0, sizeof(desc
));
12419 desc
.dwSize
= sizeof(desc
);
12420 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
12421 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
12422 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
12423 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0);
12424 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
12425 hr
= IDirect3DVertexBuffer7_Lock(vb_strip
, 0, &data
, NULL
);
12426 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
12427 memcpy(data
, quad_strip
, sizeof(quad_strip
));
12428 hr
= IDirect3DVertexBuffer7_Unlock(vb_strip
);
12429 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12431 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
12432 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0);
12433 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
12434 hr
= IDirect3DVertexBuffer7_Lock(vb_list
, 0, &data
, NULL
);
12435 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
12436 memcpy(data
, quad_list
, sizeof(quad_list
));
12437 hr
= IDirect3DVertexBuffer7_Unlock(vb_list
);
12438 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12440 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
12441 * the color fixups we have to do for FLAT shading will be dependent on that. */
12443 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
12445 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
12446 ok(hr
== D3D_OK
, "Failed to clear, hr %#x.\n", hr
);
12448 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
12449 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
12451 hr
= IDirect3DDevice7_BeginScene(device
);
12452 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12453 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
12454 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
12455 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
12456 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12457 hr
= IDirect3DDevice7_EndScene(device
);
12458 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12460 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
12461 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
12463 /* For D3DSHADE_FLAT it should take the color of the first vertex of
12464 * each triangle. This requires EXT_provoking_vertex or similar
12465 * functionality being available. */
12466 /* PHONG should be the same as GOURAUD, since no hardware implements
12468 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
12469 i
, color0
, tests
[i
].color0
);
12470 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
12471 i
, color1
, tests
[i
].color1
);
12474 IDirect3DVertexBuffer7_Release(vb_strip
);
12475 IDirect3DVertexBuffer7_Release(vb_list
);
12476 IDirectDrawSurface7_Release(rt
);
12477 IDirect3D7_Release(d3d
);
12478 refcount
= IDirect3DDevice7_Release(device
);
12479 ok(!refcount
, "Device has %u references left.\n", refcount
);
12480 DestroyWindow(window
);
12483 static void test_lockrect_invalid(void)
12486 IDirectDraw7
*ddraw
;
12487 IDirectDrawSurface7
*surface
;
12490 DDSURFACEDESC2 surface_desc
;
12491 DDSURFACEDESC2 locked_desc
;
12493 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
12494 static RECT valid
[] =
12499 {120, 60, 128, 68},
12500 {60, 120, 68, 128},
12502 static RECT invalid
[] =
12504 {68, 60, 60, 68}, /* left > right */
12505 {60, 68, 68, 60}, /* top > bottom */
12506 {-8, 60, 0, 68}, /* left < surface */
12507 {60, -8, 68, 0}, /* top < surface */
12508 {-16, 60, -8, 68}, /* right < surface */
12509 {60, -16, 68, -8}, /* bottom < surface */
12510 {60, 60, 136, 68}, /* right > surface */
12511 {60, 60, 68, 136}, /* bottom > surface */
12512 {136, 60, 144, 68}, /* left > surface */
12513 {60, 136, 68, 144}, /* top > surface */
12515 static const struct
12524 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12525 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12526 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", TRUE
, DD_OK
},
12527 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", TRUE
, DDERR_INVALIDPARAMS
},
12528 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", TRUE
, DD_OK
},
12530 /* FWIW the SDK header mentions DDSCAPS_WRITEONLY as being a "READ
12532 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12533 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12534 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem texture writeonly", FALSE
, DD_OK
},
12535 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12536 {DDSCAPS_TEXTURE
| DDSCAPS_WRITEONLY
, DDSCAPS2_TEXTUREMANAGE
, "managed texture writeonly", TRUE
, DD_OK
},
12539 window
= create_window();
12540 ddraw
= create_ddraw();
12541 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12542 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12543 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12545 memset(&hal_caps
, 0, sizeof(hal_caps
));
12546 hal_caps
.dwSize
= sizeof(hal_caps
);
12547 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
12548 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
12549 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
12550 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
12552 skip("Required surface types not supported, skipping test.\n");
12556 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
12558 memset(&surface_desc
, 0, sizeof(surface_desc
));
12559 surface_desc
.dwSize
= sizeof(surface_desc
);
12560 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12561 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
12562 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
12563 surface_desc
.dwWidth
= 128;
12564 surface_desc
.dwHeight
= 128;
12565 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12566 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12567 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12568 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
12569 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
12570 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
12572 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12573 if (!resources
[r
].allowed
)
12575 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
12578 if (is_ddraw64
&& (resources
[r
].caps
& DDSCAPS_TEXTURE
))
12580 todo_wine
ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
12582 IDirectDrawSurface7_Release(surface
);
12585 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12587 /* Crashes in ddraw7
12588 hr = IDirectDrawSurface7_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL);
12589 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name);
12592 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
12594 RECT
*rect
= &valid
[i
];
12596 memset(&locked_desc
, 0, sizeof(locked_desc
));
12597 locked_desc
.dwSize
= sizeof(locked_desc
);
12599 hr
= IDirectDrawSurface7_Lock(surface
, rect
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12600 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
12601 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12603 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12604 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12607 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
12609 RECT
*rect
= &invalid
[i
];
12611 memset(&locked_desc
, 1, sizeof(locked_desc
));
12612 locked_desc
.dwSize
= sizeof(locked_desc
);
12614 hr
= IDirectDrawSurface7_Lock(surface
, rect
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12615 todo_wine_if (SUCCEEDED(resources
[r
].hr
))
12616 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
12617 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12620 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12621 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12624 ok(!locked_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", locked_desc
.lpSurface
);
12627 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12628 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
12629 hr
, resources
[r
].name
);
12630 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &locked_desc
, DDLOCK_WAIT
, NULL
);
12631 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
12632 hr
, resources
[r
].name
);
12633 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12634 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12636 hr
= IDirectDrawSurface7_Lock(surface
, &valid
[0], &locked_desc
, DDLOCK_WAIT
, NULL
);
12637 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
12638 hr
= IDirectDrawSurface7_Lock(surface
, &valid
[0], &locked_desc
, DDLOCK_WAIT
, NULL
);
12639 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
12640 wine_dbgstr_rect(&valid
[0]), hr
);
12642 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
12643 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
12645 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
12646 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
12648 IDirectDrawSurface7_Release(surface
);
12652 IDirectDraw7_Release(ddraw
);
12653 DestroyWindow(window
);
12656 static void test_yv12_overlay(void)
12658 IDirectDrawSurface7
*src_surface
, *dst_surface
;
12659 RECT rect
= {13, 17, 14, 18};
12660 unsigned int offset
, y
;
12661 DDSURFACEDESC2 desc
;
12662 unsigned char *base
;
12663 IDirectDraw7
*ddraw
;
12667 window
= create_window();
12668 ddraw
= create_ddraw();
12669 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12670 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12671 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12673 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12675 skip("Failed to create a YV12 overlay, skipping test.\n");
12679 memset(&desc
, 0, sizeof(desc
));
12680 desc
.dwSize
= sizeof(desc
);
12681 hr
= IDirectDrawSurface7_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12682 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12684 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
12685 "Got unexpected flags %#x.\n", desc
.dwFlags
);
12686 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
12687 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
12688 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
12689 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
12690 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
12691 /* The overlay pitch seems to have 256 byte alignment. */
12692 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
12694 /* Fill the surface with some data for the blit test. */
12695 base
= desc
.lpSurface
;
12697 for (y
= 0; y
< desc
.dwHeight
; ++y
)
12699 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
12702 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
12704 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
12707 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
12709 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
12712 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
12713 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12715 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
12716 * other block-based formats like DXT the entire Y channel is stored in
12717 * one big chunk of memory, followed by the chroma channels. So partial
12718 * locks do not really make sense. Show that they are allowed nevertheless
12719 * and the offset points into the luminance data. */
12720 hr
= IDirectDrawSurface7_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
12721 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12722 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
12723 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
12724 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
12725 hr
= IDirectDrawSurface7_Unlock(src_surface
, NULL
);
12726 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12728 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12730 /* Windows XP with a Radeon X1600 GPU refuses to create a second
12731 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
12732 skip("Failed to create a second YV12 surface, skipping blit test.\n");
12733 IDirectDrawSurface7_Release(src_surface
);
12737 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
12738 /* VMware rejects YV12 blits. This behavior has not been seen on real
12739 * hardware yet, so mark it broken. */
12740 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
12744 memset(&desc
, 0, sizeof(desc
));
12745 desc
.dwSize
= sizeof(desc
);
12746 hr
= IDirectDrawSurface7_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12747 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
12749 base
= desc
.lpSurface
;
12750 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
12751 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
12752 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
12753 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
12754 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
12756 hr
= IDirectDrawSurface7_Unlock(dst_surface
, NULL
);
12757 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
12760 IDirectDrawSurface7_Release(dst_surface
);
12761 IDirectDrawSurface7_Release(src_surface
);
12763 IDirectDraw7_Release(ddraw
);
12764 DestroyWindow(window
);
12767 static BOOL
dwm_enabled(void)
12771 if (!strcmp(winetest_platform
, "wine"))
12773 if (!pDwmIsCompositionEnabled
)
12775 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
12780 static void test_offscreen_overlay(void)
12782 IDirectDrawSurface7
*overlay
, *offscreen
, *primary
;
12783 DDSURFACEDESC2 surface_desc
;
12784 IDirectDraw7
*ddraw
;
12789 window
= create_window();
12790 ddraw
= create_ddraw();
12791 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12792 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12793 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12795 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
12797 skip("Failed to create a UYVY overlay, skipping test.\n");
12801 memset(&surface_desc
, 0, sizeof(surface_desc
));
12802 surface_desc
.dwSize
= sizeof(surface_desc
);
12803 surface_desc
.dwFlags
= DDSD_CAPS
;
12804 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
12805 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
12806 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
12808 /* On Windows 7, and probably Vista, UpdateOverlay() will return
12809 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
12810 * surface prevents this by disabling the dwm. */
12811 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
12812 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
12813 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
12814 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
12816 /* Try to overlay a NULL surface. */
12817 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
12818 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12819 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
12820 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12822 /* Try to overlay an offscreen surface. */
12823 memset(&surface_desc
, 0, sizeof(surface_desc
));
12824 surface_desc
.dwSize
= sizeof(surface_desc
);
12825 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
12826 surface_desc
.dwWidth
= 64;
12827 surface_desc
.dwHeight
= 64;
12828 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12829 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12830 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12831 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
12832 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
12833 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
12834 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
12835 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
12836 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12837 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
12839 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
12840 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
12841 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
12842 "Failed to update overlay, hr %#x.\n", hr
);
12844 /* Try to overlay the primary with a non-overlay surface. */
12845 hr
= IDirectDrawSurface7_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
12846 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
12847 hr
= IDirectDrawSurface7_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
12848 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
12850 IDirectDrawSurface7_Release(offscreen
);
12851 IDirectDrawSurface7_Release(primary
);
12852 IDirectDrawSurface7_Release(overlay
);
12854 IDirectDraw7_Release(ddraw
);
12855 DestroyWindow(window
);
12858 static void test_overlay_rect(void)
12860 IDirectDrawSurface7
*overlay
, *primary
= NULL
;
12861 DDSURFACEDESC2 surface_desc
;
12862 RECT rect
= {0, 0, 64, 64};
12863 IDirectDraw7
*ddraw
;
12869 window
= create_window();
12870 ddraw
= create_ddraw();
12871 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12872 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12873 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12875 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
12877 skip("Failed to create a UYVY overlay, skipping test.\n");
12881 memset(&surface_desc
, 0, sizeof(surface_desc
));
12882 surface_desc
.dwSize
= sizeof(surface_desc
);
12883 surface_desc
.dwFlags
= DDSD_CAPS
;
12884 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
12885 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
12886 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
12888 /* On Windows 7, and probably Vista, UpdateOverlay() will return
12889 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
12890 * surface prevents this by disabling the dwm. */
12891 hr
= IDirectDrawSurface7_GetDC(primary
, &dc
);
12892 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
12893 hr
= IDirectDrawSurface7_ReleaseDC(primary
, dc
);
12894 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
12896 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
12899 win_skip("Cannot disable DWM, skipping overlay test.\n");
12903 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
12904 * used. This is not true in Windows Vista and earlier, but changed in
12906 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
12907 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
12908 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
12909 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
12910 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
12911 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
12913 /* Show that the overlay position is the (top, left) coordinate of the
12914 * destination rectangle. */
12915 OffsetRect(&rect
, 32, 16);
12916 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
12917 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
12918 pos_x
= -1; pos_y
= -1;
12919 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
12920 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
12921 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
12922 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
12924 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
12925 * seen that the overlay overlays the whole primary(==screen). */
12926 hr2
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
12927 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
12928 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
12929 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
12930 if (SUCCEEDED(hr2
))
12932 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
12933 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
12937 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
12938 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
12941 /* The position cannot be retrieved when the overlay is not shown. */
12942 hr
= IDirectDrawSurface7_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
12943 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
12944 pos_x
= -1; pos_y
= -1;
12945 hr
= IDirectDrawSurface7_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
12946 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
12947 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
12948 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
12952 IDirectDrawSurface7_Release(primary
);
12954 IDirectDrawSurface7_Release(overlay
);
12955 IDirectDraw7_Release(ddraw
);
12956 DestroyWindow(window
);
12959 static void test_blt(void)
12961 IDirectDrawSurface7
*surface
, *rt
;
12962 DDSURFACEDESC2 surface_desc
;
12963 IDirect3DDevice7
*device
;
12964 IDirectDraw7
*ddraw
;
12979 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
12980 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
12981 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
12982 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
12983 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
12984 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
12985 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
12986 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
12987 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
12988 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
12991 window
= create_window();
12992 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12994 skip("Failed to create a 3D device, skipping test.\n");
12995 DestroyWindow(window
);
12999 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13000 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13001 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13002 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13003 IDirect3D7_Release(d3d
);
13004 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
13005 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13007 memset(&surface_desc
, 0, sizeof(surface_desc
));
13008 surface_desc
.dwSize
= sizeof(surface_desc
);
13009 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13010 surface_desc
.dwWidth
= 640;
13011 surface_desc
.dwHeight
= 480;
13012 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13013 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13014 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13016 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
13017 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13019 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
13020 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13022 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13024 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13025 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13026 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
13028 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13029 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13030 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
13032 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
,
13033 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13034 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13036 hr
= IDirectDrawSurface7_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
13037 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13040 IDirectDrawSurface7_Release(surface
);
13041 IDirectDrawSurface7_Release(rt
);
13042 IDirectDraw7_Release(ddraw
);
13043 refcount
= IDirect3DDevice7_Release(device
);
13044 ok(!refcount
, "Device has %u references left.\n", refcount
);
13045 DestroyWindow(window
);
13048 static void test_blt_z_alpha(void)
13050 DWORD blt_flags
[] =
13054 DDBLT_ALPHADESTCONSTOVERRIDE
,
13055 DDBLT_ALPHADESTNEG
,
13056 DDBLT_ALPHADESTSURFACEOVERRIDE
,
13057 DDBLT_ALPHAEDGEBLEND
,
13060 DDBLT_ALPHASRCCONSTOVERRIDE
,
13062 DDBLT_ALPHASRCSURFACEOVERRIDE
,
13065 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
13066 DDBLT_ZBUFFERDESTOVERRIDE
,
13067 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
13068 DDBLT_ZBUFFERSRCOVERRIDE
,
13070 IDirectDrawSurface7
*src_surface
, *dst_surface
;
13071 DDSURFACEDESC2 surface_desc
;
13072 IDirectDraw7
*ddraw
;
13081 window
= create_window();
13082 ddraw
= create_ddraw();
13083 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13084 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13085 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13087 memset(&pf
, 0, sizeof(pf
));
13088 pf
.dwSize
= sizeof(pf
);
13089 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13090 U1(pf
).dwRGBBitCount
= 32;
13091 U2(pf
).dwRBitMask
= 0x00ff0000;
13092 U3(pf
).dwGBitMask
= 0x0000ff00;
13093 U4(pf
).dwBBitMask
= 0x000000ff;
13094 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
13096 memset(&surface_desc
, 0, sizeof(surface_desc
));
13097 surface_desc
.dwSize
= sizeof(surface_desc
);
13098 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13099 surface_desc
.dwWidth
= 64;
13100 surface_desc
.dwHeight
= 64;
13101 U4(surface_desc
).ddpfPixelFormat
= pf
;
13102 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13104 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
13105 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
13106 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
13107 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
13109 memset(&fx
, 0, sizeof(fx
));
13110 fx
.dwSize
= sizeof(fx
);
13111 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
13112 fx
.dwZDestConstBitDepth
= 32;
13113 U1(fx
).dwZDestConst
= 0x11111111;
13114 fx
.dwZSrcConstBitDepth
= 32;
13115 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
13116 fx
.dwAlphaEdgeBlendBitDepth
= 8;
13117 fx
.dwAlphaEdgeBlend
= 0x7f;
13118 fx
.dwAlphaDestConstBitDepth
= 8;
13119 U3(fx
).dwAlphaDestConst
= 0xdd;
13120 fx
.dwAlphaSrcConstBitDepth
= 8;
13121 U4(fx
).dwAlphaSrcConst
= 0x22;
13123 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
13125 U5(fx
).dwFillColor
= 0x3300ff00;
13126 hr
= IDirectDrawSurface7_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13127 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13129 U5(fx
).dwFillColor
= 0xccff0000;
13130 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13131 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13133 hr
= IDirectDrawSurface7_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
13134 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
13136 color
= get_surface_color(dst_surface
, 32, 32);
13137 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
13140 IDirectDrawSurface7_Release(dst_surface
);
13141 IDirectDrawSurface7_Release(src_surface
);
13142 refcount
= IDirectDraw7_Release(ddraw
);
13143 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13144 DestroyWindow(window
);
13147 static void test_cross_device_blt(void)
13149 IDirectDrawSurface7
*surface
, *surface2
, *sysmem_surface
;
13150 IDirect3DDevice7
*device
, *device2
;
13151 IDirectDraw7
*ddraw
, *ddraw2
;
13152 DDSURFACEDESC2 surface_desc
;
13153 HWND window
, window2
;
13160 window
= create_window();
13161 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
13163 skip("Failed to create a 3D device.\n");
13164 DestroyWindow(window
);
13168 window2
= create_window();
13169 if (!(device2
= create_device(window2
, DDSCL_NORMAL
)))
13171 skip("Failed to create a 3D device.\n");
13172 IDirect3DDevice7_Release(device
);
13173 DestroyWindow(window
);
13174 DestroyWindow(window2
);
13178 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13179 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13180 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13181 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13182 IDirect3D7_Release(d3d
);
13184 hr
= IDirect3DDevice7_GetDirect3D(device2
, &d3d
);
13185 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
13186 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw2
);
13187 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13188 IDirect3D7_Release(d3d
);
13190 memset(&surface_desc
, 0, sizeof(surface_desc
));
13191 surface_desc
.dwSize
= sizeof(surface_desc
);
13192 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13193 surface_desc
.dwWidth
= 640;
13194 surface_desc
.dwHeight
= 480;
13195 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13196 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
13197 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13199 memset(&surface_desc
, 0, sizeof(surface_desc
));
13200 surface_desc
.dwSize
= sizeof(surface_desc
);
13201 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13202 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
13203 U5(surface_desc
).dwBackBufferCount
= 2;
13204 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13205 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13207 memset(&surface_desc
, 0, sizeof(surface_desc
));
13208 surface_desc
.dwSize
= sizeof(surface_desc
);
13209 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13210 surface_desc
.dwWidth
= 640;
13211 surface_desc
.dwHeight
= 480;
13212 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13213 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
13214 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13215 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
13216 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
13217 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
13218 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
13219 hr
= IDirectDraw7_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13220 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13222 memset(&fx
, 0, sizeof(fx
));
13223 fx
.dwSize
= sizeof(fx
);
13224 U5(fx
).dwFillColor
= 0xff0000ff;
13225 hr
= IDirectDrawSurface7_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13226 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
13228 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13229 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13230 hr
= IDirectDrawSurface7_Flip(surface
, NULL
, DDFLIP_WAIT
);
13231 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
13232 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13233 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13234 color
= get_surface_color(surface
, 320, 240);
13235 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13237 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13238 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13239 color
= get_surface_color(sysmem_surface
, 320, 240);
13240 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13242 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13243 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13244 hr
= IDirectDrawSurface7_IsLost(sysmem_surface
);
13245 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
13247 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13248 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
13249 color
= get_surface_color(sysmem_surface
, 320, 240);
13250 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13252 IDirectDrawSurface7_Release(surface2
);
13253 memset(&surface_desc
, 0, sizeof(surface_desc
));
13254 surface_desc
.dwSize
= sizeof(surface_desc
);
13255 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13256 surface_desc
.dwWidth
= 640;
13257 surface_desc
.dwHeight
= 480;
13258 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13259 hr
= IDirectDraw7_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13260 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13261 hr
= IDirectDrawSurface7_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13262 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
13264 hr
= IDirectDrawSurface7_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13265 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#x.\n", hr
);
13266 color
= get_surface_color(sysmem_surface
, 320, 240);
13267 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13269 IDirectDrawSurface7_Release(surface
);
13270 IDirectDrawSurface7_Release(surface2
);
13271 IDirectDrawSurface7_Release(sysmem_surface
);
13272 IDirectDraw7_Release(ddraw
);
13273 IDirectDraw7_Release(ddraw2
);
13274 refcount
= IDirect3DDevice7_Release(device
);
13275 ok(!refcount
, "Device has %u references left.\n", refcount
);
13276 refcount
= IDirect3DDevice7_Release(device2
);
13277 ok(!refcount
, "Device has %u references left.\n", refcount
);
13278 DestroyWindow(window
);
13279 DestroyWindow(window2
);
13282 static void test_color_clamping(void)
13284 static D3DMATRIX mat
=
13286 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13287 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13288 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13289 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13291 static struct vec3 quad
[] =
13293 {-1.0f
, -1.0f
, 0.1f
},
13294 {-1.0f
, 1.0f
, 0.1f
},
13295 { 1.0f
, -1.0f
, 0.1f
},
13296 { 1.0f
, 1.0f
, 0.1f
},
13298 IDirect3DDevice7
*device
;
13299 IDirectDrawSurface7
*rt
;
13305 window
= create_window();
13306 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13308 skip("Failed to create a 3D device, skipping test.\n");
13309 DestroyWindow(window
);
13313 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
13314 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13316 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
13317 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13318 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
13319 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
13320 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
13321 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
13322 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
13323 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
13324 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13325 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
13326 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13327 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
13328 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
13329 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
13330 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13331 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
13332 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13333 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
13335 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
13336 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
13337 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
13338 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
13339 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
13340 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13341 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
13342 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13343 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
13344 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
13345 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
13346 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13347 hr
= IDirect3DDevice7_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
13348 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13350 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
13351 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13353 hr
= IDirect3DDevice7_BeginScene(device
);
13354 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13356 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
13357 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13359 hr
= IDirect3DDevice7_EndScene(device
);
13360 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13362 color
= get_surface_color(rt
, 320, 240);
13363 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
13365 IDirectDrawSurface7_Release(rt
);
13366 refcount
= IDirect3DDevice7_Release(device
);
13367 ok(!refcount
, "Device has %u references left.\n", refcount
);
13368 DestroyWindow(window
);
13371 static void test_getdc(void)
13373 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, DDSCAPS2_CUBEMAP_NEGATIVEZ
, 0, {0}};
13374 IDirectDrawSurface7
*surface
, *surface2
, *tmp
;
13375 DDSURFACEDESC2 surface_desc
, map_desc
;
13376 IDirectDraw7
*ddraw
;
13377 unsigned int i
, screen_bpp
;
13382 static const struct
13385 DDPIXELFORMAT format
;
13386 BOOL getdc_supported
;
13387 HRESULT alt_result
;
13391 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13392 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
13393 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13394 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
13395 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13396 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13397 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13398 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13399 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13400 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
13401 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13402 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13403 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13404 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13405 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13406 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
13407 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13408 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13409 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13410 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13411 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
13412 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
13413 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
13414 * This is not implemented in wine yet, so disable the test for now.
13415 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
13416 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
13417 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
13419 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
13420 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13421 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
13422 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
13423 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
13424 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13425 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
13426 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13427 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
13428 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13429 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
13430 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13431 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
13432 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13435 window
= create_window();
13436 ddraw
= create_ddraw();
13437 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13438 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13439 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13441 surface_desc
.dwSize
= sizeof(surface_desc
);
13442 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
13443 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13444 screen_bpp
= U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
;
13446 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13448 memset(&surface_desc
, 0, sizeof(surface_desc
));
13449 surface_desc
.dwSize
= sizeof(surface_desc
);
13450 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13451 surface_desc
.dwWidth
= 64;
13452 surface_desc
.dwHeight
= 64;
13453 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
13454 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13456 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13458 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13459 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
13460 if (FAILED(hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13462 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
13467 dc
= (void *)0x1234;
13468 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13469 if (test_data
[i
].getdc_supported
)
13470 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
13471 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13473 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13477 unsigned int width_bytes
;
13483 type
= GetObjectType(dc
);
13484 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
13485 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
13486 type
= GetObjectType(bitmap
);
13487 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
13489 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
13490 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
13491 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
13492 dib
.dsBm
.bmType
, test_data
[i
].name
);
13493 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
13494 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
13495 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
13496 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
13497 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
13498 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
13499 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
13500 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
13501 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
13502 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
13503 "Got unexpected bit count %d for format %s.\n",
13504 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
13505 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
13506 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
13507 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
13508 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
13509 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
13511 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
13512 dib
.dsBmih
.biSize
, test_data
[i
].name
);
13513 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
13514 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13515 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
13516 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13517 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
13518 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
13519 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
13520 "Got unexpected bit count %u for format %s.\n",
13521 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
13522 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
13523 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
13524 "Got unexpected compression %#x for format %s.\n",
13525 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
13526 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
13527 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
13528 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
13529 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
13530 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
13531 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
13532 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
13533 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
13534 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
13535 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
13537 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
13539 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
13540 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
13541 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
13542 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
13543 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
13544 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13548 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
13549 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
13550 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13552 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
13553 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
13555 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13556 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13560 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13563 IDirectDrawSurface7_Release(surface
);
13568 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
13569 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
| DDSCAPS2_TEXTUREMANAGE
;
13570 if (FAILED(hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13572 skip("Failed to create cube texture for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
13576 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &caps
, &surface2
);
13577 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13578 hr
= IDirectDrawSurface7_GetAttachedSurface(surface2
, &caps
, &tmp
);
13579 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13580 IDirectDrawSurface7_Release(surface2
);
13581 hr
= IDirectDrawSurface7_GetAttachedSurface(tmp
, &caps
, &surface2
);
13582 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13583 IDirectDrawSurface7_Release(tmp
);
13585 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13586 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13587 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13588 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13589 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13590 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13591 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13592 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13594 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13595 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13596 dc2
= (void *)0x1234;
13597 hr
= IDirectDrawSurface7_GetDC(surface
, &dc2
);
13598 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13599 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13600 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13601 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13602 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13603 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13605 map_desc
.dwSize
= sizeof(map_desc
);
13606 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13607 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13608 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13609 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13610 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13611 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13612 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13613 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13615 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13616 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13617 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13618 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13619 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13620 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13622 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13623 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13624 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13625 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13626 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13627 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13628 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13629 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13631 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13632 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13633 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc2
);
13634 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13635 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc2
);
13636 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13637 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13638 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13640 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13641 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13642 hr
= IDirectDrawSurface7_GetDC(surface
, &dc2
);
13643 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13644 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc2
);
13645 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13646 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13647 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13649 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13650 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13651 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13652 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13653 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13654 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13655 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13656 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13658 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13659 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13660 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13661 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13662 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13663 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13664 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13665 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13667 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13668 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13669 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13670 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13671 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13672 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13673 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13674 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13676 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13677 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13678 hr
= IDirectDrawSurface7_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13679 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13680 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13681 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13682 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13683 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13685 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13686 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13687 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13688 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13689 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13690 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13691 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13692 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13694 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13695 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13696 hr
= IDirectDrawSurface7_GetDC(surface2
, &dc
);
13697 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13698 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13699 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13700 hr
= IDirectDrawSurface7_ReleaseDC(surface2
, dc
);
13701 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13702 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
13703 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13705 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13706 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13707 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
13708 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13709 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13710 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13711 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
13712 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
13713 hr
= IDirectDrawSurface7_Unlock(surface2
, NULL
);
13714 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
13716 IDirectDrawSurface7_Release(surface2
);
13717 IDirectDrawSurface7_Release(surface
);
13720 IDirectDraw7_Release(ddraw
);
13721 DestroyWindow(window
);
13724 static void test_draw_primitive(void)
13726 static WORD indices
[] = {0, 1, 2, 3};
13727 static struct vec3 quad
[] =
13729 {-1.0f
, -1.0f
, 0.0f
},
13730 {-1.0f
, 1.0f
, 0.0f
},
13731 { 1.0f
, -1.0f
, 0.0f
},
13732 { 1.0f
, 1.0f
, 0.0f
},
13734 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
13735 D3DVERTEXBUFFERDESC vb_desc
;
13736 IDirect3DVertexBuffer7
*vb
;
13737 IDirect3DDevice7
*device
;
13739 IDirectDraw7
*ddraw
;
13745 window
= create_window();
13746 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13748 skip("Failed to create a 3D device, skipping test.\n");
13749 DestroyWindow(window
);
13753 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13754 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
13755 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13756 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13758 memset(&vb_desc
, 0, sizeof(vb_desc
));
13759 vb_desc
.dwSize
= sizeof(vb_desc
);
13760 vb_desc
.dwFVF
= D3DFVF_XYZ
;
13761 vb_desc
.dwNumVertices
= 4;
13762 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
13763 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
13765 IDirect3D7_Release(d3d
);
13767 memset(&strided
, 0, sizeof(strided
));
13769 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
13770 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13771 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13772 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
13773 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13774 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, NULL
, 0, 0);
13775 todo_wine
ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
13776 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, NULL
, 0, 0);
13777 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13778 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
13779 /* r200 rejects 0 vertices */
13780 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13781 hr
= IDirect3DDevice7_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
13782 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13783 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
13784 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13786 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
13787 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13788 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13789 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
13790 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13791 /* Interestingly r200 rejects this, but not the call with a NULL index buffer and 0 indices. */
13792 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, indices
, 4, 0);
13793 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13795 strided
.position
.lpvData
= quad
;
13796 strided
.position
.dwStride
= sizeof(*quad
);
13797 hr
= IDirect3DVertexBuffer7_Lock(vb
, 0, &data
, NULL
);
13798 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
13799 memcpy(data
, quad
, sizeof(quad
));
13800 hr
= IDirect3DVertexBuffer7_Unlock(vb
);
13801 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
13803 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
13804 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13805 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13806 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
13807 /* r200 again fails this, this time with E_OUTOFMEMORY. */
13808 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_OUTOFMEMORY
), "Failed to draw, hr %#x.\n", hr
);
13809 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, NULL
, 0, 0);
13810 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13811 /* Now this draw should work, but r200 rejects it too - presumably earlier tests broke
13812 * driver internal state. */
13813 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
13814 ok(SUCCEEDED(hr
) || broken(ddraw_is_amd(ddraw
) && hr
== E_FAIL
), "Failed to draw, hr %#x.\n", hr
);
13815 hr
= IDirect3DDevice7_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
13816 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13817 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
13818 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13820 hr
= IDirect3DDevice7_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
13821 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13822 hr
= IDirect3DDevice7_DrawIndexedPrimitiveStrided(device
,
13823 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
13824 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13825 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, indices
, 4, 0);
13826 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13828 IDirect3DVertexBuffer7_Release(vb
);
13829 IDirectDraw7_Release(ddraw
);
13830 refcount
= IDirect3DDevice7_Release(device
);
13831 ok(!refcount
, "Device has %u references left.\n", refcount
);
13832 DestroyWindow(window
);
13835 static void test_edge_antialiasing_blending(void)
13837 IDirectDrawSurface7
*offscreen
;
13838 DDSURFACEDESC2 surface_desc
;
13839 D3DDEVICEDESC7 device_desc
;
13840 IDirect3DDevice7
*device
;
13841 IDirectDraw7
*ddraw
;
13848 static D3DMATRIX mat
=
13850 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13851 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13852 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13853 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13857 struct vec3 position
;
13862 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
13863 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
13864 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
13865 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
13869 struct vec3 position
;
13874 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
13875 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
13876 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
13877 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
13880 window
= create_window();
13881 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13883 skip("Failed to create a 3D device.\n");
13884 DestroyWindow(window
);
13888 hr
= IDirect3DDevice7_GetCaps(device
, &device_desc
);
13889 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
13890 trace("Line edge antialiasing support: %#x.\n",
13891 device_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
13892 trace("Triangle edge antialiasing support: %#x.\n",
13893 device_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
13895 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
13896 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
13897 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
13898 ok(SUCCEEDED(hr
), "Failed to get DirectDraw7 interface, hr %#x.\n", hr
);
13899 IDirect3D7_Release(d3d
);
13901 memset(&surface_desc
, 0, sizeof(surface_desc
));
13902 surface_desc
.dwSize
= sizeof(surface_desc
);
13903 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13904 surface_desc
.dwWidth
= 640;
13905 surface_desc
.dwHeight
= 480;
13906 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
13907 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13908 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
13909 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
13910 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
13911 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
13912 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
13913 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
13914 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
13916 hr
= IDirect3DDevice7_SetRenderTarget(device
, offscreen
, 0);
13917 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
13919 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
13920 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13921 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
13922 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
13923 hr
= IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
13924 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
13925 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
13926 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
13927 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13928 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
13929 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13930 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
13931 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
13932 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
13933 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13934 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
13935 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13936 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
13938 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
13939 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
13940 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
13941 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
13942 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
13943 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
13945 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
13946 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
13947 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
13948 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
13949 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
13950 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
13951 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
13952 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
13954 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
13955 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13956 hr
= IDirect3DDevice7_BeginScene(device
);
13957 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13958 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13960 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13961 hr
= IDirect3DDevice7_EndScene(device
);
13962 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13963 color
= get_surface_color(offscreen
, 320, 240);
13964 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
13966 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
13967 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13968 hr
= IDirect3DDevice7_BeginScene(device
);
13969 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13970 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13972 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13973 hr
= IDirect3DDevice7_EndScene(device
);
13974 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13975 color
= get_surface_color(offscreen
, 320, 240);
13976 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
13978 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
13979 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
13981 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
13982 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13983 hr
= IDirect3DDevice7_BeginScene(device
);
13984 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13985 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13987 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13988 hr
= IDirect3DDevice7_EndScene(device
);
13989 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13990 color
= get_surface_color(offscreen
, 320, 240);
13991 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13993 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
13994 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
13995 hr
= IDirect3DDevice7_BeginScene(device
);
13996 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13997 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13999 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14000 hr
= IDirect3DDevice7_EndScene(device
);
14001 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14002 color
= get_surface_color(offscreen
, 320, 240);
14003 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14005 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
14006 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
14008 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14009 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14010 hr
= IDirect3DDevice7_BeginScene(device
);
14011 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14012 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14014 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14015 hr
= IDirect3DDevice7_EndScene(device
);
14016 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14017 color
= get_surface_color(offscreen
, 320, 240);
14018 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14020 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14021 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14022 hr
= IDirect3DDevice7_BeginScene(device
);
14023 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14024 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14026 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14027 hr
= IDirect3DDevice7_EndScene(device
);
14028 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14029 color
= get_surface_color(offscreen
, 320, 240);
14030 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14032 IDirectDrawSurface7_Release(offscreen
);
14033 IDirectDraw7_Release(ddraw
);
14034 refcount
= IDirect3DDevice7_Release(device
);
14035 ok(!refcount
, "Device has %u references left.\n", refcount
);
14036 DestroyWindow(window
);
14039 static void test_display_mode_surface_pixel_format(void)
14041 unsigned int width
, height
, bpp
;
14042 IDirectDrawSurface7
*surface
;
14043 DDSURFACEDESC2 surface_desc
;
14044 IDirectDraw7
*ddraw
;
14049 if (!(ddraw
= create_ddraw()))
14051 skip("Failed to create ddraw.\n");
14055 surface_desc
.dwSize
= sizeof(surface_desc
);
14056 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
14057 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14058 width
= surface_desc
.dwWidth
;
14059 height
= surface_desc
.dwHeight
;
14061 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14062 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
14063 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14064 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14067 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
14069 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
14071 if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
14073 ok(bpp
, "Set display mode failed.\n");
14075 surface_desc
.dwSize
= sizeof(surface_desc
);
14076 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
14077 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14078 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
14079 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
14080 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14081 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14083 memset(&surface_desc
, 0, sizeof(surface_desc
));
14084 surface_desc
.dwSize
= sizeof(surface_desc
);
14085 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14086 U5(surface_desc
).dwBackBufferCount
= 1;
14087 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
14088 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14089 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14090 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
14091 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14092 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
14093 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
14094 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
14095 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
14096 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14097 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14098 IDirectDrawSurface7_Release(surface
);
14100 memset(&surface_desc
, 0, sizeof(surface_desc
));
14101 surface_desc
.dwSize
= sizeof(surface_desc
);
14102 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
14103 surface_desc
.dwWidth
= width
;
14104 surface_desc
.dwHeight
= height
;
14105 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14106 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14107 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14108 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
14109 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
14110 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
14111 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
14112 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
14113 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14114 IDirectDrawSurface7_Release(surface
);
14116 /* Test compatibility mode mipmap texture creation. */
14117 hr
= IDirectDraw7_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0);
14118 ok(hr
== DD_OK
|| hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
14121 win_skip("SetDisplayMode failed, skipping test.");
14126 memset(&surface_desc
, 0, sizeof(surface_desc
));
14127 surface_desc
.dwSize
= sizeof(surface_desc
);
14128 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
| DDSD_PITCH
;
14129 U2(surface_desc
).dwMipMapCount
= 2;
14130 surface_desc
.dwWidth
= 4;
14131 surface_desc
.dwHeight
= 4;
14132 U1(surface_desc
).lPitch
= surface_desc
.dwWidth
* bpp
/ 8;
14133 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
| DDSCAPS_VIDEOMEMORY
;
14134 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14135 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#x.\n", hr
);
14137 IDirectDrawSurface7_Release(surface
);
14140 refcount
= IDirectDraw7_Release(ddraw
);
14141 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14142 DestroyWindow(window
);
14145 static void test_surface_desc_size(void)
14150 DDSURFACEDESC desc1
;
14151 DDSURFACEDESC2 desc2
;
14154 IDirectDrawSurface7
*surface7
;
14155 IDirectDrawSurface3
*surface3
;
14156 IDirectDrawSurface
*surface
;
14157 DDSURFACEDESC2 surface_desc
;
14158 HRESULT expected_hr
, hr
;
14159 IDirectDraw7
*ddraw
;
14163 static const struct
14170 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
14171 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
14172 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
14174 static const unsigned int desc_sizes
[] =
14176 sizeof(DDSURFACEDESC
),
14177 sizeof(DDSURFACEDESC2
),
14178 sizeof(DDSURFACEDESC
) + 1,
14179 sizeof(DDSURFACEDESC2
) + 1,
14180 2 * sizeof(DDSURFACEDESC
),
14181 2 * sizeof(DDSURFACEDESC2
),
14182 sizeof(DDSURFACEDESC
) - 1,
14183 sizeof(DDSURFACEDESC2
) - 1,
14184 sizeof(DDSURFACEDESC
) / 2,
14185 sizeof(DDSURFACEDESC2
) / 2,
14190 sizeof(desc
) - 100,
14193 if (!(ddraw
= create_ddraw()))
14195 skip("Failed to create ddraw.\n");
14198 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
14199 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14201 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
14203 memset(&surface_desc
, 0, sizeof(surface_desc
));
14204 surface_desc
.dwSize
= sizeof(surface_desc
);
14205 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
14206 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
14207 surface_desc
.dwHeight
= 128;
14208 surface_desc
.dwWidth
= 128;
14209 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface7
, NULL
)))
14211 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
14214 hr
= IDirectDrawSurface_QueryInterface(surface7
, &IID_IDirectDrawSurface
, (void **)&surface
);
14215 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
14216 hr
= IDirectDrawSurface_QueryInterface(surface7
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
14217 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
14219 /* GetSurfaceDesc() */
14220 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14222 memset(&desc
, 0, sizeof(desc
));
14223 desc
.dwSize
= desc_sizes
[j
];
14224 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14225 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
14226 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14227 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14229 memset(&desc
, 0, sizeof(desc
));
14230 desc
.dwSize
= desc_sizes
[j
];
14231 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14232 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
14233 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14234 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14236 memset(&desc
, 0, sizeof(desc
));
14237 desc
.dwSize
= desc_sizes
[j
];
14238 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
14239 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
14240 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14241 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14245 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14247 const BOOL ignore_size
= surface_caps
[i
].caps
& DDSCAPS_TEXTURE
14248 && !(surface_caps
[i
].caps
& DDSCAPS_VIDEOMEMORY
);
14249 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
14250 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
14251 DWORD expected_texture_stage
;
14253 memset(&desc
, 0, sizeof(desc
));
14254 desc
.dwSize
= desc_sizes
[j
];
14255 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14256 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14257 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
14258 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14259 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14260 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14261 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14262 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14263 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14264 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14267 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14268 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14269 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14270 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14271 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14272 todo_wine_if(!expected_texture_stage
)
14273 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14274 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14275 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14276 IDirectDrawSurface_Unlock(surface
, NULL
);
14279 memset(&desc
, 0, sizeof(desc
));
14280 desc
.dwSize
= desc_sizes
[j
];
14281 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14282 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14283 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
14284 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14285 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14286 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14287 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14288 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14289 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14290 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14293 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14294 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14295 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14296 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14297 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14298 todo_wine_if(!expected_texture_stage
)
14299 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14300 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14301 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14302 IDirectDrawSurface3_Unlock(surface3
, NULL
);
14305 memset(&desc
, 0, sizeof(desc
));
14306 desc
.dwSize
= desc_sizes
[j
];
14307 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
14308 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
14309 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
14310 expected_hr
= ignore_size
|| valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
14311 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
14312 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
14313 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
14314 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
14315 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
14316 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
14319 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
14320 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
14321 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
14322 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
14323 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
14324 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
14325 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
14326 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
14327 IDirectDrawSurface7_Unlock(surface7
, NULL
);
14331 IDirectDrawSurface7_Release(surface7
);
14332 IDirectDrawSurface3_Release(surface3
);
14333 IDirectDrawSurface_Release(surface
);
14336 /* GetDisplayMode() */
14337 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
14339 memset(&desc
, 0xcc, sizeof(desc
));
14340 desc
.dwSize
= desc_sizes
[j
];
14341 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
14342 ? DD_OK
: DDERR_INVALIDPARAMS
;
14343 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &desc
.desc2
);
14344 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
14347 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
14348 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
14349 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
14353 refcount
= IDirectDraw7_Release(ddraw
);
14354 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14357 static void test_get_surface_from_dc(void)
14359 IDirectDrawSurface
*surface1
, *tmp1
;
14360 IDirectDrawSurface7
*surface
, *tmp
;
14361 DDSURFACEDESC2 surface_desc
;
14362 IDirectDraw7
*ddraw
;
14369 window
= create_window();
14370 ddraw
= create_ddraw();
14371 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14372 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14373 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14375 memset(&surface_desc
, 0, sizeof(surface_desc
));
14376 surface_desc
.dwSize
= sizeof(surface_desc
);
14377 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14378 surface_desc
.dwWidth
= 64;
14379 surface_desc
.dwHeight
= 64;
14380 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14382 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14383 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14384 hr
= IDirectDrawSurface7_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
14385 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14387 refcount
= get_refcount((IUnknown
*)surface1
);
14388 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14389 refcount
= get_refcount((IUnknown
*)surface
);
14390 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14392 hr
= IDirectDrawSurface7_GetDC(surface
, &dc
);
14393 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
14395 tmp1
= (void *)0xdeadbeef;
14396 device_dc
= (void *)0xdeadbeef;
14397 hr
= GetSurfaceFromDC(NULL
, &tmp1
, &device_dc
);
14398 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14399 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14400 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
14402 device_dc
= (void *)0xdeadbeef;
14403 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
14404 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14405 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
14407 tmp1
= (void *)0xdeadbeef;
14408 hr
= GetSurfaceFromDC(dc
, &tmp1
, NULL
);
14409 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14410 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14412 hr
= GetSurfaceFromDC(dc
, &tmp1
, &device_dc
);
14413 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14414 ok(tmp1
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp1
, surface1
);
14415 IDirectDrawSurface_Release(tmp1
);
14417 ret
= GetObjectType(device_dc
);
14418 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#x.\n", ret
);
14419 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
14420 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#x.\n", ret
);
14422 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, NULL
);
14423 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14425 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, &tmp
);
14426 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14427 ok(tmp
== surface
, "Got unexpected surface %p, expected %p.\n", tmp
, surface
);
14429 refcount
= get_refcount((IUnknown
*)surface1
);
14430 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14431 refcount
= get_refcount((IUnknown
*)surface
);
14432 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14434 hr
= IDirectDrawSurface7_ReleaseDC(surface
, dc
);
14435 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#x.\n", hr
);
14437 IDirectDrawSurface_Release(tmp
);
14439 dc
= CreateCompatibleDC(NULL
);
14440 ok(!!dc
, "CreateCompatibleDC failed.\n");
14442 tmp1
= (void *)0xdeadbeef;
14443 device_dc
= (void *)0xdeadbeef;
14444 hr
= GetSurfaceFromDC(dc
, &tmp1
, &device_dc
);
14445 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14446 ok(!tmp1
, "Got unexpected surface %p.\n", tmp1
);
14447 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
14449 tmp
= (void *)0xdeadbeef;
14450 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, dc
, &tmp
);
14451 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14452 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14454 ok(DeleteDC(dc
), "DeleteDC failed.\n");
14456 tmp
= (void *)0xdeadbeef;
14457 hr
= IDirectDraw7_GetSurfaceFromDC(ddraw
, NULL
, &tmp
);
14458 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14459 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14461 IDirectDrawSurface7_Release(surface
);
14462 IDirectDrawSurface_Release(surface1
);
14463 IDirectDraw7_Release(ddraw
);
14464 DestroyWindow(window
);
14467 static void test_ck_operation(void)
14469 IDirectDrawSurface7
*src
, *dst
;
14470 IDirectDrawSurface
*src1
, *dst1
;
14471 DDSURFACEDESC2 surface_desc
;
14472 IDirectDraw7
*ddraw
;
14481 window
= create_window();
14482 ddraw
= create_ddraw();
14483 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14484 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14485 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14487 memset(&surface_desc
, 0, sizeof(surface_desc
));
14488 surface_desc
.dwSize
= sizeof(surface_desc
);
14489 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14490 surface_desc
.dwWidth
= 4;
14491 surface_desc
.dwHeight
= 1;
14492 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14493 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
14494 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14495 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14496 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14497 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14498 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14499 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14501 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
14502 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
14503 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
14504 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14505 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14507 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14508 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14509 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14510 color
= surface_desc
.lpSurface
;
14511 color
[0] = 0x77010203;
14512 color
[1] = 0x00010203;
14513 color
[2] = 0x77ff00ff;
14514 color
[3] = 0x00ff00ff;
14515 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
14516 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14518 for (i
= 0; i
< 2; ++i
)
14520 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14521 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14522 color
= surface_desc
.lpSurface
;
14523 color
[0] = 0xcccccccc;
14524 color
[1] = 0xcccccccc;
14525 color
[2] = 0xcccccccc;
14526 color
[3] = 0xcccccccc;
14527 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14528 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14532 hr
= IDirectDrawSurface7_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
14533 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14537 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
14538 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14541 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
14542 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14543 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14544 color
= surface_desc
.lpSurface
;
14545 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
14546 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
14547 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
14548 * color keying nor copies it. */
14549 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
14550 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
14551 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14552 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
14553 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14554 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
14555 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
14556 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
14557 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
14558 color
[0], color
[1], color
[2], color
[3], i
);
14559 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14560 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14563 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14564 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14565 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
14566 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14568 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14569 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14570 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14572 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14573 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14574 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14575 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
14576 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14578 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
14579 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
14580 hr
= IDirectDrawSurface7_GetSurfaceDesc(src
, &surface_desc
);
14581 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
14582 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
14583 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
14584 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
14585 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
14587 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
14588 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14589 ckey
.dwColorSpaceHighValue
= 0x00000000;
14590 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14591 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14593 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14594 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14595 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14596 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14597 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14599 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14600 ckey
.dwColorSpaceHighValue
= 0x00000001;
14601 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14602 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14604 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14605 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14606 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14607 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14608 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14610 ckey
.dwColorSpaceLowValue
= 0x000000fe;
14611 ckey
.dwColorSpaceHighValue
= 0x000000fd;
14612 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14613 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14615 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14616 hr
= IDirectDrawSurface7_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14617 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14618 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
14619 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14621 IDirectDrawSurface7_Release(src
);
14622 IDirectDrawSurface7_Release(dst
);
14624 /* Test source and destination keys and where they are read from. Use a surface with alpha
14625 * to avoid driver-dependent content in the X channel. */
14626 memset(&surface_desc
, 0, sizeof(surface_desc
));
14627 surface_desc
.dwSize
= sizeof(surface_desc
);
14628 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14629 surface_desc
.dwWidth
= 6;
14630 surface_desc
.dwHeight
= 1;
14631 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14632 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
14633 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14634 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14635 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14636 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14637 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
14638 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14639 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14640 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14641 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14643 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
14644 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14645 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
14646 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14647 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
14648 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
14649 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
14650 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
14653 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
14654 skip("Failed to set destination color key, skipping related tests.\n");
14658 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14659 ckey
.dwColorSpaceHighValue
= 0x000000ff;
14660 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14661 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14662 ckey
.dwColorSpaceLowValue
= 0x000000aa;
14663 ckey
.dwColorSpaceHighValue
= 0x000000aa;
14664 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
14665 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14667 memset(&fx
, 0, sizeof(fx
));
14668 fx
.dwSize
= sizeof(fx
);
14669 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
14670 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
14671 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
14672 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
14674 hr
= IDirectDrawSurface7_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14675 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14676 color
= surface_desc
.lpSurface
;
14677 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
14678 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
14679 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
14680 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
14681 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
14682 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
14683 hr
= IDirectDrawSurface7_Unlock(src
, NULL
);
14684 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14686 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14687 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14688 color
= surface_desc
.lpSurface
;
14689 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14690 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14691 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14693 /* Test a blit without keying. */
14694 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
14695 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14697 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14698 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14699 color
= surface_desc
.lpSurface
;
14700 /* Should have copied src data unmodified to dst. */
14701 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14702 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14703 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14704 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14706 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14707 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14708 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14711 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
14712 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14714 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14715 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14716 color
= surface_desc
.lpSurface
;
14717 /* Src key applied to color[0]. It is unmodified, the others are copied. */
14718 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14719 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14720 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14721 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14723 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14724 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14725 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14727 /* Src override. */
14728 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
14729 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14731 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14732 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14733 color
= surface_desc
.lpSurface
;
14734 /* Override key applied to color[5]. It is unmodified, the others are copied. */
14735 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14736 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
14737 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14738 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14740 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14741 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14742 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14744 /* Src override AND src key. That is not supposed to work. */
14745 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
14746 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14748 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14749 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14750 color
= surface_desc
.lpSurface
;
14751 /* Ensure the destination was not changed. */
14752 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
14753 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
14754 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14755 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14757 /* Use different dst colors for the dst key test. */
14758 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14759 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14760 color
[2] = 0x00001100; /* Dest key in override. */
14761 color
[3] = 0x00001100; /* Dest key in override. */
14762 color
[4] = 0x000000aa; /* Dest key in src surface. */
14763 color
[5] = 0x000000aa; /* Dest key in src surface. */
14764 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14765 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14767 /* Dest key blit. The key is taken from the DESTINATION surface in v7! */
14768 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14769 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14771 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14772 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14773 color
= surface_desc
.lpSurface
;
14774 /* Dst key applied to color[0,1], they are the only changed pixels. */
14775 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
14776 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14777 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14778 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14780 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14781 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14782 color
[2] = 0x00001100; /* Dest key in override. */
14783 color
[3] = 0x00001100; /* Dest key in override. */
14784 color
[4] = 0x000000aa; /* Dest key in src surface. */
14785 color
[5] = 0x000000aa; /* Dest key in src surface. */
14786 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14787 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14789 /* What happens with a QI'd older version of the interface? It takes the key
14790 * from the source surface. */
14791 hr
= IDirectDrawSurface7_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
14792 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14793 hr
= IDirectDrawSurface7_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
14794 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14796 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
14797 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14799 IDirectDrawSurface_Release(dst1
);
14800 IDirectDrawSurface_Release(src1
);
14802 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14803 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14804 color
= surface_desc
.lpSurface
;
14805 /* Dst key applied to color[4,5], they are the only changed pixels. */
14806 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14807 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14808 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14809 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14811 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14812 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14813 color
[2] = 0x00001100; /* Dest key in override. */
14814 color
[3] = 0x00001100; /* Dest key in override. */
14815 color
[4] = 0x000000aa; /* Dest key in src surface. */
14816 color
[5] = 0x000000aa; /* Dest key in src surface. */
14817 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14818 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14820 /* Dest override key blit. */
14821 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
14822 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14824 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14825 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14826 color
= surface_desc
.lpSurface
;
14827 /* Dst key applied to color[2,3], they are the only changed pixels. */
14828 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
14829 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14830 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14831 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14833 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14834 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14835 color
[2] = 0x00001100; /* Dest key in override. */
14836 color
[3] = 0x00001100; /* Dest key in override. */
14837 color
[4] = 0x000000aa; /* Dest key in src surface. */
14838 color
[5] = 0x000000aa; /* Dest key in src surface. */
14839 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14840 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14842 /* Dest override together with surface key. Supposed to fail. */
14843 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
14844 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14846 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14847 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14848 color
= surface_desc
.lpSurface
;
14849 /* Destination is unchanged. */
14850 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14851 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14852 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14853 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14854 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14855 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14857 /* Source and destination key. This is driver dependent. New HW treats it like
14858 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
14861 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
14862 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14864 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14865 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14866 color
= surface_desc
.lpSurface
;
14867 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
14868 * the driver applies it. */
14869 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14870 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14871 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14872 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14874 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14875 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14876 color
[2] = 0x00001100; /* Dest key in override. */
14877 color
[3] = 0x00001100; /* Dest key in override. */
14878 color
[4] = 0x000000aa; /* Dest key in src surface. */
14879 color
[5] = 0x000000aa; /* Dest key in src surface. */
14880 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14881 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14884 /* Override keys without ddbltfx parameter fail */
14885 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
14886 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14887 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
14888 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14890 /* Try blitting without keys in the source surface. */
14891 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
14892 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14893 hr
= IDirectDrawSurface7_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
14894 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14896 /* That fails now. Do not bother to check that the data is unmodified. */
14897 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
14898 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14900 /* Dest key blit still works, the destination surface key is used in v7. */
14901 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14902 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14904 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14905 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14906 color
= surface_desc
.lpSurface
;
14907 /* Dst key applied to color[0,1], they are the only changed pixels. */
14908 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
14909 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14910 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14911 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14912 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14913 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14915 /* Try blitting without keys in the destination surface. */
14916 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
14917 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14918 hr
= IDirectDrawSurface7_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
14919 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14921 /* This fails, as sanity would dictate. */
14922 hr
= IDirectDrawSurface7_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14923 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14926 IDirectDrawSurface7_Release(src
);
14927 IDirectDrawSurface7_Release(dst
);
14928 refcount
= IDirectDraw7_Release(ddraw
);
14929 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14930 DestroyWindow(window
);
14933 static void test_vb_refcount(void)
14935 ULONG prev_d3d_refcount
, prev_device_refcount
;
14936 ULONG cur_d3d_refcount
, cur_device_refcount
;
14937 IDirect3DVertexBuffer7
*vb
, *vb7
;
14938 D3DVERTEXBUFFERDESC vb_desc
;
14939 IDirect3DVertexBuffer
*vb1
;
14940 IDirect3DDevice7
*device
;
14947 window
= create_window();
14948 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14950 skip("Failed to create a 3D device, skipping test.\n");
14951 DestroyWindow(window
);
14955 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
14956 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
14958 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
14959 prev_device_refcount
= get_refcount((IUnknown
*)device
);
14961 memset(&vb_desc
, 0, sizeof(vb_desc
));
14962 vb_desc
.dwSize
= sizeof(vb_desc
);
14963 vb_desc
.dwFVF
= D3DFVF_XYZ
;
14964 vb_desc
.dwNumVertices
= 4;
14965 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
14966 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14968 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
14969 cur_device_refcount
= get_refcount((IUnknown
*)device
);
14970 ok(cur_d3d_refcount
> prev_d3d_refcount
, "D3D object refcount didn't change from %u.\n", prev_d3d_refcount
);
14971 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %u to %u.\n",
14972 prev_device_refcount
, cur_device_refcount
);
14974 prev_d3d_refcount
= cur_d3d_refcount
;
14975 hr
= IDirect3DVertexBuffer7_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
14976 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer7, hr %#x.\n", hr
);
14977 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
14978 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %u to %u.\n",
14979 prev_d3d_refcount
, cur_d3d_refcount
);
14980 IDirect3DVertexBuffer7_Release(vb7
);
14982 hr
= IDirect3DVertexBuffer7_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
14983 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer returned unexpected hr %#x.\n", hr
);
14985 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
14986 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#x.\n", hr
);
14987 ok((IUnknown
*)vb
== unk
,
14988 "IDirect3DVertexBuffer7 and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
14989 IUnknown_Release(unk
);
14991 refcount
= IDirect3DVertexBuffer7_Release(vb
);
14992 ok(!refcount
, "Vertex buffer has %u references left.\n", refcount
);
14994 IDirect3D7_Release(d3d
);
14995 refcount
= IDirect3DDevice7_Release(device
);
14996 ok(!refcount
, "Device has %u references left.\n", refcount
);
14997 DestroyWindow(window
);
15000 static void test_compute_sphere_visibility(void)
15002 static D3DVALUE clip_plane
[4] = {1.0f
, 0.0f
, 0.0f
, 0.5f
};
15003 static D3DMATRIX proj_1
=
15005 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
15006 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
15007 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
15008 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
15010 static D3DMATRIX proj_2
=
15012 10.0f
, 0.0f
, 0.0f
, 0.0f
,
15013 0.0f
, 10.0f
, 0.0f
, 0.0f
,
15014 0.0f
, 0.0f
, 10.0f
, 0.0f
,
15015 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15017 static D3DMATRIX view_1
=
15019 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
15020 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
15021 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
15022 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
15024 static D3DMATRIX identity
=
15026 1.0f
, 0.0f
, 0.0f
, 0.0f
,
15027 0.0f
, 1.0f
, 0.0f
, 0.0f
,
15028 0.0f
, 0.0f
, 1.0f
, 0.0f
,
15029 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15033 D3DMATRIX
*view
, *proj
;
15034 unsigned int sphere_count
;
15035 D3DVECTOR center
[3];
15036 D3DVALUE radius
[3];
15037 DWORD enable_planes
;
15038 const DWORD expected
[3];
15042 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, 0, {0x3f}},
15043 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
15044 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
15045 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
15046 {4.354097f
, 12.500704f
, 17.251318f
}, 0, {0x103d, 0x3f, 0x3f}},
15047 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, 0, {0}},
15048 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, 0, {0}},
15049 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, 0, {0}},
15050 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, 0, {0x9}}, /* 5 */
15051 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x103d}},
15052 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x203e}},
15053 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x803b}},
15054 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, 0, {0x4037}},
15055 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, 0, {0x1001f}}, /* 10 */
15056 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, 0, {0x2002f}},
15057 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {5.0f
}, 1, {0x7f}},
15058 {&identity
, &identity
, 1, {{{-0.5f
}, {0.0f
}, {0.0f
}}}, {5.0f
}, 1, {0x7f}},
15059 {&identity
, &identity
, 1, {{{-0.5f
}, {0.0f
}, {0.0f
}}}, {1.0f
}, 1, {0x51}},
15060 {&identity
, &identity
, 1, {{{-2.5f
}, {0.0f
}, {0.0f
}}}, {1.0f
}, 1, {0x41051}}, /* 15 */
15062 IDirect3DDevice7
*device
;
15069 window
= create_window();
15070 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15072 skip("Failed to create a 3D device, skipping test.\n");
15073 DestroyWindow(window
);
15077 hr
= IDirect3DDevice7_SetClipPlane(device
, 0, clip_plane
);
15078 ok(SUCCEEDED(hr
), "Failed to set user clip plane, hr %#x.\n", hr
);
15080 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
15082 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15084 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
15085 IDirect3DDevice7_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
15087 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
,
15088 tests
[i
].enable_planes
);
15089 ok(SUCCEEDED(hr
), "Failed to enable / disable user clip planes, hr %#x.\n", hr
);
15091 hr
= IDirect3DDevice7_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
15092 tests
[i
].sphere_count
, 0, result
);
15093 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15095 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
15096 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#x, got %#x.\n",
15097 i
, j
, tests
[i
].expected
[j
], result
[j
]);
15100 refcount
= IDirect3DDevice7_Release(device
);
15101 ok(!refcount
, "Device has %u references left.\n", refcount
);
15102 DestroyWindow(window
);
15105 static void test_clip_planes_limits(void)
15107 IDirect3DDevice7
*device
;
15108 D3DDEVICEDESC7 caps
;
15116 window
= create_window();
15117 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15119 skip("Failed to create 3D device.\n");
15120 DestroyWindow(window
);
15124 memset(&caps
, 0, sizeof(caps
));
15125 hr
= IDirect3DDevice7_GetCaps(device
, &caps
);
15126 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
15128 trace("Max user clip planes: %u.\n", caps
.wMaxUserClipPlanes
);
15130 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15132 memset(plane
, 0xff, sizeof(plane
));
15133 hr
= IDirect3DDevice7_GetClipPlane(device
, i
, plane
);
15134 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#x.\n", i
, hr
);
15135 ok(!plane
[0] && !plane
[1] && !plane
[2] && !plane
[3],
15136 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
15137 i
, plane
[0], plane
[1], plane
[2], plane
[3]);
15143 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15146 hr
= IDirect3DDevice7_SetClipPlane(device
, i
, plane
);
15147 ok(hr
== D3D_OK
, "Failed to set clip plane %u, hr %#x.\n", i
, hr
);
15149 for (i
= 0; i
< caps
.wMaxUserClipPlanes
; ++i
)
15151 memset(plane
, 0xff, sizeof(plane
));
15152 hr
= IDirect3DDevice7_GetClipPlane(device
, i
, plane
);
15153 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#x.\n", i
, hr
);
15154 ok(plane
[0] == 2.0f
&& plane
[1] == 8.0f
&& plane
[2] == 5.0f
&& plane
[3] == i
,
15155 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
15156 i
, plane
[0], plane
[1], plane
[2], plane
[3]);
15159 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, 0xffffffff);
15160 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15161 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, &state
);
15162 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
15163 ok(state
== 0xffffffff, "Got unexpected state %#x.\n", state
);
15164 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, 0x80000000);
15165 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15166 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_CLIPPLANEENABLE
, &state
);
15167 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
15168 ok(state
== 0x80000000, "Got unexpected state %#x.\n", state
);
15170 refcount
= IDirect3DDevice7_Release(device
);
15171 ok(!refcount
, "Device has %u references left.\n", refcount
);
15172 DestroyWindow(window
);
15175 static void test_texture_stages_limits(void)
15177 IDirectDrawSurface7
*texture
;
15178 DDSURFACEDESC2 surface_desc
;
15179 IDirect3DDevice7
*device
;
15180 IDirectDraw7
*ddraw
;
15187 window
= create_window();
15188 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15190 skip("Failed to create 3D device.\n");
15191 DestroyWindow(window
);
15194 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15195 ok(SUCCEEDED(hr
), "Failed to get Direct3D interface, hr %#x.\n", hr
);
15196 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15197 ok(SUCCEEDED(hr
), "Failed to get DirectDraw interface, hr %#x.\n", hr
);
15198 IDirect3D7_Release(d3d
);
15200 memset(&surface_desc
, 0, sizeof(surface_desc
));
15201 surface_desc
.dwSize
= sizeof(surface_desc
);
15202 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15203 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
15204 surface_desc
.dwWidth
= 16;
15205 surface_desc
.dwHeight
= 16;
15206 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
15207 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
15209 for (i
= 0; i
< 8; ++i
)
15211 hr
= IDirect3DDevice7_SetTexture(device
, i
, texture
);
15212 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
15213 hr
= IDirect3DDevice7_SetTexture(device
, i
, NULL
);
15214 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
15215 hr
= IDirect3DDevice7_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
15216 ok(hr
== D3D_OK
, "Failed to set texture stage state %u, hr %#x.\n", i
, hr
);
15219 IDirectDrawSurface7_Release(texture
);
15220 IDirectDraw7_Release(ddraw
);
15221 refcount
= IDirect3DDevice7_Release(device
);
15222 ok(!refcount
, "Device has %u references left.\n", refcount
);
15223 DestroyWindow(window
);
15226 static void test_set_render_state(void)
15228 IDirect3DDevice7
*device
;
15234 window
= create_window();
15235 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15237 skip("Failed to create 3D device.\n");
15238 DestroyWindow(window
);
15242 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
15243 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15244 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
15245 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15247 /* States deprecated in D3D7 */
15248 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
15249 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15250 state
= 0xdeadbeef;
15251 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
15252 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15253 ok(state
== 0xdeadbeef, "Got unexpected render state %#x.\n", state
);
15254 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
15255 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15256 state
= 0xdeadbeef;
15257 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
15258 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15259 ok(state
== 0xdeadbeef, "Got unexpected render state %#x.\n", state
);
15261 refcount
= IDirect3DDevice7_Release(device
);
15262 ok(!refcount
, "Device has %u references left.\n", refcount
);
15263 DestroyWindow(window
);
15266 static void test_map_synchronisation(void)
15268 LARGE_INTEGER frequency
, diff
, ts
[3];
15269 IDirect3DVertexBuffer7
*buffer
;
15270 unsigned int i
, j
, tri_count
;
15271 D3DVERTEXBUFFERDESC vb_desc
;
15272 IDirect3DDevice7
*device
;
15273 BOOL unsynchronised
, ret
;
15274 IDirectDrawSurface7
*rt
;
15275 IDirectDraw7
*ddraw
;
15282 static const struct
15284 unsigned int flags
;
15285 BOOL unsynchronised
;
15290 {DDLOCK_NOOVERWRITE
, TRUE
},
15291 {DDLOCK_DISCARDCONTENTS
, FALSE
},
15292 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, TRUE
},
15295 static const struct quad
15299 struct vec3 position
;
15306 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
15307 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
15308 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
15309 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
15315 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
15316 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
15317 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
15318 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
15321 struct quad
*quads
;
15323 window
= create_window();
15324 ok(!!window
, "Failed to create a window.\n");
15326 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15328 skip("Failed to create a D3D device, skipping tests.\n");
15329 DestroyWindow(window
);
15333 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15334 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15335 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15336 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15337 /* Maps are always synchronised on WARP. */
15338 if (ddraw_is_warp(ddraw
))
15340 skip("Running on WARP, skipping test.\n");
15344 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15345 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15347 tri_count
= 0x1000;
15349 ret
= QueryPerformanceFrequency(&frequency
);
15350 ok(ret
, "Failed to get performance counter frequency.\n");
15352 vb_desc
.dwSize
= sizeof(vb_desc
);
15353 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
15354 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
15355 vb_desc
.dwNumVertices
= tri_count
+ 2;
15356 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0);
15357 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
15358 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
15359 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15360 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
15364 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15365 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15367 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15368 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15370 /* Initial draw to initialise states, compile shaders, etc. */
15371 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15372 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15373 hr
= IDirect3DDevice7_BeginScene(device
);
15374 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15375 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15376 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15377 hr
= IDirect3DDevice7_EndScene(device
);
15378 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15379 /* Read the result to ensure the GPU has finished drawing. */
15380 colour
= get_surface_color(rt
, 320, 240);
15382 /* Time drawing tri_count triangles. */
15383 ret
= QueryPerformanceCounter(&ts
[0]);
15384 ok(ret
, "Failed to read performance counter.\n");
15385 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15386 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15387 hr
= IDirect3DDevice7_BeginScene(device
);
15388 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15389 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15390 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15391 hr
= IDirect3DDevice7_EndScene(device
);
15392 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15393 colour
= get_surface_color(rt
, 320, 240);
15394 /* Time drawing a single triangle. */
15395 ret
= QueryPerformanceCounter(&ts
[1]);
15396 ok(ret
, "Failed to read performance counter.\n");
15397 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15398 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15399 hr
= IDirect3DDevice7_BeginScene(device
);
15400 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15401 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
15402 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15403 hr
= IDirect3DDevice7_EndScene(device
);
15404 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15405 colour
= get_surface_color(rt
, 320, 240);
15406 ret
= QueryPerformanceCounter(&ts
[2]);
15407 ok(ret
, "Failed to read performance counter.\n");
15409 IDirect3DVertexBuffer7_Release(buffer
);
15411 /* Estimate the number of triangles we can draw in 100ms. */
15412 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
15413 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
15414 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
15415 vb_desc
.dwNumVertices
= tri_count
+ 2;
15417 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15419 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0);
15420 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
15421 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
15422 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15423 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
15427 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15428 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15430 /* Start a draw operation. */
15431 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15432 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15433 hr
= IDirect3DDevice7_BeginScene(device
);
15434 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15435 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
15436 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15437 hr
= IDirect3DDevice7_EndScene(device
);
15438 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15440 /* Map the last quad while the draw is in progress. */
15441 hr
= IDirect3DVertexBuffer7_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
15442 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
15443 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
15444 hr
= IDirect3DVertexBuffer7_Unlock(buffer
);
15445 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
15447 colour
= get_surface_color(rt
, 320, 240);
15448 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
15449 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
15450 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
15452 IDirect3DVertexBuffer7_Release(buffer
);
15455 IDirectDrawSurface7_Release(rt
);
15457 IDirectDraw7_Release(ddraw
);
15458 IDirect3D7_Release(d3d
);
15459 refcount
= IDirect3DDevice7_Release(device
);
15460 ok(!refcount
, "Device has %u references left.\n", refcount
);
15461 DestroyWindow(window
);
15464 static void test_depth_readback(void)
15466 DWORD depth
, expected_depth
, max_diff
, raw_value
, passed_fmts
= 0;
15467 IDirectDrawSurface7
*rt
, *ds
;
15468 DDSURFACEDESC2 surface_desc
;
15469 IDirect3DDevice7
*device
;
15470 unsigned int i
, x
, y
;
15471 IDirectDraw7
*ddraw
;
15477 BOOL all_zero
, all_one
, all_pass
;
15481 struct vec3 position
;
15486 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
15487 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
15488 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
15489 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
15492 static const struct
15494 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
15499 {16, 0, 0x0000ffff, 0x00000000},
15500 {24, 0, 0x00ffffff, 0x00000000},
15501 {32, 0, 0x00ffffff, 0x00000000},
15502 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
15503 {32, 0, 0xffffffff, 0x00000000},
15506 window
= create_window();
15507 ok(!!window
, "Failed to create a window.\n");
15509 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15511 skip("Failed to create a D3D device, skipping tests.\n");
15512 DestroyWindow(window
);
15516 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15517 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15518 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15519 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15521 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15522 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15524 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15525 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
15527 ds
= get_depth_stencil(device
);
15528 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
15529 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15530 IDirectDrawSurface7_Release(ds
);
15532 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15534 memset(&surface_desc
, 0, sizeof(surface_desc
));
15535 surface_desc
.dwSize
= sizeof(surface_desc
);
15536 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
15537 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
15538 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
15539 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
15540 if (tests
[i
].s_depth
)
15541 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
15542 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
15543 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
15544 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
15545 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
15546 surface_desc
.dwWidth
= 640;
15547 surface_desc
.dwHeight
= 480;
15548 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
15551 skip("Format %u not supported, skipping test.\n", i
);
15555 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
15556 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
15557 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
15558 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
15560 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
15561 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15562 hr
= IDirect3DDevice7_BeginScene(device
);
15563 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15564 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
15565 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15566 hr
= IDirect3DDevice7_EndScene(device
);
15567 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15569 all_zero
= all_one
= all_pass
= TRUE
;
15570 for (y
= 60; y
< 480; y
+= 120)
15572 for (x
= 80; x
< 640; x
+= 160)
15574 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
15575 memset(&surface_desc
, 0, sizeof(surface_desc
));
15576 surface_desc
.dwSize
= sizeof(surface_desc
);
15577 hr
= IDirectDrawSurface7_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
, NULL
);
15578 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
15580 raw_value
= *((DWORD
*)surface_desc
.lpSurface
);
15583 if (raw_value
!= 0x00ffffff)
15586 depth
= raw_value
& tests
[i
].z_mask
;
15587 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
15588 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
15589 /* This test is very reliably on AMD, but fails in a number of interesting ways on Nvidia GPUs:
15591 * Geforce 7 GPUs work only with D16. D24 and D24S8 return 0, D24X8 broken data.
15593 * Geforce 9 GPUs return broken data for D16 that resembles the expected data in
15594 * the lower 8 bits and has 0xff in the upper 8 bits. D24X8 works, D24 and D24S8 return
15597 * Geforce GTX 650 has working D16 and D24, but D24S8 returns 0.
15599 * Arx Fatalis is broken on the Geforce 9 in the same way it was broken in Wine (bug 43654).
15600 * The !tests[i].s_depth is supposed to rule out D16 on GF9 and D24X8 on GF7. */
15601 todo_wine_if(tests
[i
].todo
)
15602 ok(compare_uint(expected_depth
, depth
, max_diff
)
15603 || (ddraw_is_nvidia(ddraw
) && (all_zero
|| all_one
|| !tests
[i
].s_depth
)),
15604 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
15605 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
15606 if (!compare_uint(expected_depth
, depth
, max_diff
))
15609 hr
= IDirectDrawSurface7_Unlock(ds
, &r
);
15610 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
15616 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
15617 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15618 IDirectDrawSurface7_Release(ds
);
15621 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
15623 IDirectDrawSurface7_Release(rt
);
15624 IDirectDraw7_Release(ddraw
);
15625 IDirect3D7_Release(d3d
);
15626 refcount
= IDirect3DDevice7_Release(device
);
15627 ok(!refcount
, "Device has %u references left.\n", refcount
);
15628 DestroyWindow(window
);
15631 static void test_clear(void)
15633 IDirect3DDevice7
*device
;
15634 IDirectDrawSurface7
*rt
;
15635 D3DVIEWPORT7 vp
, old_vp
;
15636 IDirectDraw7
*ddraw
;
15637 D3DRECT rect_negneg
;
15645 window
= create_window();
15646 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15648 skip("Failed to create 3D device.\n");
15649 DestroyWindow(window
);
15653 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
15654 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
15655 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
15656 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15658 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
15659 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15661 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15662 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15664 /* Positive x, negative y. */
15665 U1(rect
[0]).x1
= 0;
15666 U2(rect
[0]).y1
= 480;
15667 U3(rect
[0]).x2
= 320;
15668 U4(rect
[0]).y2
= 240;
15670 /* Positive x, positive y. */
15671 U1(rect
[1]).x1
= 0;
15672 U2(rect
[1]).y1
= 0;
15673 U3(rect
[1]).x2
= 320;
15674 U4(rect
[1]).y2
= 240;
15676 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
15677 * refuse negative rectangles, but it will not clear them either. */
15678 hr
= IDirect3DDevice7_Clear(device
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
15679 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15681 color
= get_surface_color(rt
, 160, 360);
15682 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
15683 color
= get_surface_color(rt
, 160, 120);
15684 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
15685 color
= get_surface_color(rt
, 480, 360);
15686 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
15687 color
= get_surface_color(rt
, 480, 120);
15688 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
15690 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
15691 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15692 /* negative x, negative y.
15693 * Also ignored, except on WARP, which clears the entire screen. */
15694 U1(rect_negneg
).x1
= 640;
15695 U2(rect_negneg
).y1
= 240;
15696 U3(rect_negneg
).x2
= 320;
15697 U4(rect_negneg
).y2
= 0;
15698 hr
= IDirect3DDevice7_Clear(device
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15699 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15701 color
= get_surface_color(rt
, 160, 360);
15702 ok(compare_color(color
, 0x00ffffff, 0)
15703 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15704 "Got unexpected color 0x%08x.\n", color
);
15705 color
= get_surface_color(rt
, 160, 120);
15706 ok(compare_color(color
, 0x00ffffff, 0)
15707 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15708 "Got unexpected color 0x%08x.\n", color
);
15709 color
= get_surface_color(rt
, 480, 360);
15710 ok(compare_color(color
, 0x00ffffff, 0)
15711 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15712 "Got unexpected color 0x%08x.\n", color
);
15713 color
= get_surface_color(rt
, 480, 120);
15714 ok(compare_color(color
, 0x00ffffff, 0)
15715 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15716 "Got unexpected color 0x%08x.\n", color
);
15718 /* Test how the viewport affects clears. */
15719 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15720 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15721 hr
= IDirect3DDevice7_GetViewport(device
, &old_vp
);
15722 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#x.\n", hr
);
15730 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
15731 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15732 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15733 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15741 hr
= IDirect3DDevice7_SetViewport(device
, &vp
);
15742 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15744 U1(rect
[0]).x1
= 160;
15745 U2(rect
[0]).y1
= 120;
15746 U3(rect
[0]).x2
= 480;
15747 U4(rect
[0]).y2
= 360;
15748 hr
= IDirect3DDevice7_Clear(device
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15749 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15751 hr
= IDirect3DDevice7_SetViewport(device
, &old_vp
);
15752 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
15754 color
= get_surface_color(rt
, 158, 118);
15755 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
15756 color
= get_surface_color(rt
, 162, 118);
15757 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
15758 color
= get_surface_color(rt
, 158, 122);
15759 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
15760 color
= get_surface_color(rt
, 162, 122);
15761 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
15763 color
= get_surface_color(rt
, 318, 238);
15764 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
15765 color
= get_surface_color(rt
, 322, 238);
15766 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
15767 color
= get_surface_color(rt
, 318, 242);
15768 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
15769 color
= get_surface_color(rt
, 322, 242);
15770 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
15772 color
= get_surface_color(rt
, 478, 358);
15773 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
15774 color
= get_surface_color(rt
, 482, 358);
15775 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
15776 color
= get_surface_color(rt
, 478, 362);
15777 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
15778 color
= get_surface_color(rt
, 482, 362);
15779 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
15781 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
15784 IDirectDrawSurface7_Release(rt
);
15785 IDirectDraw7_Release(ddraw
);
15786 IDirect3D7_Release(d3d
);
15787 refcount
= IDirect3DDevice7_Release(device
);
15788 ok(!refcount
, "Device has %u references left.\n", refcount
);
15789 DestroyWindow(window
);
15792 struct enum_surfaces_param
15794 IDirectDraw7
*ddraw
;
15795 DDSURFACEDESC2 modes
[20];
15796 unsigned int mode_count
;
15798 IDirectDrawSurface7
*surfaces
[8];
15799 unsigned int count
;
15802 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC2
*desc
, void *context
)
15804 struct enum_surfaces_param
*param
= context
;
15805 IDirectDrawSurface7
*surface
;
15807 if (SUCCEEDED(IDirectDraw7_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
15809 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
15810 param
->modes
[param
->mode_count
] = *desc
;
15811 ++param
->mode_count
;
15812 IDirectDrawSurface7_Release(surface
);
15815 return DDENUMRET_OK
;
15818 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
15820 struct enum_surfaces_param
*param
= context
;
15821 BOOL found
= FALSE
;
15824 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
15826 if (param
->surfaces
[i
] == surface
)
15833 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
15834 IDirectDrawSurface7_Release(surface
);
15837 return DDENUMRET_OK
;
15840 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*desc
, void *context
)
15842 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
15843 struct enum_surfaces_param
*param
= context
;
15845 ok(!surface
, "Unexpected surface %p.\n", surface
);
15846 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#x.\n", desc
->dwFlags
);
15847 if (param
->count
< ARRAY_SIZE(param
->modes
))
15849 const DDSURFACEDESC2
*expect
= ¶m
->modes
[param
->count
];
15850 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %u, got %u.\n", expect
->dwWidth
, desc
->dwWidth
);
15851 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %u, got %u.\n", expect
->dwHeight
, desc
->dwHeight
);
15852 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
15853 "Pixel formats didn't match.\n");
15858 return DDENUMRET_OK
;
15861 static void test_enum_surfaces(void)
15863 struct enum_surfaces_param param
= {0};
15864 DDPIXELFORMAT current_format
;
15865 DDSURFACEDESC2 desc
;
15866 IDirectDraw7
*ddraw
;
15869 ddraw
= create_ddraw();
15870 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15871 param
.ddraw
= ddraw
;
15873 memset(&desc
, 0, sizeof(desc
));
15874 desc
.dwSize
= sizeof(desc
);
15875 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &desc
);
15876 ok(hr
== DD_OK
, "Failed to get display mode, hr %#x.\n", hr
);
15877 current_format
= U4(desc
).ddpfPixelFormat
;
15879 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
15880 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#x.\n", hr
);
15882 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
, NULL
, NULL
, NULL
);
15883 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15885 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
15886 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15888 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
15889 NULL
, NULL
, enum_surfaces_cb
);
15890 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15892 memset(&desc
, 0, sizeof(desc
));
15893 desc
.dwSize
= sizeof(desc
);
15894 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
15895 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
15896 U2(desc
).dwMipMapCount
= 3;
15898 desc
.dwHeight
= 32;
15899 if (FAILED(IDirectDraw7_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
)))
15901 win_skip("Failed to create a texture, skipping tests.\n");
15902 IDirectDraw7_Release(ddraw
);
15906 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
15907 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#x.\n", hr
);
15908 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
15909 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#x.\n", hr
);
15910 hr
= IDirectDrawSurface7_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
15911 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
15912 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
15915 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
15916 &desc
, ¶m
, enum_surfaces_cb
);
15917 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15918 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15921 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
15922 NULL
, ¶m
, enum_surfaces_cb
);
15923 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15924 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15926 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
15928 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
15929 &desc
, ¶m
, enum_surfaces_cb
);
15930 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15931 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15934 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
15935 &desc
, ¶m
, enum_surfaces_cb
);
15936 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15937 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15941 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
15942 &desc
, ¶m
, enum_surfaces_cb
);
15943 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15944 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15948 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
15949 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15950 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15952 IDirectDrawSurface7_Release(param
.surfaces
[2]);
15953 IDirectDrawSurface7_Release(param
.surfaces
[1]);
15954 IDirectDrawSurface7_Release(param
.surfaces
[0]);
15957 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
15958 NULL
, ¶m
, enum_surfaces_cb
);
15959 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15960 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15962 memset(&desc
, 0, sizeof(desc
));
15963 desc
.dwSize
= sizeof(desc
);
15964 desc
.dwFlags
= DDSD_CAPS
;
15965 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
15967 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
15968 &desc
, ¶m
, enum_surfaces_create_cb
);
15969 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15971 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
15972 &desc
, ¶m
, enum_surfaces_create_cb
);
15973 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15975 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
15976 &desc
, ¶m
, enum_surfaces_create_cb
);
15977 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15979 /* When not passed width and height, the callback is called with every
15980 * available display resolution. */
15982 param
.mode_count
= 0;
15983 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
15984 U4(desc
).ddpfPixelFormat
= current_format
;
15985 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
15986 ok(hr
== DD_OK
, "Failed to build mode list, hr %#x.\n", hr
);
15989 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
15990 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
15991 &desc
, ¶m
, enum_surfaces_create_cb
);
15992 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
15993 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
15995 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
15996 desc
.dwWidth
= desc
.dwHeight
= 32;
15998 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
16001 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16002 &desc
, ¶m
, enum_surfaces_create_cb
);
16003 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16004 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16006 hr
= IDirectDraw7_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
16007 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
16009 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16010 &desc
, ¶m
, enum_surfaces_create_cb
);
16011 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16012 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16013 IDirectDrawSurface7_Release(param
.surfaces
[0]);
16015 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
16016 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
16017 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
16018 U4(desc
).ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
16021 hr
= IDirectDraw7_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16022 &desc
, ¶m
, enum_surfaces_create_cb
);
16023 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#x.\n", hr
);
16024 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16026 IDirectDraw7_Release(ddraw
);
16029 static void test_viewport(void)
16035 RECT expected_rect
;
16036 const char *message
;
16040 {{ 0, 0, 640, 480}, 0.001f
, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
16041 {{ 0, 0, 320, 240}, 0.001f
, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
16042 /* Don't run this right after the other 640x480 test, it breaks r500. */
16043 {{ 0, 0, 640, 480, 0.5f
, 0.0f
}, 0.501f
,
16044 {0, 120, 479, 359}, "Viewport (0, 0, 0.5) - (640, 480, 0.0)"},
16045 {{ 0, 0, 1280, 960}, 0.001f
, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
16046 {{ 0, 0, 2000, 1600}, 0.001f
, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
16047 {{100, 100, 640, 480}, 0.001f
, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
16048 {{ 0, 0, 8192, 8192}, 0.001f
, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
16050 static struct vec3 quad
[] =
16052 {-1.5f
, -0.5f
, 1.0f
},
16053 {-1.5f
, 0.5f
, 1.0f
},
16054 { 0.5f
, -0.5f
, 1.0f
},
16055 { 0.5f
, 0.5f
, 1.0f
},
16057 static const struct vec2 rt_sizes
[] =
16059 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
16061 IDirectDrawSurface7
*rt
, *ds
;
16062 DDSURFACEDESC2 surface_desc
;
16063 const float z_eps
= 0.0001;
16064 IDirect3DDevice7
*device
;
16065 IDirectDraw7
*ddraw
;
16066 DDPIXELFORMAT z_fmt
;
16073 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16074 0, 0, 640, 480, 0, 0, 0, 0);
16075 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16077 skip("Failed to create a 3D device, skipping test.\n");
16078 DestroyWindow(window
);
16082 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
16083 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16084 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
16085 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16086 IDirect3D7_Release(d3d
);
16088 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16089 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16091 /* Well, by default the vertices without color info should be white, and without any texture
16092 * ops this should just show up in the output, but the r200 driver begs to differ and draws a
16094 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
16095 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16096 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
16097 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16098 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00ffffff);
16099 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16101 hr
= IDirect3DDevice7_SetViewport(device
, NULL
);
16102 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
16104 ds
= get_depth_stencil(device
);
16105 memset(&surface_desc
, 0, sizeof(surface_desc
));
16106 surface_desc
.dwSize
= sizeof(surface_desc
);
16107 hr
= IDirectDrawSurface7_GetSurfaceDesc(ds
, &surface_desc
);
16108 z_fmt
= U4(surface_desc
).ddpfPixelFormat
;
16110 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
16114 memset(&surface_desc
, 0, sizeof(surface_desc
));
16115 surface_desc
.dwSize
= sizeof(surface_desc
);
16116 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
16117 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
16118 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
16119 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
16120 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
16121 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16123 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
16124 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16125 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
16126 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
16127 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16128 hr
= IDirectDrawSurface7_AddAttachedSurface(rt
, ds
);
16129 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16131 hr
= IDirect3DDevice7_SetRenderTarget(device
, rt
, 0);
16132 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16136 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
16137 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16140 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
16142 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000,
16143 tests
[j
].expected_z
- z_eps
, 0);
16144 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16145 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_GREATER
);
16146 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16148 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, !i
);
16149 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16151 hr
= IDirect3DDevice7_SetViewport(device
, &tests
[j
].vp
);
16152 if (tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
16153 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
)
16155 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16160 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16163 hr
= IDirect3DDevice7_BeginScene(device
);
16164 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16165 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
16166 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16167 hr
= IDirect3DDevice7_EndScene(device
);
16168 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16170 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
16174 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff000000,
16175 tests
[j
].expected_z
+ z_eps
, 0);
16176 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16177 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESS
);
16178 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16180 hr
= IDirect3DDevice7_BeginScene(device
);
16181 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16182 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
16183 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16184 hr
= IDirect3DDevice7_EndScene(device
);
16185 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
16187 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
16191 hr
= IDirectDrawSurface7_DeleteAttachedSurface(rt
, 0, ds
);
16192 ok(hr
== DD_OK
, "Got unexpected hr %#x (i %u).\n", hr
, i
);
16193 IDirectDrawSurface7_Release(ds
);
16194 IDirectDrawSurface7_Release(rt
);
16197 refcount
= IDirect3DDevice7_Release(device
);
16198 ok(!refcount
, "Device has %u references left.\n", refcount
);
16199 IDirectDraw7_Release(ddraw
);
16200 DestroyWindow(window
);
16203 static unsigned int validate_loaded_surface(IDirectDrawSurface7
*surface
, unsigned int face
,
16204 unsigned int level
, const RECT
*src_rect
, const POINT
*dst_point
)
16206 DDSURFACEDESC2 surface_desc
;
16207 unsigned int diff
, x
, y
;
16210 memset(&surface_desc
, 0, sizeof(surface_desc
));
16211 surface_desc
.dwSize
= sizeof(surface_desc
);
16212 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
16213 ok(SUCCEEDED(hr
), "Failed to map surface, hr %#x.\n", hr
);
16215 for (y
= 0, diff
= 0; y
< surface_desc
.dwHeight
; ++y
)
16217 DWORD
*texture_row
= (DWORD
*)((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
16219 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
16221 DWORD colour
= texture_row
[x
];
16222 DWORD r
= (colour
& 0xff0000) >> 16;
16223 DWORD g
= (colour
& 0xff00) >> 8;
16224 DWORD b
= (colour
& 0xff);
16226 if (x
< dst_point
->x
|| x
>= dst_point
->x
+ src_rect
->right
- src_rect
->left
16227 || y
< dst_point
->y
|| y
>= dst_point
->y
+ src_rect
->bottom
- src_rect
->top
)
16229 if (colour
& 0xffffff)
16234 if (r
!= ((face
<< 4) | level
)
16235 || g
!= x
+ src_rect
->left
- dst_point
->x
16236 || b
!= y
+ src_rect
->top
- dst_point
->y
)
16242 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
16243 ok(SUCCEEDED(hr
), "Failed to unmap surface, hr %#x.\n", hr
);
16248 static void test_device_load(void)
16250 IDirectDrawSurface7
*src_surface
, *dst_surface
, *surface
, *tmp
;
16251 DDSCAPS2 mip_caps
= {0, DDSCAPS2_MIPMAPSUBLEVEL
, 0, {0}};
16252 IDirectDrawPalette
*src_palette
, *dst_palette
, *palette
;
16253 unsigned int i
, j
, k
, l
, x
, y
;
16254 DDSURFACEDESC2 surface_desc
;
16255 IDirect3DDevice7
*device
;
16256 PALETTEENTRY table1
[256];
16257 D3DDEVICEDESC7 d3d_caps
;
16258 DDCOLORKEY colour_key
;
16259 IDirectDraw7
*ddraw
;
16267 #define TEX_MIP 0x01
16268 #define TEX_CUBE 0x02
16269 #define NULL_COORDS 0x04
16271 /* Creating partial cube maps (e.g. created with just
16272 * DDSCAPS2_CUBEMAP_POSITIVEX) BSODs some Windows machines. (Radeon X1600,
16273 * Windows XP, Catalyst 10.2 driver, 6.14.10.6925)
16275 * Passing non-toplevel surfaces to IDirect3DDevice7_Load() crashes on
16276 * native. (Windows XP / NVIDIA, Windows 98 / RGB software rasteriser) */
16277 static const struct
16279 unsigned int src_w
, src_h
, src_mip_count
;
16282 unsigned int dst_w
, dst_h
, dst_mip_count
;
16289 {128, 128, 0, { 0, 0, 0, 0}, TEX_MIP
, 128, 128, 0, { 0, 0}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16290 {128, 128, 0, { 0, 0, 100, 100}, TEX_MIP
, 128, 128, 0, {50, 50}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16291 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 0, {31, 31}, TEX_MIP
, D3D_OK
},
16292 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, NULL_COORDS
, D3D_OK
},
16293 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 256, 128, 0, { 0, 0}, NULL_COORDS
, DDERR_INVALIDPARAMS
},
16294 {256, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, NULL_COORDS
, DDERR_INVALIDPARAMS
},
16295 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
| TEX_CUBE
, 128, 128, 0, {10, 10}, TEX_MIP
| TEX_CUBE
, D3D_OK
},
16296 {128, 128, 0, { 0, 0, 0, 0}, NULL_COORDS
, 128, 128, 0, { 0, 0}, TEX_CUBE
| NULL_COORDS
, DDERR_INVALIDPARAMS
},
16297 {128, 128, 0, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 4, {31, 31}, TEX_MIP
, D3D_OK
},
16298 {128, 128, 4, {30, 20, 93, 52}, TEX_MIP
, 128, 128, 0, {31, 31}, TEX_MIP
, DDERR_INVALIDPARAMS
},
16299 {128, 128, 0, {32, 32, 96, 96}, TEX_MIP
, 32, 32, 0, {32, 32}, 0, D3D_OK
},
16300 {128, 128, 0, { 0, 0, 64, 64}, TEX_MIP
, 32, 32, 4, { 0, 0}, TEX_MIP
, D3D_OK
},
16303 window
= create_window();
16304 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16306 skip("Failed to create a 3D device, skipping test.\n");
16307 DestroyWindow(window
);
16311 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
16312 ok(SUCCEEDED(hr
), "Failed to get Direct3D7 interface, hr %#x.\n", hr
);
16313 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
16314 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
16315 IDirect3D7_Release(d3d
);
16317 memset(&d3d_caps
, 0, sizeof(d3d_caps
));
16318 hr
= IDirect3DDevice7_GetCaps(device
, &d3d_caps
);
16319 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
16320 cube_support
= d3d_caps
.dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_CUBEMAP
;
16322 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16324 unsigned int src_count
, dst_count
;
16325 POINT dst_point
, dst_point_broken
;
16326 RECT src_rect
, src_rect_broken
;
16328 if ((tests
[i
].src_flags
| tests
[i
].dst_flags
) & TEX_CUBE
&& !cube_support
)
16330 skip("No cubemap support, skipping test %u.\n", i
);
16334 memset(&surface_desc
, 0, sizeof(surface_desc
));
16335 surface_desc
.dwSize
= sizeof(surface_desc
);
16336 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16337 if (tests
[i
].src_mip_count
)
16338 surface_desc
.dwFlags
|= DDSD_MIPMAPCOUNT
;
16339 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16340 if (tests
[i
].src_flags
& (TEX_MIP
| TEX_CUBE
))
16341 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
16342 if (tests
[i
].src_flags
& TEX_MIP
)
16343 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_MIPMAP
;
16344 if (tests
[i
].src_flags
& TEX_CUBE
)
16345 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
16346 surface_desc
.dwWidth
= tests
[i
].src_w
;
16347 surface_desc
.dwHeight
= tests
[i
].src_h
;
16348 U2(surface_desc
).dwMipMapCount
= tests
[i
].src_mip_count
;
16349 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16350 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
16351 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
16352 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
16353 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
16354 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
16355 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
16356 ok(SUCCEEDED(hr
), "Test %u: Failed to create source surface, hr %#x.\n", i
, hr
);
16358 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16359 if (tests
[i
].dst_mip_count
)
16360 surface_desc
.dwFlags
|= DDSD_MIPMAPCOUNT
;
16361 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16362 if (tests
[i
].dst_flags
& (TEX_MIP
| TEX_CUBE
))
16363 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
16364 if (tests
[i
].dst_flags
& TEX_MIP
)
16365 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_MIPMAP
;
16366 surface_desc
.ddsCaps
.dwCaps2
= 0;
16367 if (tests
[i
].dst_flags
& TEX_CUBE
)
16368 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| DDSCAPS2_CUBEMAP_ALLFACES
;
16369 surface_desc
.dwWidth
= tests
[i
].dst_w
;
16370 surface_desc
.dwHeight
= tests
[i
].dst_h
;
16371 U2(surface_desc
).dwMipMapCount
= tests
[i
].dst_mip_count
;
16372 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
16373 ok(SUCCEEDED(hr
), "Test %u: Failed to create destination surface, hr %#x.\n", i
, hr
);
16375 src_count
= dst_count
= 1;
16376 if (tests
[i
].src_flags
& TEX_MIP
)
16377 src_count
= tests
[i
].src_mip_count
? tests
[i
].src_mip_count
: 8;
16378 if (tests
[i
].dst_flags
& TEX_MIP
)
16379 dst_count
= tests
[i
].dst_mip_count
? tests
[i
].dst_mip_count
: 8;
16381 surface
= src_surface
;
16382 IDirectDrawSurface7_AddRef(surface
);
16385 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16387 /* Check the number of created mipmaps. */
16388 if (tests
[i
].src_flags
& TEX_MIP
)
16390 memset(&surface_desc
, 0, sizeof(surface_desc
));
16391 surface_desc
.dwSize
= sizeof(surface_desc
);
16392 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
16393 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface description, hr %#x.\n", i
, hr
);
16394 ok(U2(surface_desc
).dwMipMapCount
== src_count
,
16395 "Test %u: Got unexpected mip count %u, expected %u.\n",
16396 i
, U2(surface_desc
).dwMipMapCount
, src_count
);
16401 memset(&surface_desc
, 0, sizeof(surface_desc
));
16402 surface_desc
.dwSize
= sizeof(surface_desc
);
16403 hr
= IDirectDrawSurface7_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
16404 ok(SUCCEEDED(hr
), "Test %u: Failed to map surface, hr %#x.\n", i
, hr
);
16406 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
16408 DWORD
*texture_row
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
16410 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
16412 /* The face number is stored in the high 4 bits of the
16413 * red component, the mip-level in the low 4 bits. The
16414 * x-coordinate is stored in the green component, and
16415 * the y-coordinate in the blue component. */
16416 texture_row
[x
] = (j
<< 20) | (k
<< 16) | (x
<< 8) | y
;
16420 hr
= IDirectDrawSurface7_Unlock(surface
, NULL
);
16421 ok(SUCCEEDED(hr
), "Test %u: Failed to unmap surface, hr %#x.\n", i
, hr
);
16423 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16424 IDirectDrawSurface7_Release(surface
);
16430 if (!(tests
[i
].src_flags
& TEX_CUBE
) || ++j
>= 6)
16433 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16434 hr
= IDirectDrawSurface7_GetAttachedSurface(src_surface
, &face_caps
, &surface
);
16435 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16438 surface
= dst_surface
;
16439 IDirectDrawSurface7_AddRef(surface
);
16442 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16444 /* Check the number of created mipmaps. */
16445 if (tests
[i
].dst_flags
& TEX_MIP
)
16447 memset(&surface_desc
, 0, sizeof(surface_desc
));
16448 surface_desc
.dwSize
= sizeof(surface_desc
);
16449 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
16450 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface description, hr %#x.\n", i
, hr
);
16451 ok(U2(surface_desc
).dwMipMapCount
== dst_count
,
16452 "Test %u: Got unexpected mip count %u, expected %u.\n",
16453 i
, U2(surface_desc
).dwMipMapCount
, dst_count
);
16458 memset(&fx
, 0, sizeof(fx
));
16459 fx
.dwSize
= sizeof(fx
);
16460 U5(fx
).dwFillColor
= 0x00000000;
16461 hr
= IDirectDrawSurface7_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
16462 ok(SUCCEEDED(hr
), "Test %u: Failed to clear surface, hr %#x.\n", i
, hr
);
16464 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16465 IDirectDrawSurface7_Release(surface
);
16471 if (!(tests
[i
].dst_flags
& TEX_CUBE
) || ++j
>= 6)
16474 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16475 hr
= IDirectDrawSurface7_GetAttachedSurface(dst_surface
, &face_caps
, &surface
);
16476 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16479 src_rect
= tests
[i
].src_rect
;
16480 dst_point
= tests
[i
].dst_point
;
16481 hr
= IDirect3DDevice7_Load(device
,
16482 dst_surface
, tests
[i
].dst_flags
& NULL_COORDS
? NULL
: &dst_point
,
16483 src_surface
, tests
[i
].src_flags
& NULL_COORDS
? NULL
: &src_rect
,
16484 tests
[i
].dst_flags
& TEX_CUBE
? DDSCAPS2_CUBEMAP_ALLFACES
: 0);
16485 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
16489 unsigned int level_offset
, level_offset_broken
;
16491 for (level_offset
= 0, k
= tests
[i
].src_w
; k
> tests
[i
].dst_w
; ++level_offset
, k
/= 2);
16492 level_offset_broken
= src_count
- dst_count
;
16494 surface
= dst_surface
;
16495 IDirectDrawSurface7_AddRef(surface
);
16498 DDSCAPS2 face_caps
= {0, 0, 0, {0}};
16500 if (tests
[i
].src_flags
& NULL_COORDS
)
16501 SetRect(&src_rect
, 0, 0, tests
[i
].src_w
, tests
[i
].src_h
);
16503 src_rect
= tests
[i
].src_rect
;
16505 if (tests
[i
].dst_flags
& NULL_COORDS
)
16506 dst_point
.x
= dst_point
.y
= 0;
16508 dst_point
= tests
[i
].dst_point
;
16510 for (k
= 0; k
< level_offset
; ++k
)
16515 src_rect
.left
/= 2;
16516 src_rect
.right
= (src_rect
.right
+ 1) / 2;
16517 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
16522 unsigned int diff
, diff2
, diff3
;
16524 diff
= validate_loaded_surface(surface
, j
, k
+ level_offset
, &src_rect
, &dst_point
);
16526 /* On some newer (XP+) versions of Windows, it appears the
16527 * source/destination coordinates are divided too often.
16528 * This works correctly on Windows 98 with the RGB
16529 * software rasteriser. */
16530 src_rect_broken
= src_rect
;
16531 dst_point_broken
= dst_point
;
16532 for (l
= 0; l
< level_offset
; ++l
)
16534 dst_point_broken
.x
/= 2;
16535 dst_point_broken
.y
/= 2;
16536 src_rect_broken
.top
/= 2;
16537 src_rect_broken
.left
/= 2;
16538 src_rect_broken
.right
= (src_rect_broken
.right
+ 1) / 2;
16539 src_rect_broken
.bottom
= (src_rect_broken
.bottom
+ 1) / 2;
16541 diff2
= validate_loaded_surface(surface
, j
, k
+ level_offset
,
16542 &src_rect_broken
, &dst_point_broken
);
16544 /* On Windows 8+ things are slightly worse still. Instead
16545 * of applying the correct level offset twice, like on
16546 * XP+, an incorrect offset is applied in addition to the
16547 * correct one. Additionally, on Windows 8+, this offset
16548 * also affects the selected source mip-level, as opposed
16549 * to Windows XP+ where it only affects the
16550 * source/destination coordinates. */
16551 src_rect_broken
= src_rect
;
16552 dst_point_broken
= dst_point
;
16553 for (l
= 0; l
< level_offset_broken
; ++l
)
16555 dst_point_broken
.x
/= 2;
16556 dst_point_broken
.y
/= 2;
16557 src_rect_broken
.top
/= 2;
16558 src_rect_broken
.left
/= 2;
16559 src_rect_broken
.right
= (src_rect_broken
.right
+ 1) / 2;
16560 src_rect_broken
.bottom
= (src_rect_broken
.bottom
+ 1) / 2;
16562 diff3
= validate_loaded_surface(surface
, j
, k
+ level_offset_broken
,
16563 &src_rect_broken
, &dst_point_broken
);
16565 ok(!diff
|| broken(!diff2
|| !diff3
), "Test %u, face %u, level %u: "
16566 "Unexpected destination texture level pixels; %u/%u/%u differences.\n",
16567 i
, j
, k
, diff
, diff2
, diff3
);
16569 hr
= IDirectDrawSurface7_GetAttachedSurface(surface
, &mip_caps
, &tmp
);
16570 IDirectDrawSurface7_Release(surface
);
16578 src_rect
.left
/= 2;
16579 src_rect
.right
= (src_rect
.right
+ 1) / 2;
16580 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
16583 if (!(tests
[i
].dst_flags
& TEX_CUBE
) || ++j
>= 6)
16586 face_caps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (DDSCAPS2_CUBEMAP_POSITIVEX
<< j
);
16587 hr
= IDirectDrawSurface7_GetAttachedSurface(dst_surface
, &face_caps
, &surface
);
16588 ok(SUCCEEDED(hr
), "Test %u: Failed to get face %u.\n", i
, j
);
16592 IDirectDrawSurface7_Release(dst_surface
);
16593 IDirectDrawSurface7_Release(src_surface
);
16599 memset(&surface_desc
, 0, sizeof(surface_desc
));
16600 surface_desc
.dwSize
= sizeof(surface_desc
);
16601 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16602 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
16603 surface_desc
.dwWidth
= 128;
16604 surface_desc
.dwHeight
= 128;
16605 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16606 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED8
;
16607 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
16608 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
16609 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
16610 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
16611 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
16612 hr
= IDirectDrawSurface7_GetAttachedSurface(src_surface
, &mip_caps
, &surface
);
16613 ok(SUCCEEDED(hr
), "Failed to get surface, hr %#x.\n", hr
);
16615 /* Test palette copying. */
16616 memset(table1
, 0, sizeof(table1
));
16617 table1
[0].peBlue
= 1;
16618 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table1
, &src_palette
, NULL
);
16619 ok(SUCCEEDED(hr
), "Failed to create source palette, hr %#x.\n", hr
);
16620 table1
[0].peBlue
= 3;
16621 hr
= IDirectDraw7_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, table1
, &dst_palette
, NULL
);
16622 ok(SUCCEEDED(hr
), "Failed to create destination palette, hr %#x.\n", hr
);
16624 hr
= IDirectDrawSurface7_SetPalette(src_surface
, src_palette
);
16625 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
16627 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16628 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16630 hr
= IDirectDrawSurface7_GetPalette(surface
, &palette
);
16631 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
16632 hr
= IDirectDrawSurface7_GetPalette(dst_surface
, &palette
);
16633 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
16635 hr
= IDirectDrawSurface7_SetPalette(surface
, src_palette
);
16636 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
16637 hr
= IDirectDrawSurface7_SetPalette(dst_surface
, dst_palette
);
16638 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
16640 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16641 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16643 hr
= IDirectDrawSurface7_GetPalette(dst_surface
, &palette
);
16644 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
16645 ok(palette
== dst_palette
, "Got unexpected palette %p, expected %p.\n", palette
, dst_palette
);
16646 memset(table1
, 0, sizeof(table1
));
16647 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 0, 256, table1
);
16648 ok(SUCCEEDED(hr
), "Failed to retrieve palette entries, hr %#x.\n", hr
);
16649 ok(table1
[0].peBlue
== 1, "Got unexpected palette colour %#x.\n", (unsigned int)table1
[0].peBlue
);
16650 IDirectDrawPalette_Release(palette
);
16652 IDirectDrawPalette_Release(dst_palette
);
16653 IDirectDrawPalette_Release(src_palette
);
16655 /* Test colour-key copying. */
16656 colour_key
.dwColorSpaceLowValue
= 32;
16657 colour_key
.dwColorSpaceHighValue
= 64;
16658 hr
= IDirectDrawSurface7_SetColorKey(src_surface
, DDCKEY_SRCBLT
, &colour_key
);
16659 ok(SUCCEEDED(hr
), "Failed to set colour-key, hr %#x.\n", hr
);
16660 hr
= IDirectDrawSurface7_SetColorKey(surface
, DDCKEY_SRCBLT
, &colour_key
);
16661 ok(hr
== DDERR_NOTONMIPMAPSUBLEVEL
, "Got unexpected hr %#x.\n", hr
);
16663 hr
= IDirectDrawSurface7_GetColorKey(dst_surface
, DDCKEY_SRCBLT
, &colour_key
);
16664 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
16666 hr
= IDirect3DDevice7_Load(device
, dst_surface
, NULL
, src_surface
, NULL
, 0);
16667 ok(SUCCEEDED(hr
), "Failed to load texture, hr %#x.\n", hr
);
16669 hr
= IDirectDrawSurface7_GetColorKey(dst_surface
, DDCKEY_SRCBLT
, &colour_key
);
16670 ok(SUCCEEDED(hr
), "Failed to get colour-key, hr %#x.\n", hr
);
16671 ok(colour_key
.dwColorSpaceLowValue
== 32, "Got unexpected value %u.\n", colour_key
.dwColorSpaceLowValue
);
16672 ok(colour_key
.dwColorSpaceHighValue
== 32, "Got unexpected value %u.\n", colour_key
.dwColorSpaceHighValue
);
16674 IDirectDrawSurface7_Release(surface
);
16675 IDirectDrawSurface7_Release(dst_surface
);
16676 IDirectDrawSurface7_Release(src_surface
);
16678 IDirectDraw7_Release(ddraw
);
16679 refcount
= IDirect3DDevice7_Release(device
);
16680 ok(!refcount
, "Device has %u references left.\n", refcount
);
16681 DestroyWindow(window
);
16684 static void test_color_vertex(void)
16686 IDirect3DDevice7
*device
;
16687 IDirectDrawSurface7
*rt
;
16688 D3DMATERIAL7 material
;
16697 struct vec3 position
;
16703 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16704 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16705 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16706 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff00ff00},
16710 struct vec3 position
;
16715 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16716 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
16717 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16718 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
16722 struct vec3 position
;
16726 {{-1.0f
, -1.0f
, 0.0f
}},
16727 {{-1.0f
, 1.0f
, 0.0f
}},
16728 {{ 1.0f
, -1.0f
, 0.0f
}},
16729 {{ 1.0f
, 1.0f
, 0.0f
}},
16732 /* The idea here is to set up ambient light parameters in a way that the
16733 * ambient colour from the material is just passed through. The emissive
16734 * colour is just passed through anyway. The sum of ambient + emissive
16735 * should allow deduction of where the material colour came from. */
16736 static const struct
16738 DWORD fvf
, color_vertex
, ambient
, emissive
, result
;
16743 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, FALSE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0, quad_2c
},
16745 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ffff00, quad_2c
},
16746 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x0000ff80, quad_2c
},
16747 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040, quad_2c
},
16748 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR1
, 0x00ff0000, quad_2c
},
16749 {D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR2
, D3DMCS_COLOR2
, 0x0000ff00, quad_2c
},
16751 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0080, quad_1c
},
16752 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x000000c0, quad_1c
},
16753 {D3DFVF_SPECULAR
, TRUE
, D3DMCS_MATERIAL
, D3DMCS_COLOR2
, 0x00ff0080, quad_1c
},
16754 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x00ff0040, quad_1c
},
16755 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR1
, D3DMCS_MATERIAL
, 0x00ff0040, quad_1c
},
16756 {D3DFVF_DIFFUSE
, TRUE
, D3DMCS_COLOR2
, D3DMCS_MATERIAL
, 0x000000c0, quad_1c
},
16758 {0, TRUE
, D3DMCS_COLOR1
, D3DMCS_COLOR2
, 0x000000c0, quad_0c
},
16761 window
= CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16762 0, 0, 640, 480, 0, 0, 0, 0);
16763 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16765 skip("Failed to create a 3D device, skipping test.\n");
16766 DestroyWindow(window
);
16769 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
16770 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
16772 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
16773 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16774 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_AMBIENT
, 0xffffffff);
16775 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16777 memset(&material
, 0, sizeof(material
));
16778 U3(U1(material
).ambient
).b
= 0.5f
;
16779 U3(U3(material
).emissive
).b
= 0.25f
;
16780 hr
= IDirect3DDevice7_SetMaterial(device
, &material
);
16781 ok(SUCCEEDED(hr
), "Failed to set material, hr %#x\n", hr
);
16783 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16785 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_COLORVERTEX
, tests
[i
].color_vertex
);
16786 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16787 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_AMBIENTMATERIALSOURCE
, tests
[i
].ambient
);
16788 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16789 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE
, tests
[i
].emissive
);
16790 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16791 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
16792 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
16794 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
16795 ok(SUCCEEDED(hr
), "Failed to clear depth/stencil, hr %#x.\n", hr
);
16797 hr
= IDirect3DDevice7_BeginScene(device
);
16798 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
16799 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
16800 D3DFVF_XYZ
| tests
[i
].fvf
, tests
[i
].vtx
, 4, 0);
16801 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
16802 hr
= IDirect3DDevice7_EndScene(device
);
16803 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
16805 colour
= get_surface_color(rt
, 320, 240);
16806 ok(compare_color(colour
, tests
[i
].result
, 1),
16807 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
16808 tests
[i
].result
, i
, colour
);
16811 IDirectDrawSurface7_Release(rt
);
16812 refcount
= IDirect3DDevice7_Release(device
);
16813 ok(!refcount
, "Device has %u references left.\n", refcount
);
16814 DestroyWindow(window
);
16817 static IDirectDraw7
*killfocus_ddraw
;
16818 static IDirectDrawSurface7
*killfocus_surface
;
16820 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
16824 if (message
== WM_KILLFOCUS
)
16826 ref
= IDirectDrawSurface7_Release(killfocus_surface
);
16827 ok(!ref
, "Unexpected surface refcount %u.\n", ref
);
16828 ref
= IDirectDraw7_Release(killfocus_ddraw
);
16829 ok(!ref
, "Unexpected ddraw refcount %u.\n", ref
);
16830 killfocus_ddraw
= NULL
;
16833 return DefWindowProcA(window
, message
, wparam
, lparam
);
16836 static void test_killfocus(void)
16838 DDSURFACEDESC2 surface_desc
;
16841 WNDCLASSA wc
= {0};
16843 wc
.lpfnWndProc
= killfocus_proc
;
16844 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
16845 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
16847 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
16848 0, 0, 640, 480, 0, 0, 0, 0);
16850 killfocus_ddraw
= create_ddraw();
16851 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
16853 hr
= IDirectDraw7_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
16854 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
16856 memset(&surface_desc
, 0, sizeof(surface_desc
));
16857 surface_desc
.dwSize
= sizeof(surface_desc
);
16858 surface_desc
.dwFlags
= DDSD_CAPS
;
16859 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
16860 hr
= IDirectDraw7_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
16861 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
16863 SetForegroundWindow(GetDesktopWindow());
16864 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
16866 DestroyWindow(window
);
16867 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
16870 static void test_sysmem_draw(void)
16872 IDirectDrawSurface7
*rt
, *texture
;
16873 DDSURFACEDESC2 surface_desc
;
16874 D3DVERTEXBUFFERDESC vb_desc
;
16875 IDirect3DVertexBuffer7
*vb
;
16876 IDirect3DDevice7
*device
;
16877 IDirectDraw7
*ddraw
;
16885 static const struct
16887 struct vec3 position
;
16892 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16893 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
16894 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
16895 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
16897 static WORD indices
[] = {0, 1, 2, 3};
16899 window
= create_window();
16900 ok(!!window
, "Failed to create a window.\n");
16902 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16904 skip("Failed to create a 3D device, skipping test.\n");
16905 DestroyWindow(window
);
16909 hr
= IDirect3DDevice7_GetDirect3D(device
, &d3d
);
16910 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16911 hr
= IDirect3D7_QueryInterface(d3d
, &IID_IDirectDraw7
, (void **)&ddraw
);
16912 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16913 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
16914 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16916 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16917 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16919 vb_desc
.dwSize
= sizeof(vb_desc
);
16920 vb_desc
.dwCaps
= D3DVBCAPS_SYSTEMMEMORY
;
16921 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
16922 vb_desc
.dwNumVertices
= 4;
16923 hr
= IDirect3D7_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0);
16924 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16926 hr
= IDirect3DVertexBuffer7_Lock(vb
, 0, (void **)&data
, NULL
);
16927 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16928 memcpy(data
, quad
, sizeof(quad
));
16929 hr
= IDirect3DVertexBuffer7_Unlock(vb
);
16930 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16932 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
16933 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16935 hr
= IDirect3DDevice7_BeginScene(device
);
16936 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16937 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
16938 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16939 hr
= IDirect3DDevice7_EndScene(device
);
16940 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16942 colour
= get_surface_color(rt
, 320, 240);
16943 ok(compare_color(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
16945 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
16946 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16948 hr
= IDirect3DDevice7_BeginScene(device
);
16949 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16950 hr
= IDirect3DDevice7_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, indices
, 4, 0);
16951 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16952 hr
= IDirect3DDevice7_EndScene(device
);
16953 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16955 colour
= get_surface_color(rt
, 320, 240);
16956 ok(compare_color(colour
, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour
);
16958 memset(&surface_desc
, 0, sizeof(surface_desc
));
16959 surface_desc
.dwSize
= sizeof(surface_desc
);
16960 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
16961 surface_desc
.dwHeight
= 2;
16962 surface_desc
.dwWidth
= 2;
16963 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
16964 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16965 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
16966 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
16967 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
16968 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
16969 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
16970 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
16971 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
16972 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16973 hr
= IDirect3DDevice7_SetTexture(device
, 0, texture
);
16974 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16976 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x77777777, 0.0f
, 0);
16977 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16979 hr
= IDirect3DDevice7_BeginScene(device
);
16980 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16981 hr
= IDirect3DDevice7_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
16982 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16983 hr
= IDirect3DDevice7_EndScene(device
);
16984 ok(hr
== D3D_OK
|| hr
== D3DERR_SCENE_END_FAILED
, "Got unexpected hr %#x.\n", hr
);
16986 IDirectDrawSurface7_Release(texture
);
16987 IDirect3DVertexBuffer7_Release(vb
);
16988 IDirectDrawSurface7_Release(rt
);
16989 IDirectDraw7_Release(ddraw
);
16990 IDirect3D7_Release(d3d
);
16991 refcount
= IDirect3DDevice7_Release(device
);
16992 ok(!refcount
, "Device has %u references left.\n", refcount
);
16993 DestroyWindow(window
);
16996 static void test_gdi_surface(void)
16998 IDirectDrawSurface7
*primary
, *backbuffer
, *gdi_surface
;
16999 DDSCAPS2 caps
= {DDSCAPS_BACKBUFFER
, 0, 0, {0}};
17000 DDSURFACEDESC2 surface_desc
;
17001 IDirectDraw7
*ddraw
;
17006 window
= create_window();
17007 ddraw
= create_ddraw();
17008 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17009 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17010 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17012 /* Retrieving the GDI surface requires a primary surface to exist. */
17013 gdi_surface
= (void *)0xc0dec0de;
17014 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17015 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
17016 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
17018 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17019 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
17021 memset(&surface_desc
, 0, sizeof(surface_desc
));
17022 surface_desc
.dwSize
= sizeof(surface_desc
);
17023 surface_desc
.dwFlags
= DDSD_CAPS
;
17024 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17025 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17026 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17028 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17029 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17030 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17031 IDirectDrawSurface7_Release(gdi_surface
);
17033 /* Flipping to the GDI surface requires the primary surface to be
17035 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17036 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
17038 IDirectDrawSurface7_Release(primary
);
17040 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
17041 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17043 memset(&surface_desc
, 0, sizeof(surface_desc
));
17044 surface_desc
.dwSize
= sizeof(surface_desc
);
17045 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
17046 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
17047 U5(surface_desc
).dwBackBufferCount
= 1;
17048 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17049 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17050 hr
= IDirectDrawSurface7_GetAttachedSurface(primary
, &caps
, &backbuffer
);
17051 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17052 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
17054 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17055 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17056 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17057 IDirectDrawSurface7_Release(gdi_surface
);
17059 hr
= IDirectDrawSurface7_Flip(primary
, NULL
, DDFLIP_WAIT
);
17060 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17061 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17062 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17063 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
17064 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
17065 IDirectDrawSurface7_Release(gdi_surface
);
17067 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17068 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17070 hr
= IDirectDraw7_GetGDISurface(ddraw
, &gdi_surface
);
17071 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17072 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17073 IDirectDrawSurface7_Release(gdi_surface
);
17075 hr
= IDirectDraw7_FlipToGDISurface(ddraw
);
17076 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17078 IDirectDrawSurface7_Release(backbuffer
);
17079 IDirectDrawSurface7_Release(primary
);
17081 refcount
= IDirectDraw7_Release(ddraw
);
17082 ok(!refcount
, "%u references left.\n", refcount
);
17083 DestroyWindow(window
);
17086 static void test_multiply_transform(void)
17088 IDirect3DDevice7
*device
;
17096 static const D3DTRANSFORMSTATETYPE tests
[] =
17098 D3DTRANSFORMSTATE_WORLD
,
17099 D3DTRANSFORMSTATE_VIEW
,
17100 D3DTRANSFORMSTATE_PROJECTION
,
17101 D3DTRANSFORMSTATE_WORLD1
,
17102 D3DTRANSFORMSTATE_WORLD2
,
17103 D3DTRANSFORMSTATE_WORLD3
,
17104 D3DTRANSFORMSTATE_TEXTURE0
,
17105 D3DTRANSFORMSTATE_TEXTURE1
,
17106 D3DTRANSFORMSTATE_TEXTURE2
,
17107 D3DTRANSFORMSTATE_TEXTURE3
,
17108 D3DTRANSFORMSTATE_TEXTURE4
,
17109 D3DTRANSFORMSTATE_TEXTURE5
,
17110 D3DTRANSFORMSTATE_TEXTURE6
,
17111 D3DTRANSFORMSTATE_TEXTURE7
,
17116 1.0f
, 0.0f
, 0.0f
, 0.0f
,
17117 0.0f
, 1.0f
, 0.0f
, 0.0f
,
17118 0.0f
, 0.0f
, 1.0f
, 0.0f
,
17119 0.0f
, 0.0f
, 0.0f
, 1.0f
,
17123 2.0f
, 0.0f
, 0.0f
, 0.0f
,
17124 0.0f
, 2.0f
, 0.0f
, 0.0f
,
17125 0.0f
, 0.0f
, 2.0f
, 0.0f
,
17126 0.0f
, 0.0f
, 0.0f
, 2.0f
,
17129 window
= create_window();
17130 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17132 skip("Failed to create 3D device.\n");
17133 DestroyWindow(window
);
17137 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
17139 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17140 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17141 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
17143 hr
= IDirect3DDevice7_MultiplyTransform(device
, tests
[i
], &mat2
);
17144 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17146 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17147 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17148 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
17150 /* MultiplyTransform() goes directly into the primary stateblock. */
17152 hr
= IDirect3DDevice7_SetTransform(device
, tests
[i
], &mat1
);
17153 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17155 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17156 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17158 hr
= IDirect3DDevice7_MultiplyTransform(device
, tests
[i
], &mat2
);
17159 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17161 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock
);
17162 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17164 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17165 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17166 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
17168 hr
= IDirect3DDevice7_CaptureStateBlock(device
, stateblock
);
17169 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17171 hr
= IDirect3DDevice7_SetTransform(device
, tests
[i
], &mat1
);
17172 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17174 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock
);
17175 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17177 hr
= IDirect3DDevice7_GetTransform(device
, tests
[i
], &ret_mat
);
17178 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
17179 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
17181 IDirect3DDevice7_DeleteStateBlock(device
, stateblock
);
17184 refcount
= IDirect3DDevice7_Release(device
);
17185 ok(!refcount
, "Device has %u references left.\n", refcount
);
17186 DestroyWindow(window
);
17189 static void test_alphatest(void)
17191 #define ALPHATEST_PASSED 0x0000ff00
17192 #define ALPHATEST_FAILED 0x00ff0000
17193 IDirect3DDevice7
*device
;
17194 IDirectDrawSurface7
*rt
;
17202 static const struct
17205 D3DCOLOR color_less
;
17206 D3DCOLOR color_equal
;
17207 D3DCOLOR color_greater
;
17211 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17212 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17213 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17214 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17215 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17216 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17217 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17218 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17222 struct vec3 position
;
17227 {{-1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17228 {{-1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17229 {{ 1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17230 {{ 1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17233 window
= create_window();
17234 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17236 skip("Failed to create a 3D device.\n");
17237 DestroyWindow(window
);
17240 hr
= IDirect3DDevice7_GetRenderTarget(device
, &rt
);
17241 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17243 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
17244 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17245 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17246 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17247 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
17248 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17249 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
17250 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17252 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
17254 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
17255 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17257 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17258 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17259 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
17260 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17261 hr
= IDirect3DDevice7_BeginScene(device
);
17262 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17263 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17264 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17265 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17266 hr
= IDirect3DDevice7_EndScene(device
);
17267 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17268 color
= get_surface_color(rt
, 320, 240);
17269 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17270 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17271 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17273 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17274 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17275 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
17276 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17277 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
17278 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17279 ok(value
== 0xff70, "Got unexpected value %#x.\n", value
);
17280 hr
= IDirect3DDevice7_BeginScene(device
);
17281 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17282 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17283 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17284 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17285 hr
= IDirect3DDevice7_EndScene(device
);
17286 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17287 color
= get_surface_color(rt
, 320, 240);
17288 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17289 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17290 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17293 IDirectDrawSurface7_Release(rt
);
17294 refcount
= IDirect3DDevice7_Release(device
);
17295 ok(!refcount
, "Device has %u references left.\n", refcount
);
17296 DestroyWindow(window
);
17299 static void test_clipper_refcount(void)
17301 IDirectDrawSurface7
*surface
;
17302 IDirectDrawClipper
*clipper
, *clipper2
;
17303 DDSURFACEDESC2 surface_desc
;
17304 IDirectDraw7
*ddraw
;
17305 IDirectDraw
*ddraw1
;
17310 const IDirectDrawClipperVtbl
*orig_vtbl
;
17312 window
= create_window();
17313 ddraw
= create_ddraw();
17314 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17315 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17316 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17318 memset(&surface_desc
, 0, sizeof(surface_desc
));
17319 surface_desc
.dwSize
= sizeof(surface_desc
);
17320 surface_desc
.dwFlags
= DDSD_CAPS
;
17321 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17322 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17323 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17325 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17326 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17327 refcount
= get_refcount((IUnknown
*)clipper
);
17328 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17330 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
17332 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
17333 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17334 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
17335 clipper
->lpVtbl
, clipper2
->lpVtbl
);
17336 orig_vtbl
= clipper
->lpVtbl
;
17337 IDirectDrawClipper_Release(clipper2
);
17339 /* Surfaces hold a reference to clippers. No surprises there. */
17340 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17341 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17342 refcount
= get_refcount((IUnknown
*)clipper
);
17343 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17345 hr
= IDirectDrawSurface7_GetClipper(surface
, &clipper2
);
17346 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
17347 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17348 refcount
= IDirectDrawClipper_Release(clipper2
);
17349 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17351 hr
= IDirectDrawSurface7_SetClipper(surface
, NULL
);
17352 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17353 refcount
= get_refcount((IUnknown
*)clipper
);
17354 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17356 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17357 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17358 refcount
= get_refcount((IUnknown
*)clipper
);
17359 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17361 refcount
= IDirectDrawSurface7_Release(surface
);
17362 ok(!refcount
, "%u references left.\n", refcount
);
17363 refcount
= get_refcount((IUnknown
*)clipper
);
17364 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17366 /* SetClipper with an invalid pointer crashes. */
17368 /* Clipper methods work with a broken vtable, with the exception of Release. */
17369 clipper
->lpVtbl
= (void *)0xdeadbeef;
17370 refcount
= orig_vtbl
->AddRef(clipper
);
17371 todo_wine
ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
17372 refcount
= orig_vtbl
->Release(clipper
);
17373 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
17375 clipper
->lpVtbl
= orig_vtbl
;
17376 refcount
= orig_vtbl
->Release(clipper
);
17377 todo_wine
ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
17379 /* Fix the refcount difference because Wine did not increase the ref in the
17380 * AddRef call above. */
17383 refcount
= IDirectDrawClipper_Release(clipper
);
17384 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
17387 /* Steal the reference and see what happens - releasing the surface works fine.
17388 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
17389 * release it after the GetClipper call is likely to crash, and certain to crash
17390 * if we allocate and zero as much heap memory as we can get. */
17391 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17392 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17393 hr
= IDirectDraw7_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17394 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
17395 hr
= IDirectDrawSurface7_SetClipper(surface
, clipper
);
17396 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
17398 IDirectDrawClipper_Release(clipper
);
17399 IDirectDrawClipper_Release(clipper
);
17403 /* Disabled because it causes heap corruption (HeapValidate fails and random
17404 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
17405 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
17406 * is affected too. Some testbot machines have crashes directly in GetClipper
17407 * or proceed with a corrupted heap too.
17409 * The same Windows and driver versions run the test without heap corruption on
17410 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
17411 hr
= IDirectDrawSurface7_GetClipper(surface
, &clipper2
);
17412 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
17413 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17416 /* Show that invoking the Release method does not crash, but don't get the
17417 * vtable through the clipper pointer because it is no longer pointing to
17419 refcount
= orig_vtbl
->Release(clipper
);
17420 ok(!refcount
, "%u references left.\n", refcount
);
17422 refcount
= IDirectDrawSurface7_Release(surface
);
17423 ok(!refcount
, "%u references left.\n", refcount
);
17425 /* It looks like the protection against invalid thispointers is part of
17426 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
17427 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
17428 ok(!!clipper
, "failed to allocate memory\n");
17430 /* Assigning the vtable to our fake clipper does NOT make a difference on
17431 * native - there is a different member of the clipper implementation struct
17432 * that is used to determine if a clipper is valid. */
17433 clipper
->lpVtbl
= orig_vtbl
;
17435 refcount
= orig_vtbl
->AddRef(clipper
);
17436 todo_wine
ok(!refcount
, "Got refcount %u.\n", refcount
);
17437 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
17438 ok(!refcount
, "Got refcount %u.\n", refcount
);
17441 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
17442 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17443 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17446 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
17447 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17448 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17450 /* Nope, we can't initialize our fake clipper. */
17451 hr
= IDirectDraw7_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
17452 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#x.\n", hr
);
17454 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
17455 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
17457 IDirectDraw_Release(ddraw1
);
17459 HeapFree(GetProcessHeap(), 0, clipper
);
17461 refcount
= IDirectDraw7_Release(ddraw
);
17462 ok(!refcount
, "%u references left.\n", refcount
);
17463 DestroyWindow(window
);
17466 static void test_begin_end_state_block(void)
17468 DWORD stateblock
, stateblock2
;
17469 IDirect3DDevice7
*device
;
17475 window
= create_window();
17476 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17478 skip("Failed to create 3D device.\n");
17479 DestroyWindow(window
);
17483 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17484 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17486 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17487 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17489 stateblock
= 0xdeadbeef;
17490 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock
);
17491 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17492 ok(!!stateblock
&& stateblock
!= 0xdeadbeef, "Got unexpected stateblock %#x.\n", stateblock
);
17494 stateblock2
= 0xdeadbeef;
17495 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock2
);
17496 ok(hr
== D3DERR_NOTINBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17497 ok(stateblock2
== 0xdeadbeef, "Got unexpected stateblock %#x.\n", stateblock2
);
17499 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17500 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17501 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17503 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17504 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17506 hr
= IDirect3DDevice7_BeginStateBlock(device
);
17507 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17509 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock
);
17510 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17512 hr
= IDirect3DDevice7_CaptureStateBlock(device
, stateblock
);
17513 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17515 hr
= IDirect3DDevice7_CreateStateBlock(device
, D3DSBT_ALL
, &stateblock2
);
17516 ok(hr
== D3DERR_INBEGINSTATEBLOCK
, "Got unexpected hr %#x.\n", hr
);
17518 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17519 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17520 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17522 hr
= IDirect3DDevice7_EndStateBlock(device
, &stateblock2
);
17523 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17525 hr
= IDirect3DDevice7_ApplyStateBlock(device
, stateblock2
);
17526 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17528 hr
= IDirect3DDevice7_GetRenderState(device
, D3DRENDERSTATE_LIGHTING
, &value
);
17529 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
17530 ok(value
== TRUE
, "Got unexpected value %#x.\n", value
);
17532 refcount
= IDirect3DDevice7_Release(device
);
17533 ok(!refcount
, "Device has %u references left.\n", refcount
);
17534 DestroyWindow(window
);
17537 static void test_caps(void)
17539 DWORD caps_never
, caps_always
, caps_hal
;
17540 DDCAPS hal_caps
, hel_caps
;
17541 IDirectDraw7
*ddraw
;
17545 caps_never
= DDSCAPS_RESERVED1
17547 | DDSCAPS_PRIMARYSURFACELEFT
17548 | DDSCAPS_SYSTEMMEMORY
17550 | DDSCAPS_WRITEONLY
17551 | DDSCAPS_LIVEVIDEO
17554 | DDSCAPS_RESERVED2
17557 | DDSCAPS_ALLOCONLOAD
17558 | DDSCAPS_VIDEOPORT
17559 | DDSCAPS_STANDARDVGAMODE
17560 | DDSCAPS_OPTIMIZED
;
17562 caps_always
= DDSCAPS_FLIP
17563 | DDSCAPS_OFFSCREENPLAIN
17564 | DDSCAPS_PRIMARYSURFACE
17569 caps_hal
= DDSCAPS_BACKBUFFER
17571 | DDSCAPS_FRONTBUFFER
17573 | DDSCAPS_VIDEOMEMORY
17574 | DDSCAPS_LOCALVIDMEM
17575 | DDSCAPS_NONLOCALVIDMEM
;
17577 ddraw
= create_ddraw();
17578 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17580 memset(&hal_caps
, 0, sizeof(hal_caps
));
17581 memset(&hel_caps
, 0, sizeof(hel_caps
));
17582 hal_caps
.dwSize
= sizeof(hal_caps
);
17583 hel_caps
.dwSize
= sizeof(hel_caps
);
17584 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17585 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17586 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17587 "Got unexpected caps %#x, expected %#x.\n",
17588 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17589 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17590 "Got unexpected caps %#x, expected %#x.\n",
17591 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17593 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
17594 if (hal_caps
.ddsCaps
.dwCaps
)
17596 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17597 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17598 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17599 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17601 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17602 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17603 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17604 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17606 IDirectDraw7_Release(ddraw
);
17608 if (hal_caps
.ddsCaps
.dwCaps
)
17610 hr
= pDirectDrawCreateEx((GUID
*)DDCREATE_HARDWAREONLY
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
);
17611 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17613 memset(&hal_caps
, 0, sizeof(hal_caps
));
17614 memset(&hel_caps
, 0, sizeof(hel_caps
));
17615 hal_caps
.dwSize
= sizeof(hal_caps
);
17616 hel_caps
.dwSize
= sizeof(hel_caps
);
17617 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17618 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17619 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17620 "Got unexpected caps %#x, expected %#x.\n",
17621 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17622 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17623 "Got unexpected caps %#x, expected %#x.\n",
17624 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17626 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17627 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17628 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17629 "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17630 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17632 IDirectDraw7_Release(ddraw
);
17635 hr
= pDirectDrawCreateEx((GUID
*)DDCREATE_EMULATIONONLY
, (void **)&ddraw
, &IID_IDirectDraw7
, NULL
);
17636 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17638 memset(&hal_caps
, 0, sizeof(hal_caps
));
17639 memset(&hel_caps
, 0, sizeof(hel_caps
));
17640 hal_caps
.dwSize
= sizeof(hal_caps
);
17641 hel_caps
.dwSize
= sizeof(hel_caps
);
17642 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17643 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17644 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17645 "Got unexpected caps %#x, expected %#x.\n",
17646 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17647 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17648 "Got unexpected caps %#x, expected %#x.\n",
17649 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17651 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#x.\n", hal_caps
.ddsCaps
.dwCaps
);
17652 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17653 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17654 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17655 "Got unexpected caps %#x.\n", hel_caps
.ddsCaps
.dwCaps
);
17657 IDirectDraw7_Release(ddraw
);
17660 static void test_d32_support(void)
17662 IDirectDrawSurface7
*surface
;
17663 DDSURFACEDESC2 surface_desc
;
17664 IDirectDraw7
*ddraw
;
17669 window
= create_window();
17670 ddraw
= create_ddraw();
17671 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17672 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17673 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17675 memset(&surface_desc
, 0, sizeof(surface_desc
));
17676 surface_desc
.dwSize
= sizeof(surface_desc
);
17677 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
17678 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
17679 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
17680 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
17681 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 32;
17682 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0xffffffff;
17683 surface_desc
.dwWidth
= 64;
17684 surface_desc
.dwHeight
= 64;
17685 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17686 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17688 memset(&surface_desc
, 0, sizeof(surface_desc
));
17689 surface_desc
.dwSize
= sizeof(surface_desc
);
17690 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface
, &surface_desc
);
17691 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17692 ok((surface_desc
.dwFlags
& DDSD_PIXELFORMAT
), "Got unexpected flags %#x.\n", surface_desc
.dwFlags
);
17693 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
& DDPF_ZBUFFER
,
17694 "Got unexpected format flags %#x.\n", U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
17695 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
== 32,
17696 "Got unexpected dwZBufferBitDepth %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
);
17697 ok(U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
== 0xffffffff,
17698 "Got unexpected Z mask 0x%08x.\n", U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
);
17699 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
17700 "Got unexpected surface caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
17701 IDirectDrawSurface7_Release(surface
);
17703 refcount
= IDirectDraw7_Release(ddraw
);
17704 ok(!refcount
, "%u references left.\n", refcount
);
17705 DestroyWindow(window
);
17708 static void test_surface_format_conversion_alpha(void)
17710 static const unsigned int rgba_data
[4 * 4] =
17712 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff0000ff,
17713 0xff0000ff, 0xff00ff00, 0xff0000ff, 0xff0000ff,
17714 0xff00ff00, 0xff0000ff, 0xff00ff00, 0xff0000ff,
17715 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff00ff00,
17717 static const unsigned int rgbx_data
[4 * 4] =
17719 0x0000ff00, 0x000000ff, 0x000000ff, 0x000000ff,
17720 0x000000ff, 0x0000ff00, 0x000000ff, 0x000000ff,
17721 0x0000ff00, 0x000000ff, 0x0000ff00, 0x000000ff,
17722 0x0000ff00, 0x000000ff, 0x000000ff, 0x0000ff00,
17724 static const unsigned short int r5g6b5_data
[4 * 4] =
17726 0x07e0, 0x001f, 0x001f, 0x001f,
17727 0x001f, 0x07e0, 0x001f, 0x001f,
17728 0x07e0, 0x001f, 0x07e0, 0x001f,
17729 0x07e0, 0x001f, 0x001f, 0x07e0,
17731 static const unsigned short int r5g5b5x1_data
[4 * 4] =
17733 0x03e0, 0x001f, 0x001f, 0x001f,
17734 0x001f, 0x03e0, 0x001f, 0x001f,
17735 0x03e0, 0x001f, 0x03e0, 0x001f,
17736 0x03e0, 0x001f, 0x001f, 0x03e0,
17738 static const unsigned short int r5g5b5a1_data
[4 * 4] =
17740 0x83e0, 0x801f, 0x801f, 0x801f,
17741 0x801f, 0x83e0, 0x801f, 0x801f,
17742 0x83e0, 0x801f, 0x83e0, 0x801f,
17743 0x83e0, 0x801f, 0x801f, 0x83e0,
17745 static const unsigned int dxt1_data
[8] =
17747 0x001f07e0, 0x14445154,
17749 static const unsigned int dxt2_data
[16] =
17751 0xffffffff, 0xffffffff, 0x001f07e0, 0x14445154,
17754 enum test_format_id
17766 static const struct test_format
17770 unsigned int block_size
, x_blocks
, y_blocks
;
17771 DWORD support_flag
;
17772 BOOL broken_software_blit
, broken_hardware_blit
;
17778 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
17779 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
17785 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17786 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
17792 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17793 {16}, {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}
17795 "R5G6B5", 2, 4, 4, 0, TRUE
,
17796 /* Looks broken for sysmem texture conversions on Windows (at
17797 * least with hardware device), the result is either error from
17798 * _Blt() or a copy of the source data without any conversion. */
17802 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
17803 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}
17805 "R5G5B5X1", 2, 4, 4,
17809 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
17810 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}
17812 "R5G5B5A1", 2, 4, 4, 0, FALSE
, TRUE
,
17816 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
17817 {0}, {0}, {0}, {0}, {0}
17819 "DXT1", 8, 1, 1, SUPPORT_DXT1
,
17823 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '2'),
17824 {0}, {0}, {0}, {0}, {0}
17826 "DXT2", 16, 1, 1, SUPPORT_DXT2
,
17830 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '3'),
17831 {0}, {0}, {0}, {0}, {0}
17833 "DXT3", 16, 1, 1, SUPPORT_DXT3
,
17837 static const struct
17839 DWORD src_caps
, dst_caps
;
17843 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
17844 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
17845 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
17846 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
17849 static const struct
17851 enum test_format_id src_format
;
17852 const void *src_data
;
17853 enum test_format_id dst_format
;
17854 const void *expected_data
;
17860 /* The following 3 tests give different results on AMD and NVIDIA on Windows, disabling. */
17861 {FMT_RGBX
, rgbx_data
, FMT_RGBA
, rgba_data
},
17862 {FMT_RGBA
, rgba_data
, FMT_RGBX
, rgbx_data
},
17863 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_RGBA
, rgba_data
},
17865 {FMT_R5G6B5
, r5g6b5_data
, FMT_RGBA
, rgba_data
},
17866 {FMT_R5G6B5
, r5g6b5_data
, FMT_R5G5B5A1
, r5g5b5a1_data
},
17867 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_R5G5B5A1
, r5g5b5x1_data
, TRUE
},
17868 {FMT_R5G5B5A1
, r5g5b5a1_data
, FMT_R5G6B5
, r5g6b5_data
},
17869 {FMT_RGBA
, rgba_data
, FMT_DXT1
, dxt1_data
},
17870 {FMT_RGBX
, rgbx_data
, FMT_DXT1
, dxt1_data
},
17871 {FMT_RGBA
, rgba_data
, FMT_DXT2
, dxt2_data
},
17872 {FMT_RGBX
, rgbx_data
, FMT_DXT2
, dxt2_data
},
17873 {FMT_RGBA
, rgba_data
, FMT_DXT3
, dxt2_data
},
17874 {FMT_RGBX
, rgbx_data
, FMT_DXT3
, dxt2_data
},
17875 {FMT_DXT1
, dxt1_data
, FMT_DXT2
, dxt2_data
},
17876 {FMT_DXT1
, dxt1_data
, FMT_RGBA
, rgba_data
},
17877 {FMT_DXT1
, dxt1_data
, FMT_RGBX
, rgba_data
},
17878 {FMT_DXT3
, dxt2_data
, FMT_RGBA
, rgba_data
},
17879 {FMT_DXT3
, dxt2_data
, FMT_RGBX
, rgba_data
},
17882 const struct test_format
*src_format
, *dst_format
;
17883 IDirectDrawSurface7
*src_surf
, *dst_surf
;
17884 DDSURFACEDESC2 surface_desc
, lock
;
17885 unsigned int i
, j
, x
, y
, pitch
;
17886 IDirect3DDevice7
*device
;
17887 DWORD supported_fmts
;
17888 IDirectDraw7
*ddraw
;
17895 window
= create_window();
17896 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17898 skip("Failed to create a 3D device, skipping test.\n");
17899 DestroyWindow(window
);
17903 ddraw
= create_ddraw();
17904 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17905 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17906 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17908 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
17910 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17912 is_wine
= !strcmp(winetest_platform
, "wine");
17914 memset(&surface_desc
, 0, sizeof(surface_desc
));
17915 surface_desc
.dwSize
= sizeof(surface_desc
);
17916 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
17917 surface_desc
.dwWidth
= 4;
17918 surface_desc
.dwHeight
= 4;
17920 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
17922 src_format
= &formats
[tests
[i
].src_format
];
17923 dst_format
= &formats
[tests
[i
].dst_format
];
17925 if (~supported_fmts
& dst_format
->support_flag
)
17927 skip("%s format is not supported, skipping test %u.\n", dst_format
->name
, i
);
17930 if (~supported_fmts
& src_format
->support_flag
)
17932 skip("%s format is not supported, skipping test %u.\n", src_format
->name
, i
);
17936 for (j
= 0; j
< ARRAY_SIZE(test_caps
); ++j
)
17938 if (!is_wine
&& ((test_caps
[j
].src_caps
| test_caps
[j
].dst_caps
) & DDSCAPS_SYSTEMMEMORY
)
17939 && (src_format
->broken_software_blit
|| dst_format
->broken_software_blit
))
17941 if (!is_wine
&& (test_caps
[j
].dst_caps
& DDSCAPS_VIDEOMEMORY
)
17942 && dst_format
->broken_hardware_blit
)
17945 U4(surface_desc
).ddpfPixelFormat
= src_format
->fmt
;
17946 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].src_caps
;
17947 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &src_surf
, NULL
);
17948 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", j
, i
, hr
);
17950 U4(surface_desc
).ddpfPixelFormat
= dst_format
->fmt
;
17951 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].dst_caps
;
17952 hr
= IDirectDraw7_CreateSurface(ddraw
, &surface_desc
, &dst_surf
, NULL
);
17953 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", j
, i
, hr
);
17955 memset(&lock
, 0, sizeof(lock
));
17956 lock
.dwSize
= sizeof(lock
);
17957 hr
= IDirectDrawSurface7_Lock(src_surf
, NULL
, &lock
, 0, NULL
);
17958 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17959 pitch
= U1(lock
).lPitch
;
17960 for (y
= 0; y
< src_format
->y_blocks
; ++y
)
17962 memcpy((BYTE
*)lock
.lpSurface
+ y
* pitch
,
17963 (BYTE
*)tests
[i
].src_data
+ y
* src_format
->x_blocks
* src_format
->block_size
,
17964 src_format
->block_size
* src_format
->x_blocks
);
17966 hr
= IDirectDrawSurface7_Unlock(src_surf
, NULL
);
17967 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17969 hr
= IDirectDrawSurface7_Blt(dst_surf
, NULL
, src_surf
, NULL
, DDBLT_WAIT
, NULL
);
17970 if (!is_wine
&& FAILED(hr
))
17972 /* Some software blits are rejected on Windows. */
17973 IDirectDrawSurface7_Release(dst_surf
);
17974 IDirectDrawSurface7_Release(src_surf
);
17975 skip("Skipping test (%u, %u), cannot blit %s -> %s, hr %#x.\n", j
, i
,
17976 src_format
->name
, dst_format
->name
, hr
);
17979 ok(hr
== DD_OK
, "Test (%u, %s -> %s), got unexpected hr %#x.\n", j
,
17980 src_format
->name
, dst_format
->name
, hr
);
17982 memset(&lock
, 0, sizeof(lock
));
17983 lock
.dwSize
= sizeof(lock
);
17984 hr
= IDirectDrawSurface7_Lock(dst_surf
, NULL
, &lock
, 0, NULL
);
17985 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
17986 pitch
= U1(lock
).lPitch
;
17988 for (y
= 0; y
< dst_format
->y_blocks
; ++y
)
17990 const void *expected_data
= tests
[i
].expected_data
;
17992 passed
= !memcmp((BYTE
*)lock
.lpSurface
+ y
* pitch
,
17993 (BYTE
*)expected_data
+ y
* dst_format
->x_blocks
* dst_format
->block_size
,
17994 dst_format
->block_size
* dst_format
->x_blocks
);
17995 todo_wine_if(tests
[i
].todo
)
17996 ok(passed
, "Test (%u, %s -> %s), row %u, unexpected surface data.\n", j
,
17997 src_format
->name
, dst_format
->name
, y
);
17999 if (!passed
&& !(is_wine
&& tests
[i
].todo
))
18001 for (x
= 0; x
< dst_format
->x_blocks
* dst_format
->block_size
/ 4; ++x
)
18003 trace("Test (%u, %u), x %u, y %u, got 0x%08x, expected 0x%08x.\n", j
, i
, x
, y
,
18004 *(unsigned int *)((BYTE
*)lock
.lpSurface
+ y
* pitch
+ x
* 4),
18005 *(unsigned int *)((BYTE
*)expected_data
+ y
* dst_format
->x_blocks
18006 * dst_format
->block_size
+ x
* 4));
18012 hr
= IDirectDrawSurface7_Unlock(dst_surf
, NULL
);
18013 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18015 IDirectDrawSurface7_Release(dst_surf
);
18016 IDirectDrawSurface7_Release(src_surf
);
18020 IDirect3DDevice7_Release(device
);
18021 refcount
= IDirectDraw7_Release(ddraw
);
18022 ok(!refcount
, "%u references left.\n", refcount
);
18023 DestroyWindow(window
);
18026 static void test_compressed_surface_stretch(void)
18028 static const struct
18030 unsigned int src_width
, src_height
;
18031 unsigned int dst_width
, dst_height
;
18032 unsigned int src_x
, src_y
;
18033 unsigned int dst_x
, dst_y
;
18034 BOOL todo_src
, todo_dst
;
18040 {4, 4, 2, 2, 0, 0, 0, 0, FALSE
, TRUE
},
18041 {4, 4, 6, 6, 0, 0, 0, 0, FALSE
, TRUE
},
18042 {4, 4, 8, 8, 2, 2, 2, 2, TRUE
, TRUE
},
18045 static const struct
18047 DWORD src_caps
, dst_caps
;
18052 /* Broken on Windows. */
18053 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18055 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18056 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18057 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18064 DWORD support_flag
;
18070 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18071 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}
18077 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
18078 {0}, {0}, {0}, {0}, {0}
18080 "DXT1", SUPPORT_DXT1
,
18084 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '3'),
18085 {0}, {0}, {0}, {0}, {0}
18087 "DXT3", SUPPORT_DXT3
,
18091 unsigned int i
, j
, k
, l
, x
, y
, pitch
;
18092 DDSURFACEDESC2 rb_surface_desc
, src_surface_desc
, dst_surface_desc
, lock
;
18093 IDirectDrawSurface7
*src_surf
, *dst_surf
, *rb_surf
;
18094 IDirect3DDevice7
*device
;
18095 RECT src_rect
, dst_rect
;
18096 DWORD supported_fmts
;
18097 unsigned short *data
;
18098 IDirectDraw7
*ddraw
;
18105 window
= create_window();
18106 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
18108 skip("Failed to create a 3D device, skipping test.\n");
18109 DestroyWindow(window
);
18113 ddraw
= create_ddraw();
18114 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18115 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18116 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18118 hr
= IDirect3DDevice7_EnumTextureFormats(device
, test_block_formats_creation_cb
,
18120 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18122 memset(&src_surface_desc
, 0, sizeof(src_surface_desc
));
18123 src_surface_desc
.dwSize
= sizeof(src_surface_desc
);
18124 src_surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18125 dst_surface_desc
= src_surface_desc
;
18127 memset(&rb_surface_desc
, 0, sizeof(rb_surface_desc
));
18128 rb_surface_desc
.dwSize
= sizeof(rb_surface_desc
);
18129 rb_surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18130 U4(rb_surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(rb_surface_desc
).ddpfPixelFormat
);
18131 U4(rb_surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
18132 U1(U4(rb_surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
18133 U2(U4(rb_surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
18134 U3(U4(rb_surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
18135 U4(U4(rb_surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
18136 U5(U4(rb_surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00008000;
18137 rb_surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
18139 memset(&fx
, 0, sizeof(fx
));
18140 fx
.dwSize
= sizeof(fx
);
18142 memset(&lock
, 0, sizeof(lock
));
18143 lock
.dwSize
= sizeof(lock
);
18145 for (i
= 0; i
< ARRAY_SIZE(test_caps
); ++i
)
18147 src_surface_desc
.ddsCaps
.dwCaps
= test_caps
[i
].src_caps
;
18148 dst_surface_desc
.ddsCaps
.dwCaps
= test_caps
[i
].dst_caps
;
18150 for (j
= 0; j
< ARRAY_SIZE(test_sizes
); ++j
)
18152 SetRect(&src_rect
, test_sizes
[j
].src_x
, test_sizes
[j
].src_y
,
18153 test_sizes
[j
].src_width
, test_sizes
[j
].src_height
);
18154 SetRect(&dst_rect
, test_sizes
[j
].dst_x
, test_sizes
[j
].dst_y
,
18155 test_sizes
[j
].dst_width
, test_sizes
[j
].dst_height
);
18157 src_surface_desc
.dwWidth
= test_sizes
[j
].src_width
;
18158 src_surface_desc
.dwHeight
= test_sizes
[j
].src_height
;
18160 dst_surface_desc
.dwWidth
= (test_sizes
[j
].dst_width
+ 3) & ~3;
18161 dst_surface_desc
.dwHeight
= (test_sizes
[j
].dst_height
+ 3) & ~3;
18163 rb_surface_desc
.dwWidth
= max(src_surface_desc
.dwWidth
, dst_surface_desc
.dwWidth
);
18164 rb_surface_desc
.dwHeight
= max(src_surface_desc
.dwHeight
, dst_surface_desc
.dwHeight
);
18166 hr
= IDirectDraw7_CreateSurface(ddraw
, &rb_surface_desc
, &rb_surf
, NULL
);
18167 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#x.\n", i
, j
, hr
);
18169 for (k
= 0; k
< ARRAY_SIZE(test_formats
); ++k
)
18171 U4(src_surface_desc
).ddpfPixelFormat
= test_formats
[k
].fmt
;
18172 hr
= IDirectDraw7_CreateSurface(ddraw
, &src_surface_desc
, &src_surf
, NULL
);
18173 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18175 U5(fx
).dwFillColor
= 0x801f;
18176 hr
= IDirectDrawSurface7_Blt(rb_surf
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
18177 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18179 hr
= IDirectDrawSurface7_Blt(src_surf
, &src_rect
, rb_surf
, &src_rect
, DDBLT_WAIT
, NULL
);
18181 todo_wine_if(test_formats
[k
].fmt
.dwFlags
== DDPF_FOURCC
&& test_sizes
[j
].todo_src
)
18182 ok(hr
== DD_OK
, "Test (%u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, hr
);
18185 IDirectDrawSurface7_Release(src_surf
);
18189 for (l
= 0; l
< ARRAY_SIZE(test_formats
); ++l
)
18191 if (~supported_fmts
& test_formats
[l
].support_flag
)
18193 skip("%s format is not supported, skipping test %u.\n", test_formats
[l
].name
, i
);
18197 U4(dst_surface_desc
).ddpfPixelFormat
= test_formats
[l
].fmt
;
18199 hr
= IDirectDraw7_CreateSurface(ddraw
, &dst_surface_desc
, &dst_surf
, NULL
);
18200 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18202 memset(&lock
, 0, sizeof(lock
));
18203 lock
.dwSize
= sizeof(lock
);
18205 /* r200 does not init vidmem DXT3 surfaces to 0 correctly. Do it manually.
18206 * We can't use DDBLT_COLORFILL on compressed surfaces, so we need memset.
18208 * Locking alone is not enough, so this isn't an accidental workaround that
18209 * forces a different codepath because the destination is currently in sysmem. */
18210 if (test_formats
[l
].fmt
.dwFourCC
== MAKEFOURCC('D', 'X', 'T', '3'))
18212 hr
= IDirectDrawSurface7_Lock(dst_surf
, NULL
, &lock
, 0, NULL
);
18213 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18214 memset(lock
.lpSurface
, 0, U1(lock
).dwLinearSize
);
18215 hr
= IDirectDrawSurface7_Unlock(dst_surf
, NULL
);
18216 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18219 hr
= IDirectDrawSurface7_Blt(dst_surf
, &dst_rect
, src_surf
, &src_rect
, DDBLT_WAIT
, NULL
);
18220 todo_wine_if(test_formats
[l
].fmt
.dwFlags
== DDPF_FOURCC
&& test_sizes
[j
].todo_dst
)
18221 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18224 IDirectDrawSurface7_Release(dst_surf
);
18228 U5(fx
).dwFillColor
= 0xffffffff;
18229 hr
= IDirectDrawSurface7_Blt(rb_surf
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
18230 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18232 hr
= IDirectDrawSurface7_Blt(rb_surf
, &dst_rect
, dst_surf
, &dst_rect
, DDBLT_WAIT
, NULL
);
18233 ok(hr
== DD_OK
, "Test (%u, %u, %u, %u), got unexpected hr %#x.\n", i
, j
, k
, l
, hr
);
18234 hr
= IDirectDrawSurface7_Lock(rb_surf
, NULL
, &lock
, 0, NULL
);
18235 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18236 pitch
= U1(lock
).lPitch
;
18239 for (y
= dst_rect
.top
; y
< dst_rect
.bottom
&& passed
; ++y
)
18241 data
= (unsigned short *)((BYTE
*)lock
.lpSurface
+ y
* pitch
);
18243 for (x
= dst_rect
.left
; x
< dst_rect
.right
&& passed
; ++x
)
18245 passed
= data
[x
] == 0x801f;
18246 ok(passed
, "Test (%u, %u, %u, %u), x %u, y %u, "
18247 "got unexpected colour 0x%04x.\n", i
, j
, k
, l
, x
, y
, data
[x
]);
18250 hr
= IDirectDrawSurface7_Unlock(rb_surf
, NULL
);
18251 IDirectDrawSurface7_Release(dst_surf
);
18253 IDirectDrawSurface7_Release(src_surf
);
18255 IDirectDrawSurface7_Release(rb_surf
);
18259 IDirect3DDevice7_Release(device
);
18260 refcount
= IDirectDraw7_Release(ddraw
);
18261 ok(!refcount
, "%u references left.\n", refcount
);
18262 DestroyWindow(window
);
18265 struct find_different_mode_param
18267 unsigned int old_width
;
18268 unsigned int old_height
;
18269 unsigned int old_frequency
;
18270 unsigned int new_width
;
18271 unsigned int new_height
;
18272 unsigned int new_frequency
;
18273 unsigned int new_bpp
;
18276 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC2
*surface_desc
, void *context
)
18278 struct find_different_mode_param
*param
= context
;
18280 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
18281 return DDENUMRET_OK
;
18283 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
18284 surface_desc
->dwRefreshRate
!= param
->old_frequency
)
18286 param
->new_width
= surface_desc
->dwWidth
;
18287 param
->new_height
= surface_desc
->dwHeight
;
18288 param
->new_frequency
= surface_desc
->dwRefreshRate
;
18289 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
18290 return DDENUMRET_CANCEL
;
18293 return DDENUMRET_OK
;
18296 static void test_cursor_clipping(void)
18298 struct find_different_mode_param param
;
18299 DDSURFACEDESC2 surface_desc
;
18300 RECT rect
, clip_rect
;
18301 IDirectDraw7
*ddraw
;
18306 window
= create_window();
18307 ok(!!window
, "Failed to create a window.\n");
18308 ddraw
= create_ddraw();
18309 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18311 memset(&surface_desc
, 0, sizeof(surface_desc
));
18312 surface_desc
.dwSize
= sizeof(surface_desc
);
18313 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18314 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18316 memset(¶m
, 0, sizeof(param
));
18317 param
.old_width
= surface_desc
.dwWidth
;
18318 param
.old_height
= surface_desc
.dwHeight
;
18319 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
18320 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
18321 if (!(param
.new_width
&& param
.new_height
))
18323 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
18327 ret
= ClipCursor(NULL
);
18328 ok(ret
, "ClipCursor failed, error %#x.\n", GetLastError());
18329 get_virtual_rect(&rect
);
18330 ret
= GetClipCursor(&clip_rect
);
18331 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18332 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18333 wine_dbgstr_rect(&clip_rect
));
18335 /* Set cooperative level to normal */
18336 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18337 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18339 get_virtual_rect(&rect
);
18340 ret
= GetClipCursor(&clip_rect
);
18341 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18342 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18343 wine_dbgstr_rect(&clip_rect
));
18345 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18346 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
18349 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
18353 get_virtual_rect(&rect
);
18354 ret
= GetClipCursor(&clip_rect
);
18355 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18356 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18357 wine_dbgstr_rect(&clip_rect
));
18359 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
18360 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
18362 get_virtual_rect(&rect
);
18363 ret
= GetClipCursor(&clip_rect
);
18364 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18365 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18366 wine_dbgstr_rect(&clip_rect
));
18368 /* Switch to full screen cooperative level */
18369 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18370 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18372 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18373 ret
= GetClipCursor(&clip_rect
);
18374 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18375 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18376 wine_dbgstr_rect(&clip_rect
));
18378 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18379 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#x.\n", hr
);
18382 win_skip("SetDisplayMode failed, hr %#x.\n", hr
);
18386 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
18387 ret
= GetClipCursor(&clip_rect
);
18388 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18389 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18390 wine_dbgstr_rect(&clip_rect
));
18392 /* Restore display mode */
18393 hr
= IDirectDraw7_RestoreDisplayMode(ddraw
);
18394 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#x.\n", hr
);
18396 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18397 ret
= GetClipCursor(&clip_rect
);
18398 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18399 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18400 wine_dbgstr_rect(&clip_rect
));
18402 /* Switch to normal cooperative level */
18403 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18404 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18406 get_virtual_rect(&rect
);
18407 ret
= GetClipCursor(&clip_rect
);
18408 ok(ret
, "GetClipCursor failed, error %#x.\n", GetLastError());
18409 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18410 wine_dbgstr_rect(&clip_rect
));
18413 IDirectDraw7_Release(ddraw
);
18414 DestroyWindow(window
);
18417 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18420 RECT primary_rect
, window_rect
;
18421 IDirectDraw7
*ddraw
;
18426 ddraw
= create_ddraw();
18427 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18428 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
18429 monitor_rect
->top
, monitor_rect
->right
- monitor_rect
->left
,
18430 monitor_rect
->bottom
- monitor_rect
->top
, NULL
, NULL
, NULL
, NULL
);
18431 ok(!!window
, "Failed to create a window.\n");
18434 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18435 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18437 ret
= GetWindowRect(window
, &window_rect
);
18438 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18439 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
18440 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18441 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18443 /* Window activation should restore the window to fit the whole primary monitor */
18444 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18445 SWP_NOZORDER
| SWP_NOSIZE
);
18446 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
18447 ret
= SetForegroundWindow(GetDesktopWindow());
18448 ok(ret
, "Failed to set foreground window.\n");
18450 ret
= ShowWindow(window
, SW_RESTORE
);
18451 ok(ret
, "Failed to restore window, error %#x.\n", GetLastError());
18453 ret
= SetForegroundWindow(window
);
18454 ok(ret
, "SetForegroundWindow failed, error %#x.\n", GetLastError());
18456 ret
= GetWindowRect(window
, &window_rect
);
18457 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18458 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18459 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18461 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18462 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18463 ret
= GetWindowRect(window
, &window_rect
);
18464 ok(ret
, "GetWindowRect failed, error %#x.\n", GetLastError());
18465 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18466 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18468 DestroyWindow(window
);
18469 IDirectDraw7_Release(ddraw
);
18473 static void test_window_position(void)
18475 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
18478 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18481 DDSURFACEDESC2 surface_desc
;
18482 IDirectDraw7
*ddraw
;
18487 ddraw
= create_ddraw();
18488 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18489 window
= create_window();
18490 ok(!!window
, "Failed to create a window.\n");
18492 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
18493 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18494 SWP_NOZORDER
| SWP_NOSIZE
);
18495 ok(ret
, "SetWindowPos failed, error %#x.\n", GetLastError());
18497 surface_desc
.dwSize
= sizeof(surface_desc
);
18498 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18499 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18500 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %d.\n",
18501 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
18502 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %d.\n",
18503 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
18505 DestroyWindow(window
);
18506 IDirectDraw7_Release(ddraw
);
18510 static void test_get_display_mode(void)
18512 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
18513 struct find_different_mode_param param
;
18514 DDSURFACEDESC2 surface_desc
;
18515 IDirectDraw7
*ddraw
;
18521 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
18523 ddraw
= create_ddraw();
18524 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18525 window
= create_window();
18526 ok(!!window
, "Failed to create a window.\n");
18528 hr
= IDirectDraw7_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18529 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#x.\n", hr
);
18531 memset(&devmode
, 0, sizeof(devmode
));
18532 devmode
.dmSize
= sizeof(devmode
);
18533 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
18534 ok(ret
, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
18536 surface_desc
.dwSize
= sizeof(surface_desc
);
18537 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18538 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18539 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Expected dwSize %u, got %u.\n",
18540 sizeof(surface_desc
), surface_desc
.dwSize
);
18541 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#x, got %#x.\n", flags
,
18542 surface_desc
.dwFlags
);
18543 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %u, got %u.\n",
18544 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
18545 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %u, got %u.\n",
18546 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
18547 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %u, got %u.\n",
18548 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
18549 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
18550 "Expected ddpfPixelFormat.dwSize %u, got %u.\n", sizeof(surface_desc
.ddpfPixelFormat
),
18551 surface_desc
.ddpfPixelFormat
.dwSize
);
18552 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
18553 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
18554 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18555 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18556 "Expected pitch %u, got %u.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18557 surface_desc
.lPitch
);
18559 memset(¶m
, 0, sizeof(param
));
18560 param
.old_frequency
= surface_desc
.dwRefreshRate
;
18561 hr
= IDirectDraw7_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
18562 find_different_mode_callback
);
18563 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#x.\n", hr
);
18564 if (!param
.new_frequency
)
18566 skip("Failed to find a display mode with a different frequency.\n");
18570 hr
= IDirectDraw7_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
18571 param
.new_frequency
, 0);
18572 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#x.\n", hr
);
18573 hr
= IDirectDraw7_GetDisplayMode(ddraw
, &surface_desc
);
18574 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#x.\n", hr
);
18575 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %u.\n", param
.new_width
,
18576 surface_desc
.dwWidth
);
18577 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %u.\n", param
.new_height
,
18578 surface_desc
.dwHeight
);
18579 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %u.\n",
18580 param
.new_frequency
, surface_desc
.dwRefreshRate
);
18581 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
18582 "Expected ddpfPixelFormat.dwRGBBitCount %u, got %u.\n", devmode
.dmBitsPerPel
,
18583 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18586 DestroyWindow(window
);
18587 IDirectDraw7_Release(ddraw
);
18590 static void test_texture_wrong_caps(const GUID
*device_guid
)
18594 struct vec3 position
;
18595 struct vec2 texcoord
;
18599 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
18600 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
18601 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
18602 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
18604 static DDPIXELFORMAT fmt
=
18606 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18607 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
18609 IDirectDrawSurface7
*surface
, *rt
;
18610 IDirect3DDevice7
*device
;
18611 IDirectDraw7
*ddraw
;
18612 DDSURFACEDESC2 ddsd
;
18619 window
= create_window();
18620 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
18622 skip("Failed to create a 3D device, skipping test.\n");
18623 DestroyWindow(window
);
18626 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
18627 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18628 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
18629 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18630 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
18631 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18633 memset(&ddsd
, 0, sizeof(ddsd
));
18634 ddsd
.dwSize
= sizeof(ddsd
);
18635 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
18636 ddsd
.dwHeight
= 16;
18638 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
18639 U4(ddsd
).ddpfPixelFormat
= fmt
;
18640 hr
= IDirectDraw7_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
18641 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18643 fill_surface(surface
, 0xff00ff00);
18645 hr
= IDirect3DDevice7_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
18646 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18648 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
18649 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18650 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
18651 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18652 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
18653 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18654 hr
= IDirect3DDevice7_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
18655 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18657 hr
= IDirect3DDevice7_SetTexture(device
, 0, surface
);
18658 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18660 hr
= IDirect3DDevice7_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
18661 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18662 if (is_software_device_type(device_guid
))
18663 fill_surface(rt
, 0x000000ff);
18665 hr
= IDirect3DDevice7_BeginScene(device
);
18666 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18667 hr
= IDirect3DDevice7_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
18668 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
18669 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18670 hr
= IDirect3DDevice7_EndScene(device
);
18671 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
18673 color
= get_surface_color(rt
, 320, 240);
18674 ok(color
== 0, "Got unexpected color 0x%08x.\n", color
);
18676 IDirectDrawSurface7_Release(surface
);
18677 IDirectDrawSurface7_Release(rt
);
18678 IDirectDraw7_Release(ddraw
);
18679 IDirect3D7_Release(d3d
);
18680 refcount
= IDirect3DDevice3_Release(device
);
18681 ok(!refcount
, "Device has %u references left.\n", refcount
);
18682 DestroyWindow(window
);
18685 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
18687 test_func(hw_device_guid
);
18688 test_func(&IID_IDirect3DRGBDevice
);
18693 DDDEVICEIDENTIFIER2 identifier
;
18694 HMODULE module
, dwmapi
;
18695 DEVMODEW current_mode
;
18696 IDirectDraw7
*ddraw
;
18701 module
= GetModuleHandleA("ddraw.dll");
18702 if (!(pDirectDrawCreateEx
= (void *)GetProcAddress(module
, "DirectDrawCreateEx")))
18704 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
18708 if (!(ddraw
= create_ddraw()))
18710 skip("Failed to create a ddraw object, skipping tests.\n");
18714 if (ddraw_get_identifier(ddraw
, &identifier
))
18716 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
18717 trace("Description string: \"%s\"\n", identifier
.szDescription
);
18718 trace("Driver version %d.%d.%d.%d\n",
18719 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
18720 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
18723 if (IDirectDraw7_QueryInterface(ddraw
, &IID_IDirect3D7
, (void **)&d3d
) == DD_OK
)
18725 hr
= IDirect3D7_EnumDevices(d3d
, enum_devtype_cb
, &hal_ok
);
18726 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
18728 hw_device_guid
= &IID_IDirect3DTnLHalDevice
;
18729 IDirectDraw7_Release(d3d
);
18733 trace("D3D interface is not available.\n");
18736 IDirectDraw7_Release(ddraw
);
18738 memset(¤t_mode
, 0, sizeof(current_mode
));
18739 current_mode
.dmSize
= sizeof(current_mode
);
18740 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
18741 registry_mode
.dmSize
= sizeof(registry_mode
);
18742 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
18743 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
18744 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
18746 skip("Current mode does not match registry mode, skipping test.\n");
18750 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
18751 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
18753 test_process_vertices();
18754 test_coop_level_create_device_window();
18755 test_clipper_blt();
18756 test_coop_level_d3d_state();
18757 test_surface_interface_mismatch();
18758 test_coop_level_threaded();
18759 run_for_each_device_type(test_depth_blit
);
18760 test_texture_load_ckey();
18761 run_for_each_device_type(test_zenable
);
18762 run_for_each_device_type(test_ck_rgba
);
18768 test_window_style();
18769 test_redundant_mode_set();
18770 test_coop_level_mode_set();
18771 test_coop_level_mode_set_multi();
18773 test_coop_level_surf_create();
18775 test_coop_level_multi_window();
18776 test_draw_strided();
18778 test_specular_lighting();
18779 test_clear_rect_count();
18780 test_coop_level_versions();
18781 test_fog_special();
18782 test_lighting_interface_versions();
18783 test_coop_level_activateapp();
18784 test_texturemanage();
18785 test_block_formats_creation();
18786 test_unsupported_formats();
18787 run_for_each_device_type(test_rt_caps
);
18788 test_primary_caps();
18789 test_surface_lock();
18790 test_surface_discard();
18792 test_set_surface_desc();
18793 test_user_memory_getdc();
18794 test_sysmem_overlay();
18795 test_primary_palette();
18796 test_surface_attachment();
18797 test_private_data();
18798 test_pixel_format();
18799 test_create_surface_pitch();
18801 test_palette_complex();
18804 test_palette_gdi();
18805 test_palette_alpha();
18806 test_vb_writeonly();
18807 test_lost_device();
18808 test_resource_priority();
18809 test_surface_desc_lock();
18810 test_fog_interpolation();
18811 test_fog_process_vertices();
18812 test_negative_fixedfunction_fog();
18813 test_table_fog_zw();
18814 test_signed_formats();
18816 test_texcoordindex();
18817 test_colorkey_precision();
18818 test_range_colorkey();
18820 test_lockrect_invalid();
18821 test_yv12_overlay();
18822 test_offscreen_overlay();
18823 test_overlay_rect();
18825 test_blt_z_alpha();
18826 test_cross_device_blt();
18827 test_color_clamping();
18829 test_draw_primitive();
18830 test_edge_antialiasing_blending();
18831 test_display_mode_surface_pixel_format();
18832 test_surface_desc_size();
18833 test_get_surface_from_dc();
18834 test_ck_operation();
18835 test_vb_refcount();
18836 test_compute_sphere_visibility();
18837 test_clip_planes_limits();
18838 test_texture_stages_limits();
18839 test_set_render_state();
18840 test_map_synchronisation();
18841 test_depth_readback();
18843 test_enum_surfaces();
18845 test_device_load();
18846 test_color_vertex();
18848 test_sysmem_draw();
18849 test_gdi_surface();
18850 test_multiply_transform();
18852 test_clipper_refcount();
18853 test_begin_end_state_block();
18855 test_d32_support();
18856 test_surface_format_conversion_alpha();
18857 test_compressed_surface_stretch();
18858 test_cursor_clipping();
18859 test_window_position();
18860 test_get_display_mode();
18861 run_for_each_device_type(test_texture_wrong_caps
);