2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
24 #include "wine/heap.h"
30 HRESULT WINAPI
GetSurfaceFromDC(HDC dc
, struct IDirectDrawSurface
**surface
, HDC
*device_dc
);
32 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
33 static DEVMODEW registry_mode
;
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_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, 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
)
81 && compare_float(vec
->w
, w
, ulps
);
84 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
86 unsigned int diff
= x
> y
? x
- y
: y
- x
;
88 return diff
<= max_diff
;
91 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
93 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
94 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
95 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
96 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
99 static void get_virtual_rect(RECT
*rect
)
101 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
102 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
103 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
104 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
107 /* Try to make sure pending X events have been processed before continuing */
108 static void flush_events(void)
114 time
= GetTickCount() + diff
;
117 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
119 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
120 DispatchMessageA(&msg
);
121 diff
= time
- GetTickCount();
125 static BOOL
ddraw_get_identifier(IDirectDraw4
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
129 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw
, identifier
, 0);
130 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#lx.\n", hr
);
132 return SUCCEEDED(hr
);
135 static BOOL
ddraw_is_warp(IDirectDraw4
*ddraw
)
137 DDDEVICEIDENTIFIER identifier
;
139 return strcmp(winetest_platform
, "wine")
140 && ddraw_get_identifier(ddraw
, &identifier
)
141 && strstr(identifier
.szDriver
, "warp");
144 static BOOL
ddraw_is_vendor(IDirectDraw4
*ddraw
, DWORD vendor
)
146 DDDEVICEIDENTIFIER identifier
;
148 return strcmp(winetest_platform
, "wine")
149 && ddraw_get_identifier(ddraw
, &identifier
)
150 && identifier
.dwVendorId
== vendor
;
153 static BOOL
ddraw_is_amd(IDirectDraw4
*ddraw
)
155 return ddraw_is_vendor(ddraw
, 0x1002);
158 static BOOL
ddraw_is_intel(IDirectDraw4
*ddraw
)
160 return ddraw_is_vendor(ddraw
, 0x8086);
163 static BOOL
ddraw_is_nvidia(IDirectDraw4
*ddraw
)
165 return ddraw_is_vendor(ddraw
, 0x10de);
168 static BOOL
ddraw_is_vmware(IDirectDraw4
*ddraw
)
170 return ddraw_is_vendor(ddraw
, 0x15ad);
173 static BOOL
is_software_device_type(const GUID
*device_guid
)
175 return device_guid
!= &IID_IDirect3DHALDevice
;
178 static IDirectDrawSurface4
*create_overlay(IDirectDraw4
*ddraw
,
179 unsigned int width
, unsigned int height
, DWORD format
)
181 IDirectDrawSurface4
*surface
;
184 memset(&desc
, 0, sizeof(desc
));
185 desc
.dwSize
= sizeof(desc
);
186 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
187 desc
.dwWidth
= width
;
188 desc
.dwHeight
= height
;
189 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
190 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
191 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
192 U4(desc
).ddpfPixelFormat
.dwFourCC
= format
;
194 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
199 static HWND
create_window(void)
201 RECT r
= {0, 0, 640, 480};
203 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
205 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
206 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
209 static DWORD WINAPI
create_window_thread_proc(void *param
)
211 struct create_window_thread_param
*p
= param
;
215 p
->window
= create_window();
216 ret
= SetEvent(p
->window_created
);
217 ok(ret
, "SetEvent failed, last error %lu.\n", GetLastError());
223 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
224 DispatchMessageA(&msg
);
225 res
= WaitForSingleObject(p
->destroy_window
, 100);
226 if (res
== WAIT_OBJECT_0
)
228 if (res
!= WAIT_TIMEOUT
)
230 ok(0, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
235 DestroyWindow(p
->window
);
240 static void create_window_thread(struct create_window_thread_param
*p
)
244 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
245 ok(!!p
->window_created
, "CreateEvent failed, last error %lu.\n", GetLastError());
246 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
247 ok(!!p
->destroy_window
, "CreateEvent failed, last error %lu.\n", GetLastError());
248 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
249 ok(!!p
->thread
, "Failed to create thread, last error %lu.\n", GetLastError());
250 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
251 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
254 static void destroy_window_thread(struct create_window_thread_param
*p
)
256 SetEvent(p
->destroy_window
);
257 WaitForSingleObject(p
->thread
, INFINITE
);
258 CloseHandle(p
->destroy_window
);
259 CloseHandle(p
->window_created
);
260 CloseHandle(p
->thread
);
263 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
265 IDirectDrawSurface4
*rt
, *ret
;
266 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, {0}};
269 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
270 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#lx.\n", hr
);
271 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
272 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#lx.\n", hr
);
273 IDirectDrawSurface4_Release(rt
);
277 /* Free original_modes after finished using it */
278 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
280 unsigned int number
, size
= 2, count
= 0, index
= 0;
281 DISPLAY_DEVICEW display_device
;
282 DEVMODEW
*modes
, *tmp
;
284 if (!(modes
= heap_alloc(size
* sizeof(*modes
))))
287 display_device
.cb
= sizeof(display_device
);
288 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
290 /* Skip software devices */
291 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
294 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
300 if (!(tmp
= heap_realloc(modes
, size
* sizeof(*modes
))))
308 memset(&modes
[count
], 0, sizeof(modes
[count
]));
309 modes
[count
].dmSize
= sizeof(modes
[count
]);
310 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
316 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
319 *original_modes
= modes
;
320 *display_count
= count
;
324 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
329 for (index
= 0; index
< count
; ++index
)
331 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
332 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
333 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
336 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
337 return ret
== DISP_CHANGE_SUCCESSFUL
;
340 static HRESULT
set_display_mode(IDirectDraw4
*ddraw
, DWORD width
, DWORD height
)
342 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
344 return IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
347 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
349 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
350 DDSURFACEDESC2 surface_desc
;
354 memset(&surface_desc
, 0, sizeof(surface_desc
));
355 surface_desc
.dwSize
= sizeof(surface_desc
);
357 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
358 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
362 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
364 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
365 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
370 static void fill_surface(IDirectDrawSurface4
*surface
, D3DCOLOR color
)
372 DDSURFACEDESC2 surface_desc
= {sizeof(surface_desc
)};
377 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
378 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
380 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
382 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
383 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
389 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
390 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
393 static void check_rect(IDirectDrawSurface4
*surface
, RECT r
)
395 LONG x_coords
[2][2] =
397 {r
.left
- 1, r
.left
+ 1},
398 {r
.right
+ 1, r
.right
- 1},
400 LONG y_coords
[2][2] =
402 {r
.top
- 1, r
.top
+ 1},
403 {r
.bottom
+ 1, r
.bottom
- 1}
405 unsigned int color
, i
, j
, x_side
, y_side
;
408 for (i
= 0; i
< 2; ++i
)
410 for (j
= 0; j
< 2; ++j
)
412 for (x_side
= 0; x_side
< 2; ++x_side
)
414 for (y_side
= 0; y_side
< 2; ++y_side
)
416 unsigned int expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
418 x
= x_coords
[i
][x_side
];
419 y
= y_coords
[j
][y_side
];
420 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
422 color
= get_surface_color(surface
, x
, y
);
423 ok(color
== expected
, "Pixel (%ld, %ld) has color %08x, expected %08x.\n", x
, y
, color
, expected
);
430 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
432 DDPIXELFORMAT
*z_fmt
= ctx
;
434 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
440 static IDirectDraw4
*create_ddraw(void)
442 IDirectDraw4
*ddraw4
;
446 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
449 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
450 IDirectDraw_Release(ddraw1
);
457 static IDirect3DDevice3
*create_device_ex(HWND window
, DWORD coop_level
, const GUID
*device_guid
)
459 IDirectDrawSurface4
*surface
, *ds
;
460 IDirect3DDevice3
*device
= NULL
;
461 DDSURFACEDESC2 surface_desc
;
462 IDirectDraw4
*ddraw4
;
467 if (!(ddraw4
= create_ddraw()))
470 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
471 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
473 memset(&surface_desc
, 0, sizeof(surface_desc
));
474 surface_desc
.dwSize
= sizeof(surface_desc
);
475 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
476 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
477 if (is_software_device_type(device_guid
))
478 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
479 surface_desc
.dwWidth
= 640;
480 surface_desc
.dwHeight
= 480;
482 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
483 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
485 if (coop_level
& DDSCL_NORMAL
)
487 IDirectDrawClipper
*clipper
;
489 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
490 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
491 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
492 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
493 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
494 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#lx.\n", hr
);
495 IDirectDrawClipper_Release(clipper
);
498 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
499 IDirectDraw4_Release(ddraw4
);
502 IDirectDrawSurface4_Release(surface
);
506 memset(&z_fmt
, 0, sizeof(z_fmt
));
507 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, device_guid
, enum_z_fmt
, &z_fmt
);
508 if (FAILED(hr
) || !z_fmt
.dwSize
)
510 IDirect3D3_Release(d3d3
);
511 IDirectDrawSurface4_Release(surface
);
515 memset(&surface_desc
, 0, sizeof(surface_desc
));
516 surface_desc
.dwSize
= sizeof(surface_desc
);
517 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
518 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
519 if (is_software_device_type(device_guid
))
520 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
522 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
523 surface_desc
.dwWidth
= 640;
524 surface_desc
.dwHeight
= 480;
525 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
526 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
529 IDirect3D3_Release(d3d3
);
530 IDirectDrawSurface4_Release(surface
);
534 hr
= IDirectDrawSurface4_AddAttachedSurface(surface
, ds
);
535 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
536 IDirectDrawSurface4_Release(ds
);
539 IDirect3D3_Release(d3d3
);
540 IDirectDrawSurface4_Release(surface
);
544 hr
= IDirect3D3_CreateDevice(d3d3
, device_guid
, surface
, &device
, NULL
);
545 IDirect3D3_Release(d3d3
);
546 IDirectDrawSurface4_Release(surface
);
553 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
555 return create_device_ex(window
, coop_level
, &IID_IDirect3DHALDevice
);
558 static IDirect3DViewport3
*create_viewport(IDirect3DDevice3
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
560 IDirect3DViewport3
*viewport
;
565 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
566 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
567 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
568 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
569 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
570 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
571 memset(&vp
, 0, sizeof(vp
));
572 vp
.dwSize
= sizeof(vp
);
579 vp
.dvClipWidth
= 2.0f
;
580 vp
.dvClipHeight
= 2.0f
;
583 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
584 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
585 IDirect3D3_Release(d3d
);
590 static void destroy_viewport(IDirect3DDevice3
*device
, IDirect3DViewport3
*viewport
)
594 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
595 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
596 IDirect3DViewport3_Release(viewport
);
599 static IDirect3DMaterial3
*create_material(IDirect3DDevice3
*device
, D3DMATERIAL
*mat
)
601 IDirect3DMaterial3
*material
;
605 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
606 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
607 hr
= IDirect3D3_CreateMaterial(d3d
, &material
, NULL
);
608 ok(SUCCEEDED(hr
), "Failed to create material, hr %#lx.\n", hr
);
609 hr
= IDirect3DMaterial3_SetMaterial(material
, mat
);
610 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
611 IDirect3D3_Release(d3d
);
616 static IDirect3DMaterial3
*create_diffuse_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
620 memset(&mat
, 0, sizeof(mat
));
621 mat
.dwSize
= sizeof(mat
);
622 U1(U(mat
).diffuse
).r
= r
;
623 U2(U(mat
).diffuse
).g
= g
;
624 U3(U(mat
).diffuse
).b
= b
;
625 U4(U(mat
).diffuse
).a
= a
;
627 return create_material(device
, &mat
);
630 static IDirect3DMaterial3
*create_diffuse_and_ambient_material(IDirect3DDevice3
*device
,
631 float r
, float g
, float b
, float a
)
635 memset(&mat
, 0, sizeof(mat
));
636 mat
.dwSize
= sizeof(mat
);
637 U1(U(mat
).diffuse
).r
= r
;
638 U2(U(mat
).diffuse
).g
= g
;
639 U3(U(mat
).diffuse
).b
= b
;
640 U4(U(mat
).diffuse
).a
= a
;
642 U1(U(mat
).ambient
).r
= r
;
643 U2(U(mat
).ambient
).g
= g
;
644 U3(U(mat
).ambient
).b
= b
;
645 U4(U(mat
).ambient
).a
= a
;
647 return create_material(device
, &mat
);
650 static IDirect3DMaterial3
*create_specular_material(IDirect3DDevice3
*device
,
651 float r
, float g
, float b
, float a
, float power
)
655 memset(&mat
, 0, sizeof(mat
));
656 mat
.dwSize
= sizeof(mat
);
657 U1(U2(mat
).specular
).r
= r
;
658 U2(U2(mat
).specular
).g
= g
;
659 U3(U2(mat
).specular
).b
= b
;
660 U4(U2(mat
).specular
).a
= a
;
661 U4(mat
).power
= power
;
663 return create_material(device
, &mat
);
666 static IDirect3DMaterial3
*create_emissive_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
670 memset(&mat
, 0, sizeof(mat
));
671 mat
.dwSize
= sizeof(mat
);
672 U1(U3(mat
).emissive
).r
= r
;
673 U2(U3(mat
).emissive
).g
= g
;
674 U3(U3(mat
).emissive
).b
= b
;
675 U4(U3(mat
).emissive
).a
= a
;
677 return create_material(device
, &mat
);
680 static void destroy_material(IDirect3DMaterial3
*material
)
682 IDirect3DMaterial3_Release(material
);
689 WPARAM expect_wparam
;
693 static const struct message
*expect_messages
;
694 static IDirectDraw4
*focus_test_ddraw
;
696 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
700 if (expect_messages
&& message
== expect_messages
->message
)
702 if (expect_messages
->check_wparam
)
703 ok (wparam
== expect_messages
->expect_wparam
,
704 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
705 wparam
, message
, expect_messages
->expect_wparam
);
707 if (focus_test_ddraw
)
709 hr
= IDirectDraw4_TestCooperativeLevel(focus_test_ddraw
);
710 ok(hr
== expect_messages
->ddraw_state
, "Got ddraw state %#lx on message %#x, expected %#lx.\n",
711 hr
, message
, expect_messages
->ddraw_state
);
717 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
720 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
721 * interface. This prevents subsequent SetCooperativeLevel() calls on a
722 * different window from failing with DDERR_HWNDALREADYSET. */
723 static void fix_wndproc(HWND window
, LONG_PTR proc
)
728 if (!(ddraw
= create_ddraw()))
731 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
732 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
733 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
734 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
735 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
737 IDirectDraw4_Release(ddraw
);
740 static void test_process_vertices(void)
742 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
743 IDirect3DViewport3
*viewport
;
744 D3DVERTEXBUFFERDESC vb_desc
;
745 IDirect3DDevice3
*device
;
746 struct vec3
*src_data
;
747 struct vec4
*dst_data
;
754 static D3DMATRIX identity
=
756 1.0f
, 0.0f
, 0.0f
, 0.0f
,
757 0.0f
, 1.0f
, 0.0f
, 0.0f
,
758 0.0f
, 0.0f
, 1.0f
, 0.0f
,
759 0.0f
, 0.0f
, 0.0f
, 1.0f
,
761 static D3DMATRIX projection
=
763 1.0f
, 0.0f
, 0.0f
, 0.0f
,
764 0.0f
, 1.0f
, 0.0f
, 0.0f
,
765 0.0f
, 0.0f
, 1.0f
, 0.0f
,
766 6.0f
, 7.0f
, 8.0f
, 1.0f
,
769 window
= create_window();
770 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
772 skip("Failed to create a 3D device, skipping test.\n");
773 DestroyWindow(window
);
777 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
778 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
780 memset(&vb_desc
, 0, sizeof(vb_desc
));
781 vb_desc
.dwSize
= sizeof(vb_desc
);
782 vb_desc
.dwFVF
= D3DFVF_XYZ
;
783 vb_desc
.dwNumVertices
= 3;
784 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
785 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#lx.\n", hr
);
787 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
788 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#lx.\n", hr
);
789 src_data
[0].x
= -1.0f
;
790 src_data
[0].y
= -1.0f
;
791 src_data
[0].z
= -1.0f
;
792 src_data
[1].x
= 0.0f
;
793 src_data
[1].y
= 0.0f
;
794 src_data
[1].z
= 0.0f
;
795 src_data
[2].x
= 1.0f
;
796 src_data
[2].y
= 1.0f
;
797 src_data
[2].z
= 1.0f
;
798 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
799 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#lx.\n", hr
);
801 memset(&vb_desc
, 0, sizeof(vb_desc
));
802 vb_desc
.dwSize
= sizeof(vb_desc
);
803 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
804 vb_desc
.dwNumVertices
= 3;
805 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
806 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#lx.\n", hr
);
808 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
809 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
810 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
811 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
812 vp2
.dwSize
= sizeof(vp2
);
819 vp2
.dvClipWidth
= 4.0f
;
820 vp2
.dvClipHeight
= 5.0f
;
823 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
824 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
825 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
826 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
828 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
829 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#lx.\n", hr
);
830 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
831 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#lx.\n", hr
);
832 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
833 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#lx.\n", hr
);
835 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
836 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#lx.\n", hr
);
838 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
839 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#lx.\n", hr
);
840 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
841 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
842 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
843 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
844 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
845 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
846 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
847 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
848 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
849 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
850 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#lx.\n", hr
);
852 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
853 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#lx.\n", hr
);
855 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
856 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#lx.\n", hr
);
858 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
859 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#lx.\n", hr
);
860 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+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], +1.100e+2f
, -1.400e+2f
, +2.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.350e+2f
, -1.800e+2f
, +2.200e+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 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
870 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#lx.\n", hr
);
872 vp2
.dwSize
= sizeof(vp2
);
879 vp2
.dvClipWidth
= 2.0f
;
880 vp2
.dvClipHeight
= 4.0f
;
883 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
884 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
886 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
887 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#lx.\n", hr
);
889 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
890 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#lx.\n", hr
);
891 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
892 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
893 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
894 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
895 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
896 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
897 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
898 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
899 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
900 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
901 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#lx.\n", hr
);
903 vp1
.dwSize
= sizeof(vp1
);
914 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
915 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
917 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
918 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#lx.\n", hr
);
920 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
921 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#lx.\n", hr
);
922 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
923 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
924 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
925 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
926 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
927 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
928 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
929 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
930 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
931 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
932 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#lx.\n", hr
);
934 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
935 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
937 IDirect3DVertexBuffer_Release(dst_vb
);
938 IDirect3DVertexBuffer_Release(src_vb
);
939 IDirect3DViewport3_Release(viewport
);
940 IDirect3D3_Release(d3d3
);
941 IDirect3DDevice3_Release(device
);
942 DestroyWindow(window
);
945 static void test_coop_level_create_device_window(void)
947 HWND focus_window
, device_window
;
951 focus_window
= create_window();
952 ddraw
= create_ddraw();
953 ok(!!ddraw
, "Failed to create a ddraw object.\n");
955 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
956 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
957 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
958 ok(!device_window
, "Unexpected device window found.\n");
959 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
960 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
961 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
962 ok(!device_window
, "Unexpected device window found.\n");
963 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
964 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
965 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
966 ok(!device_window
, "Unexpected device window found.\n");
967 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
968 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
969 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
970 ok(!device_window
, "Unexpected device window found.\n");
971 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
972 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#lx.\n", hr
);
973 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
974 ok(!device_window
, "Unexpected device window found.\n");
976 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
977 if (broken(hr
== DDERR_INVALIDPARAMS
))
979 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
980 IDirectDraw4_Release(ddraw
);
981 DestroyWindow(focus_window
);
985 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
986 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
987 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
988 ok(!device_window
, "Unexpected device window found.\n");
989 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
990 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
991 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
992 ok(!device_window
, "Unexpected device window found.\n");
994 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
995 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
996 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
997 ok(!device_window
, "Unexpected device window found.\n");
998 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
999 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1000 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#lx.\n", hr
);
1001 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1002 ok(!!device_window
, "Device window not found.\n");
1004 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1005 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1006 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1007 ok(!device_window
, "Unexpected device window found.\n");
1008 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
1009 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1010 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1011 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1012 ok(!!device_window
, "Device window not found.\n");
1014 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1015 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1016 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1017 ok(!device_window
, "Unexpected device window found.\n");
1018 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1019 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#lx.\n", hr
);
1020 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1021 ok(!device_window
, "Unexpected device window found.\n");
1022 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
1023 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1024 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1025 ok(!device_window
, "Unexpected device window found.\n");
1026 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1027 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1028 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
1029 ok(!!device_window
, "Device window not found.\n");
1031 IDirectDraw4_Release(ddraw
);
1032 DestroyWindow(focus_window
);
1035 static void test_clipper_blt(void)
1037 IDirectDrawSurface4
*src_surface
, *dst_surface
;
1038 unsigned int color
, i
, j
, x
, y
;
1039 RECT client_rect
, src_rect
;
1040 IDirectDrawClipper
*clipper
;
1041 DDSURFACEDESC2 surface_desc
;
1042 IDirectDraw4
*ddraw
;
1052 static const DWORD src_data
[] =
1054 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1055 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1056 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1058 static const unsigned int expected1
[] =
1060 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1061 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1062 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1063 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1065 /* Nvidia on Windows seems to have an off-by-one error
1066 * when processing source rectangles. Our left = 1 and
1067 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
1068 * read as well, but only for the edge pixels on the
1069 * output image. The bug happens on the y axis as well,
1070 * but we only read one row there, and all source rows
1071 * contain the same data. This bug is not dependent on
1072 * the presence of a clipper. */
1073 static const D3DCOLOR expected1_broken
[] =
1075 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1076 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1077 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
1078 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
1080 static const unsigned int expected2
[] =
1082 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1083 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1084 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1085 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1088 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1089 10, 10, 640, 480, 0, 0, 0, 0);
1090 ShowWindow(window
, SW_SHOW
);
1091 ddraw
= create_ddraw();
1092 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1094 ret
= GetClientRect(window
, &client_rect
);
1095 ok(ret
, "Failed to get client rect.\n");
1096 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
1097 ok(ret
, "Failed to map client rect.\n");
1099 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1100 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1102 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
1103 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
1104 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1105 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1106 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1107 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1108 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1109 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1110 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1111 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
1112 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#lx.\n", hr
);
1113 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#lx.\n", rgn_data
->rdh
.dwSize
);
1114 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#lx.\n", rgn_data
->rdh
.iType
);
1115 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %lu.\n", rgn_data
->rdh
.nCount
);
1116 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
1117 "Got unexpected bounding rect %s, expected %s.\n",
1118 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
1119 HeapFree(GetProcessHeap(), 0, rgn_data
);
1121 r1
= CreateRectRgn(0, 0, 320, 240);
1122 ok(!!r1
, "Failed to create region.\n");
1123 r2
= CreateRectRgn(320, 240, 640, 480);
1124 ok(!!r2
, "Failed to create region.\n");
1125 CombineRgn(r1
, r1
, r2
, RGN_OR
);
1126 ret
= GetRegionData(r1
, 0, NULL
);
1127 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1128 ret
= GetRegionData(r1
, ret
, rgn_data
);
1129 ok(!!ret
, "Failed to get region data.\n");
1134 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1135 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#lx.\n", hr
);
1136 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1137 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1138 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1139 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1141 HeapFree(GetProcessHeap(), 0, rgn_data
);
1143 memset(&surface_desc
, 0, sizeof(surface_desc
));
1144 surface_desc
.dwSize
= sizeof(surface_desc
);
1145 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1146 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1147 surface_desc
.dwWidth
= 640;
1148 surface_desc
.dwHeight
= 480;
1149 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1150 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1151 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1152 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1153 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1154 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1156 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
1157 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
1158 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
1159 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
1161 memset(&fx
, 0, sizeof(fx
));
1162 fx
.dwSize
= sizeof(fx
);
1163 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1164 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
1165 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1166 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1168 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
1169 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
1170 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %lu.\n", U1(surface_desc
).lPitch
);
1171 ptr
= surface_desc
.lpSurface
;
1172 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
1173 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
1174 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
1175 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
1176 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
1178 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
1179 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
1181 SetRect(&src_rect
, 1, 1, 5, 2);
1182 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
1183 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
1184 for (i
= 0; i
< 4; ++i
)
1186 for (j
= 0; j
< 4; ++j
)
1188 x
= 80 * ((2 * j
) + 1);
1189 y
= 60 * ((2 * i
) + 1);
1190 color
= get_surface_color(dst_surface
, x
, y
);
1191 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1192 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1193 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1197 U5(fx
).dwFillColor
= 0xff0000ff;
1198 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1199 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1200 for (i
= 0; i
< 4; ++i
)
1202 for (j
= 0; j
< 4; ++j
)
1204 x
= 80 * ((2 * j
) + 1);
1205 y
= 60 * ((2 * i
) + 1);
1206 color
= get_surface_color(dst_surface
, x
, y
);
1207 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1208 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1212 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1213 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#lx.\n", hr
);
1215 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1216 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1217 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1218 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1219 DestroyWindow(window
);
1220 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1221 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
1222 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1223 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1224 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1225 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1226 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1227 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1228 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1229 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1230 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1231 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1233 IDirectDrawSurface4_Release(dst_surface
);
1234 IDirectDrawSurface4_Release(src_surface
);
1235 refcount
= IDirectDrawClipper_Release(clipper
);
1236 ok(!refcount
, "Clipper has %lu references left.\n", refcount
);
1237 IDirectDraw4_Release(ddraw
);
1240 static void test_coop_level_d3d_state(void)
1242 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1243 IDirectDrawSurface4
*rt
, *surface
;
1244 IDirect3DViewport3
*viewport
;
1245 IDirect3DDevice3
*device
;
1246 IDirectDraw4
*ddraw
;
1247 DDSURFACEDESC2 lock
;
1256 struct vec3 position
;
1261 {{-1.0f
, -1.0f
, 0.0f
}, 0x800000ff},
1262 {{-1.0f
, 1.0f
, 0.0f
}, 0x800000ff},
1263 {{ 1.0f
, -1.0f
, 0.0f
}, 0x800000ff},
1264 {{ 1.0f
, 1.0f
, 0.0f
}, 0x800000ff},
1267 window
= create_window();
1268 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1270 skip("Failed to create a 3D device, skipping test.\n");
1271 DestroyWindow(window
);
1275 viewport
= create_viewport(device
, 0, 0, 640, 480);
1277 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1278 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1279 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
1280 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1282 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1283 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1284 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1285 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1286 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1287 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1288 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1289 ok(!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1290 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1291 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1292 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1293 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1294 color
= get_surface_color(rt
, 320, 240);
1295 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1297 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1298 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1299 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1300 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1301 IDirect3D3_Release(d3d
);
1303 if (ddraw_is_warp(ddraw
))
1305 /* ddraw4 occasionally crashes in GetRenderTarget. */
1306 win_skip("Skipping test that crashes WARP occasionally.\n");
1310 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1311 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1312 hr
= IDirectDrawSurface4_IsLost(rt
);
1313 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1315 memset(&lock
, 0, sizeof(lock
));
1316 lock
.dwSize
= sizeof(lock
);
1317 lock
.lpSurface
= (void *)0xdeadbeef;
1318 hr
= IDirectDrawSurface4_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1319 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1320 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1322 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
1323 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1325 hr
= IDirectDrawSurface4_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1326 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1327 hr
= IDirectDrawSurface4_Unlock(rt
, NULL
);
1328 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1330 hr
= IDirect3DDevice3_GetRenderTarget(device
, &surface
);
1331 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1332 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1333 IDirectDrawSurface4_Release(surface
);
1334 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1335 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1336 ok(!!value
, "Got unexpected z-enable state %#lx.\n", value
);
1337 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1338 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1339 ok(!!value
, "Got unexpected alpha blend enable state %#lx.\n", value
);
1340 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff00ff00, 1.0f
, 0);
1341 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1342 color
= get_surface_color(rt
, 320, 240);
1343 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1345 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1346 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1347 hr
= IDirect3DDevice3_BeginScene(device
);
1348 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1349 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
1350 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
1351 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1352 hr
= IDirect3DDevice3_EndScene(device
);
1353 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1354 color
= get_surface_color(rt
, 320, 240);
1355 ok(compare_color(color
, 0x0000ff80, 1)
1356 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
1357 "Got unexpected color 0x%08x.\n", color
);
1360 destroy_viewport(device
, viewport
);
1361 IDirectDrawSurface4_Release(rt
);
1362 IDirect3DDevice3_Release(device
);
1363 IDirectDraw4_Release(ddraw
);
1364 DestroyWindow(window
);
1367 static void test_surface_interface_mismatch(void)
1369 IDirectDraw4
*ddraw
= NULL
;
1370 IDirect3D3
*d3d
= NULL
;
1371 IDirectDrawSurface4
*surface
= NULL
, *ds
;
1372 IDirectDrawSurface3
*surface3
= NULL
;
1373 IDirect3DDevice3
*device
= NULL
;
1374 IDirect3DViewport3
*viewport
= NULL
;
1375 DDSURFACEDESC2 surface_desc
;
1376 DDPIXELFORMAT z_fmt
;
1381 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1383 window
= create_window();
1384 ddraw
= create_ddraw();
1385 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1386 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1387 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1389 memset(&surface_desc
, 0, sizeof(surface_desc
));
1390 surface_desc
.dwSize
= sizeof(surface_desc
);
1391 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1392 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1393 surface_desc
.dwWidth
= 640;
1394 surface_desc
.dwHeight
= 480;
1396 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1397 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
1399 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1400 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#lx.\n", hr
);
1402 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
1404 skip("D3D interface is not available, skipping test.\n");
1408 memset(&z_fmt
, 0, sizeof(z_fmt
));
1409 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
1410 if (FAILED(hr
) || !z_fmt
.dwSize
)
1412 skip("No depth buffer formats available, skipping test.\n");
1416 memset(&surface_desc
, 0, sizeof(surface_desc
));
1417 surface_desc
.dwSize
= sizeof(surface_desc
);
1418 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
1419 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1420 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
1421 surface_desc
.dwWidth
= 640;
1422 surface_desc
.dwHeight
= 480;
1423 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1424 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
1428 /* Using a different surface interface version still works */
1429 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1430 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
1431 refcount
= IDirectDrawSurface4_Release(ds
);
1432 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
1437 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
1438 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1442 viewport
= create_viewport(device
, 0, 0, 640, 480);
1444 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1445 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
1446 color
= get_surface_color(surface
, 320, 240);
1447 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1451 destroy_viewport(device
, viewport
);
1452 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1453 if (surface
) IDirectDrawSurface4_Release(surface
);
1454 if (device
) IDirect3DDevice3_Release(device
);
1455 if (d3d
) IDirect3D3_Release(d3d
);
1456 if (ddraw
) IDirectDraw4_Release(ddraw
);
1457 DestroyWindow(window
);
1460 static void test_coop_level_threaded(void)
1462 struct create_window_thread_param p
;
1463 IDirectDraw4
*ddraw
;
1466 ddraw
= create_ddraw();
1467 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1468 create_window_thread(&p
);
1470 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1471 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1473 destroy_window_thread(&p
);
1474 IDirectDraw4_Release(ddraw
);
1477 static void test_depth_blit(const GUID
*device_guid
)
1486 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1487 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1488 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1489 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1491 static const unsigned int expected_colors
[4][4] =
1493 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1494 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1495 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1496 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1498 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1500 IDirect3DDevice3
*device
;
1501 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1502 IDirect3DViewport3
*viewport
;
1503 unsigned int color
, i
, j
;
1504 RECT src_rect
, dst_rect
;
1507 IDirectDraw4
*ddraw
;
1512 window
= create_window();
1513 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
1515 skip("Failed to create a 3D device, skipping test.\n");
1516 DestroyWindow(window
);
1520 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1521 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1522 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1523 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1524 IDirect3D3_Release(d3d
);
1526 ds1
= get_depth_stencil(device
);
1528 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1529 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1530 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1531 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1532 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1533 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1534 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1535 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1536 if (is_software_device_type(device_guid
))
1537 ddsd_new
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1538 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1539 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1540 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1541 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1542 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1543 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1544 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#lx.\n", hr
);
1545 IDirectDraw4_Release(ddraw
);
1547 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1548 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1549 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
1551 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1552 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#lx.\n", hr
);
1553 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1554 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#lx.\n", hr
);
1556 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1557 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1558 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1559 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#lx.\n", hr
);
1562 SetRect(&src_rect
, 0, 0, 320, 240);
1563 SetRect(&dst_rect
, 0, 0, 320, 240);
1564 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1565 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1566 /* Different locations. */
1567 SetRect(&src_rect
, 0, 0, 320, 240);
1568 SetRect(&dst_rect
, 320, 240, 640, 480);
1569 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1570 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1572 SetRect(&src_rect
, 0, 0, 320, 240);
1573 SetRect(&dst_rect
, 0, 0, 640, 480);
1574 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1575 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1577 SetRect(&src_rect
, 0, 480, 640, 0);
1578 SetRect(&dst_rect
, 0, 0, 640, 480);
1579 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1580 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1581 SetRect(&src_rect
, 0, 0, 640, 480);
1582 SetRect(&dst_rect
, 0, 480, 640, 0);
1583 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1584 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
1585 /* Full, explicit. */
1586 SetRect(&src_rect
, 0, 0, 640, 480);
1587 SetRect(&dst_rect
, 0, 0, 640, 480);
1588 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1589 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1590 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1592 /* Depth blit inside a BeginScene / EndScene pair */
1593 hr
= IDirect3DDevice3_BeginScene(device
);
1594 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#lx.\n", hr
);
1595 /* From the current depth stencil */
1596 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1597 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1598 /* To the current depth stencil */
1599 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1600 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1601 /* Between unbound surfaces */
1602 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1603 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1604 hr
= IDirect3DDevice3_EndScene(device
);
1605 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#lx.\n", hr
);
1607 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1608 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1609 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1610 * a reliable result(z = 0.0) */
1611 memset(&fx
, 0, sizeof(fx
));
1612 fx
.dwSize
= sizeof(fx
);
1613 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1614 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1616 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1617 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1619 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1620 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1622 color
= get_surface_color(rt
, 80, 60);
1623 /* For some reason clears and colour fill blits randomly fail with software render target. */
1624 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
1625 "Got unexpected colour 0x%08x.\n", color
);
1628 fill_surface(rt
, 0xffff0000);
1630 color
= get_surface_color(rt
, 80, 60);
1631 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
1634 SetRect(&dst_rect
, 0, 0, 320, 240);
1635 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1636 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1637 IDirectDrawSurface4_Release(ds3
);
1638 IDirectDrawSurface4_Release(ds2
);
1639 IDirectDrawSurface4_Release(ds1
);
1641 hr
= IDirect3DDevice3_BeginScene(device
);
1642 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1643 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1645 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1646 hr
= IDirect3DDevice3_EndScene(device
);
1647 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1649 for (i
= 0; i
< 4; ++i
)
1651 for (j
= 0; j
< 4; ++j
)
1653 unsigned int x
= 80 * ((2 * j
) + 1);
1654 unsigned int y
= 60 * ((2 * i
) + 1);
1655 color
= get_surface_color(rt
, x
, y
);
1656 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1657 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1660 IDirectDrawSurface4_Release(rt
);
1662 destroy_viewport(device
, viewport
);
1663 IDirect3DDevice3_Release(device
);
1664 DestroyWindow(window
);
1667 static void test_texture_load_ckey(void)
1669 IDirectDraw4
*ddraw
;
1670 IDirectDrawSurface4
*src
;
1671 IDirectDrawSurface4
*dst
;
1672 IDirect3DTexture2
*src_tex
;
1673 IDirect3DTexture2
*dst_tex
;
1674 DDSURFACEDESC2 ddsd
;
1678 ddraw
= create_ddraw();
1679 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1680 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1681 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1683 memset(&ddsd
, 0, sizeof(ddsd
));
1684 ddsd
.dwSize
= sizeof(ddsd
);
1685 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1686 ddsd
.dwHeight
= 128;
1688 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1689 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1690 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#lx.\n", hr
);
1691 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1692 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1693 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#lx.\n", hr
);
1695 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1696 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#lx.\n", hr
);
1699 /* 64 bit ddraw does not support d3d */
1700 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1701 IDirectDrawSurface4_Release(dst
);
1702 IDirectDrawSurface4_Release(src
);
1703 IDirectDraw4_Release(ddraw
);
1706 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1707 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#lx.\n", hr
);
1709 /* No surface has a color key */
1710 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1711 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1712 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1713 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1714 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1715 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1716 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1718 /* Source surface has a color key */
1719 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1720 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1721 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1722 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1723 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1724 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1725 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1726 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1727 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1729 /* Both surfaces have a color key: Dest ckey is overwritten */
1730 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1731 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1732 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1733 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1734 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1735 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1736 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1737 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1738 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1740 /* Only the destination has a color key: It is not deleted */
1741 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1742 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
1743 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1744 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
1745 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1746 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1747 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1748 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1749 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
1750 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
1752 IDirect3DTexture2_Release(dst_tex
);
1753 IDirect3DTexture2_Release(src_tex
);
1754 IDirectDrawSurface4_Release(dst
);
1755 IDirectDrawSurface4_Release(src
);
1756 IDirectDraw4_Release(ddraw
);
1759 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1761 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1762 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1763 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1764 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1767 static ULONG
get_refcount(IUnknown
*test_iface
)
1769 IUnknown_AddRef(test_iface
);
1770 return IUnknown_Release(test_iface
);
1773 static void test_viewport_object(void)
1775 IDirect3DViewport3
*viewport3
, *another_vp
, *test_vp
;
1776 IDirectDrawGammaControl
*gamma
;
1777 IDirect3DViewport2
*viewport2
;
1778 IDirect3DViewport
*viewport
;
1779 IDirect3DDevice3
*device
;
1780 HRESULT hr
, old_d3d_ref
;
1781 IDirectDraw4
*ddraw
;
1795 window
= create_window();
1796 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1798 skip("Failed to create a 3D device, skipping test.\n");
1799 DestroyWindow(window
);
1802 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1803 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1804 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1805 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1806 old_d3d_ref
= get_refcount((IUnknown
*) d3d
);
1808 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1809 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1810 ref
= get_refcount((IUnknown
*)viewport3
);
1811 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1812 ref
= get_refcount((IUnknown
*)d3d
);
1813 ok(ref
== old_d3d_ref
, "Got unexpected refcount %lu.\n", ref
);
1815 memset(&desc
, 0, sizeof(desc
));
1816 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1817 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1818 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1819 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1820 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1821 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1822 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1823 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1824 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1825 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1826 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1827 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %lu.\n", desc
.vp1
.dwSize
);
1828 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &desc
.vp2
);
1829 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1830 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %lu.\n", desc
.vp2
.dwSize
);
1831 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1832 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &desc
.vp2
);
1833 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1835 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1836 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1837 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
1838 ok(!gamma
, "Interface not set to NULL by failed QI call: %p.\n", gamma
);
1839 /* NULL iid: Segfaults */
1841 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1842 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1843 ref
= get_refcount((IUnknown
*)viewport
);
1844 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1845 ref
= get_refcount((IUnknown
*)viewport3
);
1846 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1847 IDirect3DViewport_Release(viewport
);
1850 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1851 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1852 ref
= get_refcount((IUnknown
*)viewport2
);
1853 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1854 ref
= get_refcount((IUnknown
*)viewport3
);
1855 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1856 IDirect3DViewport3_Release(viewport2
);
1858 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IUnknown
, (void **)&unknown
);
1859 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1860 ref
= get_refcount((IUnknown
*)viewport3
);
1861 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1862 ref
= get_refcount(unknown
);
1863 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1864 IUnknown_Release(unknown
);
1866 hr
= IDirect3DDevice3_DeleteViewport(device
, NULL
);
1867 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1868 hr
= IDirect3DDevice3_GetCurrentViewport(device
, NULL
);
1869 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1871 hr
= IDirect3D3_CreateViewport(d3d
, &another_vp
, NULL
);
1872 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1874 /* Setting a viewport not in the viewport list fails */
1875 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1876 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1878 /* AddViewport(NULL): Segfault */
1879 hr
= IDirect3DDevice3_AddViewport(device
, viewport3
);
1880 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1881 ref
= get_refcount((IUnknown
*) viewport3
);
1882 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1883 hr
= IDirect3DDevice3_AddViewport(device
, another_vp
);
1884 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1885 ref
= get_refcount((IUnknown
*) another_vp
);
1886 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1888 test_vp
= (IDirect3DViewport3
*) 0xbaadc0de;
1889 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1890 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1891 ok(test_vp
== (IDirect3DViewport3
*) 0xbaadc0de, "Got unexpected pointer %p.\n", test_vp
);
1893 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1894 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1895 ref
= get_refcount((IUnknown
*) viewport3
);
1896 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1897 ref
= get_refcount((IUnknown
*) device
);
1898 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1901 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1902 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1903 ok(test_vp
== viewport3
, "Got unexpected viewport %p.\n", test_vp
);
1904 ref
= get_refcount((IUnknown
*) viewport3
);
1905 ok(ref
== 4, "Got unexpected refcount %lu.\n", ref
);
1907 IDirect3DViewport3_Release(test_vp
);
1909 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1911 /* Cannot set the viewport to NULL */
1912 hr
= IDirect3DDevice3_SetCurrentViewport(device
, NULL
);
1913 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1915 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1916 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1917 ok(test_vp
== viewport3
, "Got unexpected viewport %p.\n", test_vp
);
1919 IDirect3DViewport3_Release(test_vp
);
1921 /* SetCurrentViewport properly releases the old viewport's reference */
1922 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1923 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1924 ref
= get_refcount((IUnknown
*) viewport3
);
1925 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1926 ref
= get_refcount((IUnknown
*) another_vp
);
1927 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1929 /* Unlike device2::DeleteViewport, device3::DeleteViewport releases the
1930 * reference held by SetCurrentViewport */
1931 hr
= IDirect3DDevice3_DeleteViewport(device
, another_vp
);
1932 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1933 ref
= get_refcount((IUnknown
*) another_vp
);
1934 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1936 /* GetCurrentViewport still fails */
1938 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1939 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
1940 ok(!test_vp
, "Got unexpected viewport %p.\n", test_vp
);
1942 /* Setting a different viewport doesn't have any surprises now */
1943 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1944 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1945 ref
= get_refcount((IUnknown
*) viewport3
);
1946 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1947 ref
= get_refcount((IUnknown
*) another_vp
);
1948 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1950 memset(&vp
, 0, sizeof(vp
));
1951 memset(&vp
, 0, sizeof(vp2
));
1952 vp
.dwSize
= vp2
.dwSize
= 0;
1953 vp
.dwX
= vp2
.dwX
= 0;
1954 vp
.dwY
= vp2
.dwY
= 0;
1955 vp
.dwWidth
= vp2
.dwWidth
= 640;
1956 vp
.dwHeight
= vp2
.dwHeight
= 480;
1957 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1958 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1959 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1960 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1963 vp2
.dvClipX
= -1.0f
;
1965 vp2
.dvClipWidth
= 2.0f
;
1966 vp2
.dvClipHeight
= 2.0f
;
1967 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1968 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1969 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1970 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1972 vp
.dwSize
= sizeof(vp
);
1973 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1974 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1975 vp2
.dwSize
= sizeof(vp2
);
1976 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1977 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1979 vp2
.dwSize
= sizeof(vp2
);
1982 vp2
.dwWidth
= 640 - vp2
.dwX
;
1983 vp2
.dwHeight
= 480 - vp2
.dwY
;
1985 vp2
.dvClipY
= -1.75f
;
1986 vp2
.dvClipWidth
= 2.5f
;
1987 vp2
.dvClipHeight
= -1.5f
;
1990 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1991 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1993 memset(&vp
, 0xff, sizeof(vp
));
1994 vp
.dwSize
= sizeof(vp
);
1995 hr
= IDirect3DViewport3_GetViewport(viewport3
, &vp
);
1996 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1997 ok(vp
.dvMaxX
== 4.5f
&& vp
.dvMaxY
== -1.75f
&& vp
.dvScaleX
== 192.0f
1998 && vp
.dvScaleY
== -240.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
1999 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
2000 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
2002 vp2
.dvClipX
= -1.5f
;
2003 vp2
.dvClipY
= 1.75f
;
2004 vp2
.dvClipWidth
= -1.5f
;
2005 vp2
.dvClipHeight
= 2.0f
;
2009 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
2010 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2012 memset(&vp
, 0xff, sizeof(vp
));
2013 vp
.dwSize
= sizeof(vp
);
2014 hr
= IDirect3DViewport3_GetViewport(viewport3
, &vp
);
2015 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2016 ok(vp
.dvMaxX
== -3.0f
&& vp
.dvMaxY
== 1.75f
&& vp
.dvScaleX
== -320.0f
2017 && vp
.dvScaleY
== 180.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
2018 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
2019 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
2021 vp
.dwSize
= sizeof(vp
);
2024 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
2025 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2027 memset(&vp2
, 0xff, sizeof(vp2
));
2028 vp2
.dwSize
= sizeof(vp2
);
2029 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &vp2
);
2030 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2031 ok(vp2
.dvClipX
== 0.75f
&& vp2
.dvClipY
== 1.0f
&& vp2
.dvClipWidth
== -1.5f
2032 && vp2
.dvClipHeight
== 2.0f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
2033 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
2034 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
2038 vp
.dvScaleX
= 192.0f
;
2039 vp
.dvScaleY
= -240.0f
;
2043 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
2044 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2046 memset(&vp2
, 0xff, sizeof(vp2
));
2047 vp2
.dwSize
= sizeof(vp2
);
2048 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &vp2
);
2049 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2050 ok(vp2
.dvClipX
== -1.25f
&& vp2
.dvClipY
== -0.75f
&& vp2
.dvClipWidth
== 2.5f
2051 && vp2
.dvClipHeight
== -1.5f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
2052 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
2053 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
2055 /* Destroying the device removes the viewport and releases the reference */
2056 IDirect3DDevice3_Release(device
);
2057 ref
= get_refcount((IUnknown
*) viewport3
);
2058 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
2060 memset(&vp2
, 0xff, sizeof(vp2
));
2061 vp2
.dwSize
= sizeof(vp2
);
2062 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &vp2
);
2063 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2064 ok(vp2
.dvClipX
== -1.25f
&& vp2
.dvClipY
== -0.75f
&& vp2
.dvClipWidth
== 2.5f
2065 && vp2
.dvClipHeight
== -1.5f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
2066 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
2067 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
2069 vp
.dwSize
= sizeof(vp
);
2070 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
2071 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
2072 vp2
.dwSize
= sizeof(vp2
);
2073 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
2074 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
2076 ref
= IDirect3DViewport3_Release(another_vp
);
2077 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
2078 ref
= IDirect3DViewport3_Release(viewport3
);
2079 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
2080 IDirect3D3_Release(d3d
);
2081 DestroyWindow(window
);
2082 IDirectDraw4_Release(ddraw
);
2085 static void test_zenable(const GUID
*device_guid
)
2087 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2090 struct vec4 position
;
2095 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
2096 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
2097 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
2098 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
2100 unsigned int color
, x
, y
, i
, j
;
2101 IDirect3DViewport3
*viewport
;
2102 IDirect3DDevice3
*device
;
2103 IDirectDrawSurface4
*rt
;
2107 window
= create_window();
2108 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
2110 skip("Failed to create a 3D device, skipping test.\n");
2111 DestroyWindow(window
);
2115 viewport
= create_viewport(device
, 0, 0, 640, 480);
2116 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
2117 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2119 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
2120 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2122 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
2123 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2125 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
2126 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2128 color
= get_surface_color(rt
, 80, 60);
2129 /* For some reason clears and colour fill blits randomly fail with software render target. */
2130 ok(color
== 0x00ff0000 || broken(is_software_device_type(device_guid
) && !color
),
2131 "Got unexpected colour 0x%08x.\n", color
);
2134 fill_surface(rt
, 0xffff0000);
2136 color
= get_surface_color(rt
, 80, 60);
2137 ok(color
== 0x00ff0000, "Got unexpected colour 0x%08x.\n", color
);
2140 hr
= IDirect3DDevice3_BeginScene(device
);
2141 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2142 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
2143 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2144 hr
= IDirect3DDevice3_EndScene(device
);
2145 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2147 for (i
= 0; i
< 4; ++i
)
2149 for (j
= 0; j
< 4; ++j
)
2151 x
= 80 * ((2 * j
) + 1);
2152 y
= 60 * ((2 * i
) + 1);
2153 color
= get_surface_color(rt
, x
, y
);
2154 ok(compare_color(color
, 0x0000ff00, 1),
2155 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
2158 IDirectDrawSurface4_Release(rt
);
2160 destroy_viewport(device
, viewport
);
2161 IDirect3DDevice3_Release(device
);
2162 DestroyWindow(window
);
2165 static void test_ck_rgba(const GUID
*device_guid
)
2167 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2170 struct vec4 position
;
2171 struct vec2 texcoord
;
2175 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
2176 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
2177 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
2178 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
2179 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
2180 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
2181 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
2182 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
2186 D3DCOLOR fill_color
;
2189 unsigned int result1
, result1_broken
;
2190 unsigned int result2
, result2_broken
;
2194 /* r200 on Windows doesn't check the alpha component when applying the color
2195 * key, so the key matches on every texel. */
2196 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
2197 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
2198 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
2199 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
2200 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
2201 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
2202 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
2203 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
2206 IDirectDrawSurface4
*surface
;
2207 IDirect3DViewport3
*viewport
;
2208 DDSURFACEDESC2 surface_desc
;
2209 IDirect3DTexture2
*texture
;
2210 IDirect3DDevice3
*device
;
2211 IDirectDrawSurface4
*rt
;
2212 unsigned int color
, i
;
2213 IDirectDraw4
*ddraw
;
2219 window
= create_window();
2220 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
2222 skip("Failed to create a 3D device, skipping test.\n");
2223 DestroyWindow(window
);
2227 viewport
= create_viewport(device
, 0, 0, 640, 480);
2228 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
2229 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2231 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2232 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2233 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2234 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2235 IDirect3D3_Release(d3d
);
2237 memset(&surface_desc
, 0, sizeof(surface_desc
));
2238 surface_desc
.dwSize
= sizeof(surface_desc
);
2239 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2240 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2241 if (is_software_device_type(device_guid
))
2242 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
2243 surface_desc
.dwWidth
= 256;
2244 surface_desc
.dwHeight
= 256;
2245 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
2246 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
2247 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
2248 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2249 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2250 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2251 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
2252 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
2253 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
2254 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2255 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2256 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2257 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2259 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
2260 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2261 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
2262 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2263 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
2264 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2266 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
2267 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2269 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2271 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
2272 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2273 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
2274 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2276 memset(&fx
, 0, sizeof(fx
));
2277 fx
.dwSize
= sizeof(fx
);
2278 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
2279 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2280 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2282 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
2283 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
2284 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2285 if (is_software_device_type(device_guid
))
2286 fill_surface(rt
, 0xffff0000);
2287 hr
= IDirect3DDevice3_BeginScene(device
);
2288 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2289 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2290 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2291 hr
= IDirect3DDevice3_EndScene(device
);
2292 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2294 color
= get_surface_color(rt
, 320, 240);
2295 ok(compare_color(color
, tests
[i
].result1
, 2) || compare_color(color
, tests
[i
].result1_broken
, 1),
2296 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2297 tests
[i
].result1
, i
, color
);
2299 U5(fx
).dwFillColor
= 0xff0000ff;
2300 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2301 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
2303 hr
= IDirect3DDevice3_BeginScene(device
);
2304 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2305 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
2306 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2307 hr
= IDirect3DDevice3_EndScene(device
);
2308 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2310 /* This tests that fragments that are masked out by the color key are
2311 * discarded, instead of just fully transparent. */
2312 color
= get_surface_color(rt
, 320, 240);
2313 ok(compare_color(color
, tests
[i
].result2
, 2) || compare_color(color
, tests
[i
].result2_broken
, 1),
2314 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2315 tests
[i
].result2
, i
, color
);
2318 IDirectDrawSurface4_Release(rt
);
2319 IDirect3DTexture2_Release(texture
);
2320 IDirectDrawSurface4_Release(surface
);
2321 destroy_viewport(device
, viewport
);
2322 IDirectDraw4_Release(ddraw
);
2323 IDirect3DDevice3_Release(device
);
2324 DestroyWindow(window
);
2327 static void test_ck_default(void)
2329 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2332 struct vec4 position
;
2333 struct vec2 texcoord
;
2337 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
2338 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
2339 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
2340 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
2342 IDirectDrawSurface4
*surface
, *rt
;
2343 IDirect3DViewport3
*viewport
;
2344 DDSURFACEDESC2 surface_desc
;
2345 IDirect3DTexture2
*texture
;
2346 IDirect3DDevice3
*device
;
2347 IDirectDraw4
*ddraw
;
2355 window
= create_window();
2356 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2358 skip("Failed to create a 3D device, skipping test.\n");
2359 DestroyWindow(window
);
2363 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2364 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
2365 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2366 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
2367 IDirect3D3_Release(d3d
);
2369 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
2370 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
2372 viewport
= create_viewport(device
, 0, 0, 640, 480);
2373 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
2374 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
2376 memset(&surface_desc
, 0, sizeof(surface_desc
));
2377 surface_desc
.dwSize
= sizeof(surface_desc
);
2378 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2379 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2380 surface_desc
.dwWidth
= 256;
2381 surface_desc
.dwHeight
= 256;
2382 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
2383 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2384 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
2385 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2386 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2387 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2388 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2389 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2390 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2391 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2392 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2393 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
2394 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
2395 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
2397 memset(&fx
, 0, sizeof(fx
));
2398 fx
.dwSize
= sizeof(fx
);
2399 U5(fx
).dwFillColor
= 0x000000ff;
2400 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2401 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
2403 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2404 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2405 hr
= IDirect3DDevice3_BeginScene(device
);
2406 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2407 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2408 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2409 ok(!value
, "Got unexpected color keying state %#lx.\n", value
);
2410 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2411 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2412 hr
= IDirect3DDevice3_EndScene(device
);
2413 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2414 color
= get_surface_color(rt
, 320, 240);
2415 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2417 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2418 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2419 hr
= IDirect3DDevice3_BeginScene(device
);
2420 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2421 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2422 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
2423 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2424 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2425 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2426 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
2427 ok(!!value
, "Got unexpected color keying state %#lx.\n", value
);
2428 hr
= IDirect3DDevice3_EndScene(device
);
2429 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2430 color
= get_surface_color(rt
, 320, 240);
2431 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2433 IDirect3DTexture_Release(texture
);
2434 IDirectDrawSurface4_Release(surface
);
2435 destroy_viewport(device
, viewport
);
2436 IDirectDrawSurface4_Release(rt
);
2437 IDirect3DDevice3_Release(device
);
2438 IDirectDraw4_Release(ddraw
);
2439 DestroyWindow(window
);
2442 static void test_ck_complex(void)
2444 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
2445 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
2446 DDSURFACEDESC2 surface_desc
;
2447 IDirect3DDevice3
*device
;
2448 DDCOLORKEY color_key
;
2449 IDirectDraw4
*ddraw
;
2456 window
= create_window();
2457 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2459 skip("Failed to create a 3D device, skipping test.\n");
2460 DestroyWindow(window
);
2463 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2464 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
2465 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2466 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
2467 IDirect3D3_Release(d3d
);
2469 memset(&surface_desc
, 0, sizeof(surface_desc
));
2470 surface_desc
.dwSize
= sizeof(surface_desc
);
2471 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2472 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2473 surface_desc
.dwWidth
= 128;
2474 surface_desc
.dwHeight
= 128;
2475 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2476 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2478 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2479 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2480 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2481 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2482 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2483 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2484 memset(&color_key
, 0, sizeof(color_key
));
2485 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2486 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2487 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2488 color_key
.dwColorSpaceLowValue
);
2489 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2490 color_key
.dwColorSpaceHighValue
);
2493 IDirectDrawSurface_AddRef(mipmap
);
2494 for (i
= 0; i
< 7; ++i
)
2496 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2497 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
2499 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2500 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2501 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2502 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2503 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2504 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx, i %u.\n", hr
, i
);
2505 memset(&color_key
, 0, sizeof(color_key
));
2506 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2507 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx, i %u.\n", hr
, i
);
2508 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2509 color_key
.dwColorSpaceLowValue
, i
);
2510 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2511 color_key
.dwColorSpaceHighValue
, i
);
2513 IDirectDrawSurface_Release(mipmap
);
2517 memset(&color_key
, 0, sizeof(color_key
));
2518 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2519 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2520 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2521 color_key
.dwColorSpaceLowValue
);
2522 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2523 color_key
.dwColorSpaceHighValue
);
2525 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2526 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
2527 IDirectDrawSurface_Release(mipmap
);
2528 refcount
= IDirectDrawSurface4_Release(surface
);
2529 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2531 memset(&surface_desc
, 0, sizeof(surface_desc
));
2532 surface_desc
.dwSize
= sizeof(surface_desc
);
2533 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2534 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2535 U5(surface_desc
).dwBackBufferCount
= 1;
2536 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2537 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2539 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2540 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2541 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2542 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2543 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2544 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2545 memset(&color_key
, 0, sizeof(color_key
));
2546 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2547 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2548 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2549 color_key
.dwColorSpaceLowValue
);
2550 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2551 color_key
.dwColorSpaceHighValue
);
2553 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
2554 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
2556 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2557 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2558 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2559 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2560 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2561 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2562 memset(&color_key
, 0, sizeof(color_key
));
2563 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2564 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2565 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2566 color_key
.dwColorSpaceLowValue
);
2567 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2568 color_key
.dwColorSpaceHighValue
);
2570 IDirectDrawSurface_Release(tmp
);
2572 refcount
= IDirectDrawSurface4_Release(surface
);
2573 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2574 IDirectDraw4_Release(ddraw
);
2575 refcount
= IDirect3DDevice3_Release(device
);
2576 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2577 DestroyWindow(window
);
2583 REFIID refcount_iid
;
2587 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2588 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2590 ULONG refcount
, expected_refcount
;
2591 IUnknown
*iface1
, *iface2
;
2595 for (i
= 0; i
< entry_count
; ++i
)
2597 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2598 ok(hr
== tests
[i
].hr
, "Got hr %#lx for test \"%s\" %u.\n", hr
, test_name
, i
);
2601 for (j
= 0; j
< entry_count
; ++j
)
2603 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2604 ok(hr
== tests
[j
].hr
, "Got hr %#lx for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2607 expected_refcount
= 0;
2608 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2609 ++expected_refcount
;
2610 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2611 ++expected_refcount
;
2612 refcount
= IUnknown_Release(iface2
);
2613 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
2614 refcount
, test_name
, i
, j
, expected_refcount
);
2618 expected_refcount
= 0;
2619 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2620 ++expected_refcount
;
2621 refcount
= IUnknown_Release(iface1
);
2622 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
2623 refcount
, test_name
, i
, expected_refcount
);
2628 static void test_surface_qi(void)
2630 static const struct qi_test tests
[] =
2632 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface4
, S_OK
},
2633 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface4
, S_OK
},
2634 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2635 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2636 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2637 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2638 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2639 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2640 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2641 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2642 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2643 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2644 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2645 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2646 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2647 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2648 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2649 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2650 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2651 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2652 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2653 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2654 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2655 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2656 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2657 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2658 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2659 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2660 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2661 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2662 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2663 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2664 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2665 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2666 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2667 {NULL
, NULL
, E_INVALIDARG
},
2670 IDirectDrawSurface4
*surface
;
2671 DDSURFACEDESC2 surface_desc
;
2672 IDirect3DDevice3
*device
;
2673 IDirectDraw4
*ddraw
;
2677 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2679 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2683 window
= create_window();
2684 /* Try to create a D3D device to see if the ddraw implementation supports
2685 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2686 * doesn't support e.g. the IDirect3DTexture interfaces. */
2687 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2689 skip("Failed to create a 3D device, skipping test.\n");
2690 DestroyWindow(window
);
2693 IDirect3DDevice_Release(device
);
2694 ddraw
= create_ddraw();
2695 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2696 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2697 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
2699 memset(&surface_desc
, 0, sizeof(surface_desc
));
2700 surface_desc
.dwSize
= sizeof(surface_desc
);
2701 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2702 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2703 surface_desc
.dwWidth
= 512;
2704 surface_desc
.dwHeight
= 512;
2705 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface4
**)0xdeadbeef, NULL
);
2706 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
2707 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2708 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2710 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface4
, tests
, ARRAY_SIZE(tests
));
2712 IDirectDrawSurface4_Release(surface
);
2713 IDirectDraw4_Release(ddraw
);
2714 DestroyWindow(window
);
2717 static void test_device_qi(void)
2719 static const struct qi_test tests
[] =
2721 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2722 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2723 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2724 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2725 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2726 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2727 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2728 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2729 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2730 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2731 {&IID_IDirect3DDevice3
, &IID_IDirect3DDevice3
, S_OK
},
2732 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice3
, S_OK
},
2733 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice3
, S_OK
},
2734 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2735 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2736 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2737 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2738 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2739 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2740 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2741 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2742 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2743 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2744 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2745 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2746 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2747 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2748 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2749 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2750 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2751 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2752 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2753 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2754 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2755 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2756 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2757 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2758 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2759 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2760 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2761 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2762 {&IID_IUnknown
, &IID_IDirect3DDevice3
, S_OK
},
2765 IDirect3DDevice3
*device
;
2768 window
= create_window();
2769 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2771 skip("Failed to create a 3D device, skipping test.\n");
2772 DestroyWindow(window
);
2776 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice3
, tests
, ARRAY_SIZE(tests
));
2778 IDirect3DDevice3_Release(device
);
2779 DestroyWindow(window
);
2782 static void test_wndproc(void)
2784 LONG_PTR proc
, ddraw_proc
;
2785 IDirectDraw4
*ddraw
;
2791 static struct message messages
[] =
2793 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2794 {WM_MOVE
, FALSE
, 0},
2795 {WM_SIZE
, FALSE
, 0},
2796 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2797 {WM_ACTIVATE
, FALSE
, 0},
2798 {WM_SETFOCUS
, FALSE
, 0},
2802 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2803 ddraw
= create_ddraw();
2804 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2806 wc
.lpfnWndProc
= test_proc
;
2807 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2808 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2810 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2811 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2813 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2814 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2815 (LONG_PTR
)test_proc
, proc
);
2816 expect_messages
= messages
;
2817 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2818 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2819 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2820 expect_messages
= NULL
;
2821 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2822 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2823 (LONG_PTR
)test_proc
, proc
);
2824 ref
= IDirectDraw4_Release(ddraw
);
2825 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2826 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2827 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2828 (LONG_PTR
)test_proc
, proc
);
2830 /* DDSCL_NORMAL doesn't. */
2831 ddraw
= create_ddraw();
2832 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2833 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2834 (LONG_PTR
)test_proc
, proc
);
2835 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2836 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2837 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2838 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2839 (LONG_PTR
)test_proc
, proc
);
2840 ref
= IDirectDraw4_Release(ddraw
);
2841 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2842 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2843 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2844 (LONG_PTR
)test_proc
, proc
);
2846 /* The original window proc is only restored by ddraw if the current
2847 * window proc matches the one ddraw set. This also affects switching
2848 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2849 ddraw
= create_ddraw();
2850 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2851 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2852 (LONG_PTR
)test_proc
, proc
);
2853 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2854 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2855 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2856 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2857 (LONG_PTR
)test_proc
, proc
);
2859 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2860 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2861 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2862 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2863 (LONG_PTR
)test_proc
, proc
);
2864 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2865 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2866 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2867 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2868 (LONG_PTR
)test_proc
, proc
);
2869 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2870 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2871 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2872 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2873 (LONG_PTR
)DefWindowProcA
, proc
);
2874 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2875 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2876 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2877 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2878 (LONG_PTR
)DefWindowProcA
, proc
);
2879 ref
= IDirectDraw4_Release(ddraw
);
2880 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2881 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2882 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2883 (LONG_PTR
)test_proc
, proc
);
2885 ddraw
= create_ddraw();
2886 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2887 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2888 (LONG_PTR
)test_proc
, proc
);
2889 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2890 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2891 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2892 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2893 (LONG_PTR
)test_proc
, proc
);
2894 ref
= IDirectDraw4_Release(ddraw
);
2895 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2896 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2897 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2898 (LONG_PTR
)DefWindowProcA
, proc
);
2900 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2901 expect_messages
= NULL
;
2902 DestroyWindow(window
);
2903 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2906 static void test_window_style(void)
2908 LONG style
, exstyle
, tmp
, expected_style
;
2909 RECT fullscreen_rect
, r
;
2910 HWND window
, window2
;
2911 IDirectDraw4
*ddraw
;
2916 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2917 0, 0, 100, 100, 0, 0, 0, 0);
2918 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2919 0, 0, 50, 50, 0, 0, 0, 0);
2920 ddraw
= create_ddraw();
2921 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2923 style
= GetWindowLongA(window
, GWL_STYLE
);
2924 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2925 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2927 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2928 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2930 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2931 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2932 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2933 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2935 GetWindowRect(window
, &r
);
2936 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2937 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2938 GetClientRect(window
, &r
);
2939 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2941 ret
= SetForegroundWindow(GetDesktopWindow());
2942 ok(ret
, "Failed to set foreground window.\n");
2944 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2945 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2946 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2947 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2949 ret
= SetForegroundWindow(window
);
2950 ok(ret
, "Failed to set foreground window.\n");
2951 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2952 * the next tests expect this. */
2953 ShowWindow(window
, SW_HIDE
);
2955 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2956 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2958 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2959 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2960 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2961 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2963 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2964 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2966 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2967 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2968 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2969 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2971 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2972 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2974 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2975 expected_style
= style
| WS_VISIBLE
;
2976 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2977 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2978 expected_style
= exstyle
| WS_EX_TOPMOST
;
2979 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2981 ShowWindow(window
, SW_HIDE
);
2982 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2983 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2984 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2985 expected_style
= exstyle
| WS_EX_TOPMOST
;
2986 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2988 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2989 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2991 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2992 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2993 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2994 expected_style
= exstyle
| WS_EX_TOPMOST
;
2995 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2997 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2998 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3000 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3001 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
3002 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3003 expected_style
= exstyle
| WS_EX_TOPMOST
;
3004 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
3006 ret
= SetForegroundWindow(window
);
3007 ok(ret
, "Failed to set foreground window.\n");
3009 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3010 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3012 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3013 expected_style
= style
| WS_VISIBLE
;
3014 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3015 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3016 expected_style
= exstyle
| WS_EX_TOPMOST
;
3017 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
3019 ShowWindow(window
, SW_HIDE
);
3020 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3021 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3023 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3024 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
3025 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3026 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
3028 ShowWindow(window
, SW_SHOW
);
3029 ret
= SetForegroundWindow(GetDesktopWindow());
3030 ok(ret
, "Failed to set foreground window.\n");
3031 SetActiveWindow(window
);
3032 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
3033 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3034 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3036 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3037 expected_style
= style
| WS_VISIBLE
;
3038 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3039 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3040 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
3042 GetWindowRect(window
, &r
);
3043 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
3044 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
3046 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3047 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3049 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
3050 GetWindowRect(window
, &r
);
3051 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
3052 wine_dbgstr_rect(&r
));
3054 ret
= SetForegroundWindow(window2
);
3055 ok(ret
, "Failed to set foreground window.\n");
3056 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3057 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3059 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3060 expected_style
= style
| WS_VISIBLE
;
3061 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3062 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3063 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
3065 GetWindowRect(window
, &r
);
3066 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
3067 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
3069 ret
= SetForegroundWindow(window
);
3070 ok(ret
, "Failed to set foreground window.\n");
3071 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3072 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3074 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3075 expected_style
= style
| WS_VISIBLE
;
3076 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3077 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3078 expected_style
= exstyle
| WS_EX_TOPMOST
;
3079 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
3081 ShowWindow(window
, SW_HIDE
);
3082 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3083 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3085 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3086 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
3087 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3088 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
3090 ShowWindow(window
, SW_SHOW
);
3091 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3092 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3094 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3095 expected_style
= style
| WS_VISIBLE
;
3096 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3097 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3098 expected_style
= exstyle
| WS_EX_TOPMOST
;
3099 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
3101 ret
= SetForegroundWindow(GetDesktopWindow());
3102 ok(ret
, "Failed to set foreground window.\n");
3103 tmp
= GetWindowLongA(window
, GWL_STYLE
);
3104 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
3105 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
3106 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
3107 expected_style
= exstyle
| WS_EX_TOPMOST
;
3108 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
3110 ref
= IDirectDraw4_Release(ddraw
);
3111 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3113 DestroyWindow(window2
);
3114 DestroyWindow(window
);
3117 static void test_redundant_mode_set(void)
3119 DDSURFACEDESC2 surface_desc
= {0};
3120 IDirectDraw4
*ddraw
;
3126 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3127 0, 0, 100, 100, 0, 0, 0, 0);
3128 ddraw
= create_ddraw();
3129 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3131 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3132 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3134 surface_desc
.dwSize
= sizeof(surface_desc
);
3135 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
3136 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
3138 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
3139 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
3140 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
3142 GetWindowRect(window
, &q
);
3146 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
3147 GetWindowRect(window
, &s
);
3148 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
3150 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
3151 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
3152 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
3154 GetWindowRect(window
, &s
);
3155 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
3156 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
3158 ref
= IDirectDraw4_Release(ddraw
);
3159 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3161 DestroyWindow(window
);
3164 static SIZE screen_size
, screen_size2
;
3166 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3168 if (message
== WM_SIZE
)
3170 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
3171 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
3174 return test_proc(hwnd
, message
, wparam
, lparam
);
3177 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
3179 if (message
== WM_SIZE
)
3181 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
3182 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
3185 return test_proc(hwnd
, message
, wparam
, lparam
);
3188 struct test_coop_level_mode_set_enum_param
3190 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
3193 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
3195 struct test_coop_level_mode_set_enum_param
*param
= context
;
3197 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
3198 return DDENUMRET_OK
;
3199 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
3200 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
3201 return DDENUMRET_OK
;
3203 if (!param
->ddraw_width
)
3205 param
->ddraw_width
= surface_desc
->dwWidth
;
3206 param
->ddraw_height
= surface_desc
->dwHeight
;
3207 return DDENUMRET_OK
;
3209 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
3210 return DDENUMRET_OK
;
3212 /* The docs say the DDENUMRET_CANCEL below cancels the enumeration, so the check should be
3213 * redundant. However, since Windows 10 this no longer works and the enumeration continues
3214 * until all supported modes are enumerated. Win8 and earlier do cancel.
3216 * Unrelatedly, some testbot machines report high res modes like 1920x1080, but suffer from
3217 * some problems when we actually try to set them (w10pro64 and its localization siblings).
3218 * Try to stay below the registry mode if possible. */
3219 if (!param
->user32_width
|| (surface_desc
->dwWidth
< registry_mode
.dmPelsWidth
3220 && surface_desc
->dwHeight
< registry_mode
.dmPelsHeight
))
3222 param
->user32_width
= surface_desc
->dwWidth
;
3223 param
->user32_height
= surface_desc
->dwHeight
;
3225 return DDENUMRET_CANCEL
;
3228 static void test_coop_level_mode_set(void)
3230 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
3231 unsigned int display_count
= 0;
3232 IDirectDrawSurface4
*primary
;
3233 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
3234 IDirectDraw4
*ddraw
;
3235 DDSURFACEDESC2 ddsd
;
3237 HWND window
, window2
;
3241 struct test_coop_level_mode_set_enum_param param
;
3245 static const struct message exclusive_messages
[] =
3247 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3248 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3249 {WM_SIZE
, FALSE
, 0},
3250 {WM_DISPLAYCHANGE
, FALSE
, 0},
3253 static const struct message exclusive_focus_loss_messages
[] =
3255 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
, DD_OK
},
3256 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DD_OK
}, /* Window resize due to mode change. */
3257 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DD_OK
},
3258 {WM_SIZE
, TRUE
, SIZE_RESTORED
, DD_OK
}, /* Generated by DefWindowProc. */
3259 {WM_DISPLAYCHANGE
, FALSE
, 0, DD_OK
},
3260 {WM_KILLFOCUS
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
3261 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
}, /* Window minimized. */
3262 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
3263 * SW_MINIMIZED, causing a recursive window activation that does not
3264 * produce the same result in Wine yet. Ignore the difference for now.
3265 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
3266 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
3267 {WM_MOVE
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
3268 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
, DDERR_NOEXCLUSIVEMODE
},
3269 {WM_ACTIVATEAPP
, TRUE
, FALSE
, DDERR_NOEXCLUSIVEMODE
},
3272 static const struct message exclusive_focus_restore_messages
[] =
3274 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
3275 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
3276 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
3277 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
3278 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
3279 /* Native redundantly sets the window size here. */
3280 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
3281 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
3282 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
3283 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
3286 static const struct message sc_restore_messages
[] =
3288 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
3289 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3290 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3291 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
3294 static const struct message sc_minimize_messages
[] =
3296 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
3297 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3298 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3299 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3302 static const struct message sc_maximize_messages
[] =
3304 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
3305 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3306 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3307 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
3311 static const struct message normal_messages
[] =
3313 {WM_DISPLAYCHANGE
, FALSE
, 0},
3317 memset(&devmode
, 0, sizeof(devmode
));
3318 devmode
.dmSize
= sizeof(devmode
);
3319 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3320 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3321 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3322 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3323 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3324 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3326 ret
= save_display_modes(&original_modes
, &display_count
);
3327 ok(ret
, "Failed to save original display modes.\n");
3329 ddraw
= create_ddraw();
3330 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3332 memset(¶m
, 0, sizeof(param
));
3333 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
3334 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3335 ref
= IDirectDraw4_Release(ddraw
);
3336 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3338 if (!param
.user32_height
)
3340 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
3341 heap_free(original_modes
);
3345 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3346 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
3347 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
3349 memset(&devmode
, 0, sizeof(devmode
));
3350 devmode
.dmSize
= sizeof(devmode
);
3351 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3352 devmode
.dmPelsWidth
= param
.user32_width
;
3353 devmode
.dmPelsHeight
= param
.user32_height
;
3354 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3355 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3357 ddraw
= create_ddraw();
3358 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3360 wc
.lpfnWndProc
= mode_set_proc
;
3361 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3362 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3363 wc
.lpfnWndProc
= mode_set_proc2
;
3364 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
3365 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3367 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3368 0, 0, 100, 100, 0, 0, 0, 0);
3369 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3370 0, 0, 100, 100, 0, 0, 0, 0);
3372 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3373 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3375 GetWindowRect(window
, &r
);
3376 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3377 wine_dbgstr_rect(&r
));
3379 memset(&ddsd
, 0, sizeof(ddsd
));
3380 ddsd
.dwSize
= sizeof(ddsd
);
3381 ddsd
.dwFlags
= DDSD_CAPS
;
3382 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3384 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3385 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3386 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3387 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3388 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3389 param
.user32_width
, ddsd
.dwWidth
);
3390 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3391 param
.user32_height
, ddsd
.dwHeight
);
3393 GetWindowRect(window
, &r
);
3394 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3395 wine_dbgstr_rect(&r
));
3397 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3398 expect_messages
= exclusive_messages
;
3402 hr
= IDirectDrawSurface4_IsLost(primary
);
3403 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3404 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3405 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3406 hr
= IDirectDrawSurface4_IsLost(primary
);
3407 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3409 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3410 expect_messages
= NULL
;
3411 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3412 "Expected screen size %lux%lu, got %lux%lu.\n",
3413 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3415 GetWindowRect(window
, &r
);
3416 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3417 wine_dbgstr_rect(&r
));
3419 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3420 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3421 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3422 param
.user32_width
, ddsd
.dwWidth
);
3423 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3424 param
.user32_height
, ddsd
.dwHeight
);
3425 IDirectDrawSurface4_Release(primary
);
3427 memset(&ddsd
, 0, sizeof(ddsd
));
3428 ddsd
.dwSize
= sizeof(ddsd
);
3429 ddsd
.dwFlags
= DDSD_CAPS
;
3430 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3432 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3433 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3434 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3435 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3436 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3437 param
.ddraw_width
, ddsd
.dwWidth
);
3438 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3439 param
.ddraw_height
, ddsd
.dwHeight
);
3441 GetWindowRect(window
, &r
);
3442 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3443 wine_dbgstr_rect(&r
));
3445 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3446 expect_messages
= exclusive_messages
;
3450 hr
= IDirectDrawSurface4_IsLost(primary
);
3451 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3452 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3453 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3454 hr
= IDirectDrawSurface4_IsLost(primary
);
3455 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3457 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3458 expect_messages
= NULL
;
3459 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3460 "Expected screen size %lux%lu, got %lux%lu.\n",
3461 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3463 GetWindowRect(window
, &r
);
3464 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3465 wine_dbgstr_rect(&r
));
3467 expect_messages
= exclusive_focus_loss_messages
;
3468 focus_test_ddraw
= ddraw
;
3469 ret
= SetForegroundWindow(GetDesktopWindow());
3470 ok(ret
, "Failed to set foreground window.\n");
3471 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3472 focus_test_ddraw
= NULL
;
3474 memset(&devmode
, 0, sizeof(devmode
));
3475 devmode
.dmSize
= sizeof(devmode
);
3476 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3477 ok(ret
, "Failed to get display mode.\n");
3478 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3479 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3480 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3482 expect_messages
= exclusive_focus_restore_messages
;
3483 ShowWindow(window
, SW_RESTORE
);
3484 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3486 GetWindowRect(window
, &r
);
3487 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3488 wine_dbgstr_rect(&r
));
3489 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3490 ok(ret
, "Failed to get display mode.\n");
3491 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3492 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %lux%lu.\n",
3493 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3495 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3496 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3497 /* Normally the primary should be restored here. Unfortunately this causes the
3498 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3499 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3500 * the point of the GetSurfaceDesc call. */
3502 expect_messages
= sc_minimize_messages
;
3503 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3504 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3505 expect_messages
= NULL
;
3507 expect_messages
= sc_restore_messages
;
3508 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3509 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3510 expect_messages
= NULL
;
3512 expect_messages
= sc_maximize_messages
;
3513 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3514 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3515 expect_messages
= NULL
;
3517 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3518 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3520 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3521 expect_messages
= exclusive_messages
;
3525 hr
= IDirectDrawSurface4_IsLost(primary
);
3526 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3527 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3528 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3529 hr
= IDirectDrawSurface4_IsLost(primary
);
3530 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3533 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3534 expect_messages
= NULL
;
3536 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3537 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3538 "Expected screen size %lux%lu, got %lux%lu.\n",
3539 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3541 GetWindowRect(window
, &r
);
3543 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3544 wine_dbgstr_rect(&r
));
3546 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3547 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3548 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3549 param
.ddraw_width
, ddsd
.dwWidth
);
3550 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3551 param
.ddraw_height
, ddsd
.dwHeight
);
3552 IDirectDrawSurface4_Release(primary
);
3555 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3556 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3558 memset(&ddsd
, 0, sizeof(ddsd
));
3559 ddsd
.dwSize
= sizeof(ddsd
);
3560 ddsd
.dwFlags
= DDSD_CAPS
;
3561 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3563 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3564 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3565 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3566 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3567 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3568 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3569 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3570 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3572 GetWindowRect(window
, &r
);
3574 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3575 wine_dbgstr_rect(&r
));
3577 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3578 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3580 GetWindowRect(window
, &r
);
3582 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3583 wine_dbgstr_rect(&r
));
3585 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3586 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3587 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3588 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3589 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3590 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3591 IDirectDrawSurface4_Release(primary
);
3593 memset(&ddsd
, 0, sizeof(ddsd
));
3594 ddsd
.dwSize
= sizeof(ddsd
);
3595 ddsd
.dwFlags
= DDSD_CAPS
;
3596 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3598 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3599 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3600 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3601 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3602 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3603 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3604 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3605 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3607 GetWindowRect(window
, &r
);
3609 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3610 wine_dbgstr_rect(&r
));
3612 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3613 expect_messages
= normal_messages
;
3617 hr
= IDirectDrawSurface4_IsLost(primary
);
3618 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3619 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3620 devmode
.dmPelsWidth
= param
.user32_width
;
3621 devmode
.dmPelsHeight
= param
.user32_height
;
3622 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3623 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3624 hr
= IDirectDrawSurface4_IsLost(primary
);
3625 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3627 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3628 expect_messages
= NULL
;
3629 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3631 GetWindowRect(window
, &r
);
3633 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3634 wine_dbgstr_rect(&r
));
3636 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3637 expect_messages
= normal_messages
;
3641 hr
= IDirectDrawSurface4_Restore(primary
);
3642 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3643 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3644 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3645 hr
= IDirectDrawSurface4_Restore(primary
);
3646 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3647 hr
= IDirectDrawSurface4_IsLost(primary
);
3648 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3650 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3651 expect_messages
= NULL
;
3652 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3654 GetWindowRect(window
, &r
);
3656 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3657 wine_dbgstr_rect(&r
));
3659 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3660 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3661 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3662 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3663 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3664 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3665 IDirectDrawSurface4_Release(primary
);
3667 memset(&ddsd
, 0, sizeof(ddsd
));
3668 ddsd
.dwSize
= sizeof(ddsd
);
3669 ddsd
.dwFlags
= DDSD_CAPS
;
3670 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3672 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3673 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3674 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3675 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3676 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3677 param
.ddraw_width
, ddsd
.dwWidth
);
3678 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3679 param
.ddraw_height
, ddsd
.dwHeight
);
3681 GetWindowRect(window
, &r
);
3683 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3684 wine_dbgstr_rect(&r
));
3686 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3687 expect_messages
= normal_messages
;
3691 hr
= IDirectDrawSurface4_IsLost(primary
);
3692 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3693 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3694 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3695 hr
= IDirectDrawSurface4_IsLost(primary
);
3696 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3698 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3699 expect_messages
= NULL
;
3700 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3702 GetWindowRect(window
, &r
);
3704 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3705 wine_dbgstr_rect(&r
));
3707 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3708 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3709 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3710 param
.ddraw_width
, ddsd
.dwWidth
);
3711 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3712 param
.ddraw_height
, ddsd
.dwHeight
);
3713 IDirectDrawSurface4_Release(primary
);
3715 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3716 ok(ret
, "Failed to get display mode.\n");
3717 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3718 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3719 "Expected resolution %lux%lu, got %lux%lu.\n",
3720 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3721 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3722 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3723 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3725 memset(&ddsd
, 0, sizeof(ddsd
));
3726 ddsd
.dwSize
= sizeof(ddsd
);
3727 ddsd
.dwFlags
= DDSD_CAPS
;
3728 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3730 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3731 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3732 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3733 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3734 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3735 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3736 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3737 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3739 GetWindowRect(window
, &r
);
3741 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3742 wine_dbgstr_rect(&r
));
3744 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3745 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3746 * not DDSCL_FULLSCREEN. */
3747 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3748 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3750 GetWindowRect(window
, &r
);
3752 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3753 wine_dbgstr_rect(&r
));
3755 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3756 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3757 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3758 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3759 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3760 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3761 IDirectDrawSurface4_Release(primary
);
3763 memset(&ddsd
, 0, sizeof(ddsd
));
3764 ddsd
.dwSize
= sizeof(ddsd
);
3765 ddsd
.dwFlags
= DDSD_CAPS
;
3766 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3768 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3769 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3770 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3771 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3772 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3773 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3774 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3775 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3777 GetWindowRect(window
, &r
);
3779 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3780 wine_dbgstr_rect(&r
));
3782 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3783 expect_messages
= normal_messages
;
3787 hr
= IDirectDrawSurface4_IsLost(primary
);
3788 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3789 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3790 devmode
.dmPelsWidth
= param
.user32_width
;
3791 devmode
.dmPelsHeight
= param
.user32_height
;
3792 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3793 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3794 hr
= IDirectDrawSurface4_IsLost(primary
);
3795 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3797 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3798 expect_messages
= NULL
;
3799 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3801 GetWindowRect(window
, &r
);
3803 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3804 wine_dbgstr_rect(&r
));
3806 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3807 expect_messages
= normal_messages
;
3811 hr
= IDirectDrawSurface4_Restore(primary
);
3812 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3813 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3814 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3815 hr
= IDirectDrawSurface4_Restore(primary
);
3816 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3817 hr
= IDirectDrawSurface4_IsLost(primary
);
3818 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3820 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3821 expect_messages
= NULL
;
3822 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3824 GetWindowRect(window
, &r
);
3826 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3827 wine_dbgstr_rect(&r
));
3829 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3830 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3831 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3832 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3833 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3834 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3835 IDirectDrawSurface4_Release(primary
);
3837 memset(&ddsd
, 0, sizeof(ddsd
));
3838 ddsd
.dwSize
= sizeof(ddsd
);
3839 ddsd
.dwFlags
= DDSD_CAPS
;
3840 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3842 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3843 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3844 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3845 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3846 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3847 param
.ddraw_width
, ddsd
.dwWidth
);
3848 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3849 param
.ddraw_height
, ddsd
.dwHeight
);
3851 GetWindowRect(window
, &r
);
3853 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3854 wine_dbgstr_rect(&r
));
3856 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3857 expect_messages
= normal_messages
;
3861 hr
= IDirectDrawSurface4_IsLost(primary
);
3862 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3863 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3864 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3865 hr
= IDirectDrawSurface4_IsLost(primary
);
3866 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3868 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3869 expect_messages
= NULL
;
3870 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3872 GetWindowRect(window
, &r
);
3874 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3875 wine_dbgstr_rect(&r
));
3877 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3878 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3879 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3880 param
.ddraw_width
, ddsd
.dwWidth
);
3881 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3882 param
.ddraw_height
, ddsd
.dwHeight
);
3883 IDirectDrawSurface4_Release(primary
);
3885 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3886 ok(ret
, "Failed to get display mode.\n");
3887 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3888 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3889 "Expected resolution %lux%lu, got %lux%lu.\n",
3890 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3891 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3892 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3893 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3895 memset(&ddsd
, 0, sizeof(ddsd
));
3896 ddsd
.dwSize
= sizeof(ddsd
);
3897 ddsd
.dwFlags
= DDSD_CAPS
;
3898 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3900 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3901 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3902 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3903 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3904 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3905 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3906 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3907 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3908 IDirectDrawSurface4_Release(primary
);
3910 GetWindowRect(window
, &r
);
3912 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3913 wine_dbgstr_rect(&r
));
3915 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3916 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3917 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3918 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3919 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3921 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3922 expect_messages
= exclusive_messages
;
3926 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3927 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3929 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3930 expect_messages
= NULL
;
3931 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3932 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3933 "Expected screen size %lux%lu, got %lux%lu.\n",
3934 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3935 screen_size
.cx
, screen_size
.cy
);
3937 GetWindowRect(window
, &r
);
3938 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3939 wine_dbgstr_rect(&r
));
3941 memset(&ddsd
, 0, sizeof(ddsd
));
3942 ddsd
.dwSize
= sizeof(ddsd
);
3943 ddsd
.dwFlags
= DDSD_CAPS
;
3944 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3946 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3947 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3948 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3949 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3950 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3951 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3952 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3953 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3954 IDirectDrawSurface4_Release(primary
);
3956 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3957 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3958 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3959 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3960 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3962 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3963 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3965 memset(&ddsd
, 0, sizeof(ddsd
));
3966 ddsd
.dwSize
= sizeof(ddsd
);
3967 ddsd
.dwFlags
= DDSD_CAPS
;
3968 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3970 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3971 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3972 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3973 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3974 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3975 param
.ddraw_width
, ddsd
.dwWidth
);
3976 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3977 param
.ddraw_height
, ddsd
.dwHeight
);
3978 IDirectDrawSurface4_Release(primary
);
3980 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3981 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3983 /* If the window is changed at the same time, messages are sent to the new window. */
3984 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3985 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3986 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3987 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3989 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3990 expect_messages
= exclusive_messages
;
3993 screen_size2
.cx
= 0;
3994 screen_size2
.cy
= 0;
3996 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3997 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3999 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
4000 expect_messages
= NULL
;
4001 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n",
4002 screen_size
.cx
, screen_size
.cy
);
4003 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
4004 "Expected screen size 2 %lux%lu, got %lux%lu.\n",
4005 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
4007 GetWindowRect(window
, &r
);
4008 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
4009 wine_dbgstr_rect(&r
));
4010 GetWindowRect(window2
, &r
);
4011 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
4012 wine_dbgstr_rect(&r
));
4014 memset(&ddsd
, 0, sizeof(ddsd
));
4015 ddsd
.dwSize
= sizeof(ddsd
);
4016 ddsd
.dwFlags
= DDSD_CAPS
;
4017 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4019 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
4020 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
4021 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
4022 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
4023 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
4024 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
4025 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
4026 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
4027 IDirectDrawSurface4_Release(primary
);
4029 ref
= IDirectDraw4_Release(ddraw
);
4030 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4032 GetWindowRect(window
, &r
);
4033 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
4034 wine_dbgstr_rect(&r
));
4036 ret
= restore_display_modes(original_modes
, display_count
);
4037 ok(ret
, "Failed to restore display modes.\n");
4039 /* Test that no mode restorations if no mode changes happened */
4040 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
4041 devmode
.dmPelsWidth
= param
.user32_width
;
4042 devmode
.dmPelsHeight
= param
.user32_height
;
4043 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4044 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4046 ddraw
= create_ddraw();
4047 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4048 ref
= IDirectDraw4_Release(ddraw
);
4049 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4051 memset(&devmode2
, 0, sizeof(devmode2
));
4052 devmode2
.dmSize
= sizeof(devmode2
);
4053 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4054 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4055 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
4056 ret
= restore_display_modes(original_modes
, display_count
);
4057 ok(ret
, "Failed to restore display modes.\n");
4059 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
4060 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4061 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4063 ddraw
= create_ddraw();
4064 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4065 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4066 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4067 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4068 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4069 ref
= IDirectDraw4_Release(ddraw
);
4070 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4072 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4073 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4074 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
4075 ret
= restore_display_modes(original_modes
, display_count
);
4076 ok(ret
, "Failed to restore display modes.\n");
4078 /* Test that mode restorations use display settings in the registry after ddraw object releases
4079 * if SetDisplayMode() was called */
4080 ddraw
= create_ddraw();
4081 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4082 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
4083 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4085 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4086 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4088 ref
= IDirectDraw4_Release(ddraw
);
4089 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4091 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4092 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4093 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4094 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4095 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4096 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4097 ret
= restore_display_modes(original_modes
, display_count
);
4098 ok(ret
, "Failed to restore display modes.\n");
4100 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
4101 ddraw
= create_ddraw();
4102 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4103 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
4104 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4106 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4107 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4109 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
4110 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4112 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4113 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4114 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4115 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4116 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4117 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4119 ref
= IDirectDraw4_Release(ddraw
);
4120 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4122 expect_messages
= NULL
;
4123 DestroyWindow(window
);
4124 DestroyWindow(window2
);
4125 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4126 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
4127 ret
= restore_display_modes(original_modes
, display_count
);
4128 ok(ret
, "Failed to restore display modes.\n");
4129 heap_free(original_modes
);
4132 static void test_coop_level_mode_set_multi(void)
4134 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
4135 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
4136 WCHAR second_monitor_name
[CCHDEVICENAME
];
4137 IDirectDraw4
*ddraw1
, *ddraw2
;
4145 memset(&devmode
, 0, sizeof(devmode
));
4146 devmode
.dmSize
= sizeof(devmode
);
4147 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
4148 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4149 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
4150 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
4151 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4152 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
4154 ret
= save_display_modes(&original_modes
, &display_count
);
4155 ok(ret
, "Failed to save original display modes.\n");
4157 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
4158 0, 0, 100, 100, 0, 0, 0, 0);
4159 ddraw1
= create_ddraw();
4160 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4162 /* With just a single ddraw object, the display mode is restored on
4164 hr
= set_display_mode(ddraw1
, 800, 600);
4165 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4166 w
= GetSystemMetrics(SM_CXSCREEN
);
4167 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4168 h
= GetSystemMetrics(SM_CYSCREEN
);
4169 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4171 ref
= IDirectDraw4_Release(ddraw1
);
4172 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4173 w
= GetSystemMetrics(SM_CXSCREEN
);
4174 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4175 h
= GetSystemMetrics(SM_CYSCREEN
);
4176 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4178 /* When there are multiple ddraw objects, the display mode is restored to
4179 * the initial mode, before the first SetDisplayMode() call. */
4180 ddraw1
= create_ddraw();
4181 hr
= set_display_mode(ddraw1
, 800, 600);
4182 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4183 w
= GetSystemMetrics(SM_CXSCREEN
);
4184 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4185 h
= GetSystemMetrics(SM_CYSCREEN
);
4186 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4188 ddraw2
= create_ddraw();
4189 hr
= set_display_mode(ddraw2
, 640, 480);
4190 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4191 w
= GetSystemMetrics(SM_CXSCREEN
);
4192 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4193 h
= GetSystemMetrics(SM_CYSCREEN
);
4194 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4196 ref
= IDirectDraw4_Release(ddraw2
);
4197 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4198 w
= GetSystemMetrics(SM_CXSCREEN
);
4199 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4200 h
= GetSystemMetrics(SM_CYSCREEN
);
4201 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4203 ref
= IDirectDraw4_Release(ddraw1
);
4204 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4205 w
= GetSystemMetrics(SM_CXSCREEN
);
4206 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4207 h
= GetSystemMetrics(SM_CYSCREEN
);
4208 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4210 /* Regardless of release ordering. */
4211 ddraw1
= create_ddraw();
4212 hr
= set_display_mode(ddraw1
, 800, 600);
4213 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4214 w
= GetSystemMetrics(SM_CXSCREEN
);
4215 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4216 h
= GetSystemMetrics(SM_CYSCREEN
);
4217 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4219 ddraw2
= create_ddraw();
4220 hr
= set_display_mode(ddraw2
, 640, 480);
4221 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4222 w
= GetSystemMetrics(SM_CXSCREEN
);
4223 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4224 h
= GetSystemMetrics(SM_CYSCREEN
);
4225 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4227 ref
= IDirectDraw4_Release(ddraw1
);
4228 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4229 w
= GetSystemMetrics(SM_CXSCREEN
);
4230 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4231 h
= GetSystemMetrics(SM_CYSCREEN
);
4232 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4234 ref
= IDirectDraw4_Release(ddraw2
);
4235 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4236 w
= GetSystemMetrics(SM_CXSCREEN
);
4237 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4238 h
= GetSystemMetrics(SM_CYSCREEN
);
4239 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4241 /* But only for ddraw objects that called SetDisplayMode(). */
4242 ddraw1
= create_ddraw();
4243 ddraw2
= create_ddraw();
4244 hr
= set_display_mode(ddraw2
, 640, 480);
4245 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4246 w
= GetSystemMetrics(SM_CXSCREEN
);
4247 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4248 h
= GetSystemMetrics(SM_CYSCREEN
);
4249 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4251 ref
= IDirectDraw4_Release(ddraw1
);
4252 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4253 w
= GetSystemMetrics(SM_CXSCREEN
);
4254 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4255 h
= GetSystemMetrics(SM_CYSCREEN
);
4256 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4258 ref
= IDirectDraw4_Release(ddraw2
);
4259 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4260 w
= GetSystemMetrics(SM_CXSCREEN
);
4261 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4262 h
= GetSystemMetrics(SM_CYSCREEN
);
4263 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4265 /* If there's a ddraw object that's currently in exclusive mode, it blocks
4266 * restoring the display mode. */
4267 ddraw1
= create_ddraw();
4268 hr
= set_display_mode(ddraw1
, 800, 600);
4269 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4270 w
= GetSystemMetrics(SM_CXSCREEN
);
4271 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4272 h
= GetSystemMetrics(SM_CYSCREEN
);
4273 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4275 ddraw2
= create_ddraw();
4276 hr
= set_display_mode(ddraw2
, 640, 480);
4277 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4278 w
= GetSystemMetrics(SM_CXSCREEN
);
4279 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4280 h
= GetSystemMetrics(SM_CYSCREEN
);
4281 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4283 hr
= IDirectDraw4_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4284 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4286 ref
= IDirectDraw4_Release(ddraw1
);
4287 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4288 w
= GetSystemMetrics(SM_CXSCREEN
);
4289 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
4290 h
= GetSystemMetrics(SM_CYSCREEN
);
4291 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
4293 ref
= IDirectDraw4_Release(ddraw2
);
4294 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4295 w
= GetSystemMetrics(SM_CXSCREEN
);
4296 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4297 h
= GetSystemMetrics(SM_CYSCREEN
);
4298 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4300 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
4301 ddraw1
= create_ddraw();
4302 hr
= set_display_mode(ddraw1
, 800, 600);
4303 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
4304 w
= GetSystemMetrics(SM_CXSCREEN
);
4305 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
4306 h
= GetSystemMetrics(SM_CYSCREEN
);
4307 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
4309 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4310 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4312 ddraw2
= create_ddraw();
4313 hr
= set_display_mode(ddraw2
, 640, 480);
4314 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
4316 ref
= IDirectDraw4_Release(ddraw1
);
4317 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4318 w
= GetSystemMetrics(SM_CXSCREEN
);
4319 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4320 h
= GetSystemMetrics(SM_CYSCREEN
);
4321 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4323 ref
= IDirectDraw4_Release(ddraw2
);
4324 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4325 w
= GetSystemMetrics(SM_CXSCREEN
);
4326 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
4327 h
= GetSystemMetrics(SM_CYSCREEN
);
4328 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
4330 if (display_count
< 2)
4332 skip("Following tests require two monitors.\n");
4336 ret
= restore_display_modes(original_modes
, display_count
);
4337 ok(ret
, "Failed to restore display modes.\n");
4339 second_monitor_name
[0] = '\0';
4340 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
4342 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
4344 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
4348 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
4349 memset(&old_devmode
, 0, sizeof(old_devmode
));
4350 old_devmode
.dmSize
= sizeof(old_devmode
);
4351 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
4352 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4354 devmode
= old_devmode
;
4355 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
4357 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4358 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
4361 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
4362 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
4363 "Failed to find a different mode for the second monitor.\n");
4365 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
4366 ddraw1
= create_ddraw();
4367 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4368 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4369 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4371 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4372 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4374 memset(&devmode2
, 0, sizeof(devmode2
));
4375 devmode2
.dmSize
= sizeof(devmode2
);
4376 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4377 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4378 if (compare_mode_rect(&devmode2
, &old_devmode
))
4380 skip("Failed to change display settings of the second monitor.\n");
4381 ref
= IDirectDraw4_Release(ddraw1
);
4382 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4386 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
4387 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4388 ref
= IDirectDraw4_Release(ddraw1
);
4389 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4391 memset(&devmode3
, 0, sizeof(devmode3
));
4392 devmode3
.dmSize
= sizeof(devmode3
);
4393 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
4394 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4395 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
4396 ret
= restore_display_modes(original_modes
, display_count
);
4397 ok(ret
, "Failed to restore display modes.\n");
4399 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
4400 * SetDisplayMode() was called */
4401 ddraw1
= create_ddraw();
4402 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4403 hr
= set_display_mode(ddraw1
, 800, 600);
4404 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4406 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4407 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4409 ref
= IDirectDraw4_Release(ddraw1
);
4410 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4412 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4413 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4414 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4415 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4416 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4417 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4418 ret
= restore_display_modes(original_modes
, display_count
);
4419 ok(ret
, "Failed to restore display modes.\n");
4421 /* Test that mode restorations happen for non-primary monitors as well */
4422 ddraw1
= create_ddraw();
4423 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4424 hr
= set_display_mode(ddraw1
, 800, 600);
4425 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4427 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4428 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4430 hr
= IDirectDraw4_RestoreDisplayMode(ddraw1
);
4431 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4433 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4434 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4435 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4436 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4437 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4438 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4440 ref
= IDirectDraw4_Release(ddraw1
);
4441 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4442 ret
= restore_display_modes(original_modes
, display_count
);
4443 ok(ret
, "Failed to restore display modes.\n");
4445 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4446 ddraw1
= create_ddraw();
4447 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4448 hr
= set_display_mode(ddraw1
, 800, 600);
4449 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4451 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4452 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4453 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4455 ref
= IDirectDraw4_Release(ddraw1
);
4456 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4458 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4459 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4460 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4461 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4462 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4463 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4464 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4465 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4466 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4467 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4468 ret
= restore_display_modes(original_modes
, display_count
);
4469 ok(ret
, "Failed to restore display modes.\n");
4471 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4472 * objects and one of them restores display mode */
4473 ddraw1
= create_ddraw();
4474 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4475 ddraw2
= create_ddraw();
4476 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4477 hr
= set_display_mode(ddraw1
, 800, 600);
4478 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4479 hr
= set_display_mode(ddraw2
, 640, 480);
4480 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4482 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4483 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4485 hr
= IDirectDraw4_RestoreDisplayMode(ddraw2
);
4486 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4488 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4489 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4490 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4491 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4492 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4493 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4495 ref
= IDirectDraw4_Release(ddraw2
);
4496 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4497 ref
= IDirectDraw4_Release(ddraw1
);
4498 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4499 ret
= restore_display_modes(original_modes
, display_count
);
4500 ok(ret
, "Failed to restore display modes.\n");
4502 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4503 * objects and one of them got released */
4504 ddraw1
= create_ddraw();
4505 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4506 ddraw2
= create_ddraw();
4507 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4508 hr
= set_display_mode(ddraw1
, 800, 600);
4509 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4510 hr
= set_display_mode(ddraw2
, 640, 480);
4511 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4513 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4514 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4516 ref
= IDirectDraw4_Release(ddraw2
);
4517 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4519 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4520 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4521 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4522 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4523 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4524 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4526 ref
= IDirectDraw4_Release(ddraw1
);
4527 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4530 DestroyWindow(window
);
4531 ret
= restore_display_modes(original_modes
, display_count
);
4532 ok(ret
, "Failed to restore display modes.\n");
4533 heap_free(original_modes
);
4536 static void test_initialize(void)
4538 IDirectDraw4
*ddraw
;
4541 ddraw
= create_ddraw();
4542 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4544 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
4545 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx.\n", hr
);
4546 IDirectDraw4_Release(ddraw
);
4549 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw4
, (void **)&ddraw
);
4550 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw4 instance, hr %#lx.\n", hr
);
4551 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
4552 ok(hr
== DD_OK
, "Initialize returned hr %#lx, expected DD_OK.\n", hr
);
4553 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
4554 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4555 IDirectDraw4_Release(ddraw
);
4559 static void test_coop_level_surf_create(void)
4561 IDirectDrawSurface4
*surface
;
4562 IDirectDraw4
*ddraw
;
4563 DDSURFACEDESC2 ddsd
;
4566 ddraw
= create_ddraw();
4567 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4569 memset(&ddsd
, 0, sizeof(ddsd
));
4570 ddsd
.dwSize
= sizeof(ddsd
);
4571 ddsd
.dwFlags
= DDSD_CAPS
;
4572 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4573 surface
= (void *)0xdeadbeef;
4574 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4575 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4576 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4578 surface
= (void *)0xdeadbeef;
4579 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4580 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4581 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4583 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4584 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4586 surface
= (void *)0xdeadbeef;
4587 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4588 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#lx.\n", hr
);
4589 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4591 IDirectDraw4_Release(ddraw
);
4594 static void test_vb_discard(void)
4596 static const struct vec4 quad
[] =
4598 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
4599 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
4600 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
4601 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
4604 IDirect3DDevice3
*device
;
4606 IDirect3DVertexBuffer
*buffer
;
4609 D3DVERTEXBUFFERDESC desc
;
4611 static const unsigned int vbsize
= 16;
4614 window
= create_window();
4615 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4617 skip("Failed to create a 3D device, skipping test.\n");
4618 DestroyWindow(window
);
4622 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4623 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
4625 memset(&desc
, 0, sizeof(desc
));
4626 desc
.dwSize
= sizeof(desc
);
4627 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
4628 desc
.dwFVF
= D3DFVF_XYZRHW
;
4629 desc
.dwNumVertices
= vbsize
;
4630 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
4631 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
4633 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4634 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
4635 memcpy(data
, quad
, sizeof(quad
));
4636 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
4637 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
4639 hr
= IDirect3DDevice3_BeginScene(device
);
4640 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
4641 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
4642 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
4643 hr
= IDirect3DDevice3_EndScene(device
);
4644 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
4646 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4647 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
4648 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
4649 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
4650 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
4652 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
4653 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
4654 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
4656 if (data
[i
] != 0xaa)
4658 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
4662 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
4663 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
4665 IDirect3DVertexBuffer_Release(buffer
);
4666 IDirect3D3_Release(d3d
);
4667 IDirect3DDevice3_Release(device
);
4668 DestroyWindow(window
);
4671 static void test_coop_level_multi_window(void)
4673 HWND window1
, window2
;
4674 IDirectDraw4
*ddraw
;
4677 window1
= create_window();
4678 window2
= create_window();
4679 ddraw
= create_ddraw();
4680 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4682 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4683 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4684 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4685 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4686 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4687 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4689 IDirectDraw4_Release(ddraw
);
4690 DestroyWindow(window2
);
4691 DestroyWindow(window1
);
4694 static void test_draw_strided(void)
4696 static struct vec3 position
[] =
4703 static DWORD diffuse
[] =
4705 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
4707 static WORD indices
[] =
4712 IDirectDrawSurface4
*rt
;
4713 IDirect3DDevice3
*device
;
4717 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
4718 IDirect3DViewport3
*viewport
;
4719 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4721 window
= create_window();
4722 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4724 skip("Failed to create a 3D device, skipping test.\n");
4725 DestroyWindow(window
);
4729 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4730 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4731 viewport
= create_viewport(device
, 0, 0, 640, 480);
4732 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4733 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
4734 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
4735 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#lx.\n", hr
);
4737 hr
= IDirect3DDevice3_BeginScene(device
);
4738 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
4740 memset(&strided
, 0x55, sizeof(strided
));
4741 strided
.position
.lpvData
= position
;
4742 strided
.position
.dwStride
= sizeof(*position
);
4743 strided
.diffuse
.lpvData
= diffuse
;
4744 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
4745 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
4746 &strided
, 4, indices
, 6, 0);
4747 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
4749 hr
= IDirect3DDevice3_EndScene(device
);
4750 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
4752 color
= get_surface_color(rt
, 320, 240);
4753 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
4755 IDirect3DViewport3_Release(viewport
);
4756 IDirectDrawSurface4_Release(rt
);
4757 IDirect3DDevice3_Release(device
);
4758 DestroyWindow(window
);
4761 static void test_lighting(void)
4763 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4764 static D3DMATRIX mat
=
4766 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4767 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4768 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4769 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4773 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4774 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4775 1.0f
, 0.0f
, 1.0f
, 0.0f
,
4776 0.0f
, 0.0f
, 0.5f
, 1.0f
,
4780 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4781 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4782 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
4783 10.f
, 10.0f
, 10.0f
, 1.0f
,
4787 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4788 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4789 0.0f
, 0.0f
, 1.0f
, -1.0f
,
4790 10.f
, 10.0f
, 10.0f
, 0.0f
,
4792 static struct vertex
4794 struct vec3 position
;
4799 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4800 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4801 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4802 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4806 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4807 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4808 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4809 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4811 static struct vertex_normal
4813 struct vec3 position
;
4819 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4820 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4821 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4822 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4826 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4827 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4828 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4829 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4833 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4834 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4835 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4836 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4840 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4841 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4842 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4843 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4847 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4848 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4849 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4850 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4852 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
4855 D3DMATRIX
*world_matrix
;
4858 const char *message
;
4862 {&mat
, nquad
, 0x000080ff, "Lit quad with light"},
4863 {&mat_singular
, nquad
, 0x000080b4, "Lit quad with singular world matrix"},
4864 {&mat_transf
, rotatedquad
, 0x000080ff, "Lit quad with transformation matrix"},
4865 {&mat_nonaffine
, translatedquad
, 0x000080ff, "Lit quad with non-affine matrix"},
4867 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
4868 IDirect3DVertexBuffer
*src_vb1
, *src_vb2
, *dst_vb
;
4869 IDirect3DViewport3
*viewport
, *viewport2
;
4870 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
4871 struct vertex_normal
*src_data2
;
4872 IDirect3DMaterial3
*material
;
4873 D3DMATERIALHANDLE mat_handle
;
4874 D3DVERTEXBUFFERDESC vb_desc
;
4875 IDirect3DDevice3
*device
;
4876 struct vertex
*src_data1
;
4877 IDirectDrawSurface4
*rt
;
4878 IDirect3DLight
*light
;
4879 unsigned int color
, i
;
4880 D3DLIGHT2 light_desc
;
4887 struct vec4 position
;
4888 unsigned int diffuse
, specular
;
4892 window
= create_window();
4893 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4895 skip("Failed to create a 3D device, skipping test.\n");
4896 DestroyWindow(window
);
4900 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4901 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4903 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4904 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4906 viewport
= create_viewport(device
, 0, 0, 640, 480);
4907 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4908 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4910 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4911 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4913 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4914 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4915 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4916 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4917 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4918 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4919 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4920 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4921 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4922 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4923 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
4924 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4925 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
4926 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4928 hr
= IDirect3DDevice3_BeginScene(device
);
4929 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4931 memset(&vb_desc
, 0, sizeof(vb_desc
));
4932 vb_desc
.dwSize
= sizeof(vb_desc
);
4933 vb_desc
.dwFVF
= fvf
;
4934 vb_desc
.dwNumVertices
= 2;
4935 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb1
, 0, NULL
);
4936 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4937 vb_desc
.dwSize
= sizeof(vb_desc
);
4938 vb_desc
.dwFVF
= nfvf
;
4939 vb_desc
.dwNumVertices
= 2;
4940 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb2
, 0, NULL
);
4941 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4943 memset(&vb_desc
, 0, sizeof(vb_desc
));
4944 vb_desc
.dwSize
= sizeof(vb_desc
);
4945 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4946 vb_desc
.dwNumVertices
= 4;
4947 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0, NULL
);
4948 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4950 hr
= IDirect3DVertexBuffer_Lock(src_vb1
, 0, (void **)&src_data1
, NULL
);
4951 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4952 memcpy(src_data1
, unlitquad
, sizeof(*src_data1
));
4953 memcpy(&src_data1
[1], litquad
, sizeof(*src_data1
));
4954 hr
= IDirect3DVertexBuffer_Unlock(src_vb1
);
4955 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4957 hr
= IDirect3DVertexBuffer_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4958 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4959 memcpy(src_data2
, unlitnquad
, sizeof(*src_data2
));
4960 memcpy(&src_data2
[1], litnquad
, sizeof(*src_data2
));
4961 hr
= IDirect3DVertexBuffer_Unlock(src_vb2
);
4962 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4964 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
4965 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4966 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4967 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0,
4968 1, src_vb1
, 0, device
, 0);
4969 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4970 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
4972 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4974 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4975 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4976 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 1,
4977 1, src_vb1
, 1, device
, 0);
4978 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4979 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4981 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4983 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4984 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4985 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 2,
4986 1, src_vb2
, 0, device
, 0);
4987 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4988 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4990 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4992 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4993 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4994 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 3,
4995 1, src_vb2
, 1, device
, 0);
4996 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4997 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4999 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5001 hr
= IDirect3DDevice3_EndScene(device
);
5002 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5004 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5005 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5007 color
= get_surface_color(rt
, 160, 360);
5008 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
5009 ok(dst_data
[0].diffuse
== 0xffff0000,
5010 "Unlit quad without normals has color 0x%08x, expected 0xffff0000.\n", dst_data
[0].diffuse
);
5011 ok(!dst_data
[0].specular
,
5012 "Unexpected specular color 0x%08x.\n", dst_data
[0].specular
);
5014 color
= get_surface_color(rt
, 160, 120);
5015 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
5016 ok(dst_data
[1].diffuse
== 0xff00ff00,
5017 "Lit quad without normals has color 0x%08x, expected 0xff000000.\n", dst_data
[1].diffuse
);
5018 ok(!dst_data
[1].specular
,
5019 "Unexpected specular color 0x%08x.\n", dst_data
[1].specular
);
5021 color
= get_surface_color(rt
, 480, 360);
5022 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x.\n", color
);
5023 ok(dst_data
[2].diffuse
== 0xff0000ff,
5024 "Unlit quad with normals has color 0x%08x, expected 0xff0000ff.\n", dst_data
[2].diffuse
);
5025 ok(!dst_data
[2].specular
,
5026 "Unexpected specular color 0x%08x.\n", dst_data
[2].specular
);
5028 color
= get_surface_color(rt
, 480, 120);
5029 ok(color
== 0x00ffff00, "Lit quad with normals has color 0x%08x.\n", color
);
5030 ok(dst_data
[3].diffuse
== 0xffffff00,
5031 "Lit quad with normals has color 0x%08x, expected 0xff000000.\n", dst_data
[3].diffuse
);
5032 ok(!dst_data
[3].specular
,
5033 "Unexpected specular color 0x%08x.\n", dst_data
[3].specular
);
5035 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
5036 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5038 material
= create_diffuse_and_ambient_material(device
, 0.0f
, 1.0f
, 1.0f
, 0.5f
);
5039 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
5040 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5041 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
5042 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5043 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff008000);
5044 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5046 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
5047 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5048 memset(&light_desc
, 0, sizeof(light_desc
));
5049 light_desc
.dwSize
= sizeof(light_desc
);
5050 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
5051 U1(light_desc
.dcvColor
).r
= 1.0f
;
5052 U2(light_desc
.dcvColor
).g
= 1.0f
;
5053 U3(light_desc
.dcvColor
).b
= 1.0f
;
5054 U4(light_desc
.dcvColor
).a
= 0.5f
;
5055 U3(light_desc
.dvDirection
).z
= 1.0f
;
5056 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
5057 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5058 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
5059 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5060 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
5061 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
5063 viewport2
= create_viewport(device
, 0, 0, 640, 480);
5064 hr
= IDirect3DViewport3_AddLight(viewport2
, light
);
5065 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
5066 IDirect3DViewport3_Release(viewport2
);
5068 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
5069 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5071 hr
= IDirect3DDevice3_BeginScene(device
);
5072 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5074 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, nquad
,
5076 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5078 hr
= IDirect3DDevice3_EndScene(device
);
5079 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5081 color
= get_surface_color(rt
, 320, 240);
5082 ok(color
== 0x00008000, "Lit quad with no light has color 0x%08x.\n", color
);
5084 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
5085 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
5086 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5087 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
5088 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5089 light_desc
.dwFlags
= 0;
5090 hr
= IDirect3DLight_GetLight(light
, (D3DLIGHT
*)&light_desc
);
5091 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5092 ok(light_desc
.dwFlags
== D3DLIGHT_ACTIVE
, "Got unexpected flags %#lx.\n", light_desc
.dwFlags
);
5094 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
5095 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5097 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5099 hr
= IDirect3DVertexBuffer_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
5100 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5101 memcpy(src_data2
, tests
[i
].quad
, sizeof(*src_data2
));
5102 hr
= IDirect3DVertexBuffer_Unlock(src_vb2
);
5103 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5105 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
5106 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5108 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
5109 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5111 hr
= IDirect3DDevice3_BeginScene(device
);
5112 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5114 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
5115 1, src_vb2
, 0, device
, 0);
5116 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5117 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
5119 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5121 hr
= IDirect3DDevice3_EndScene(device
);
5122 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5124 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5125 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5127 color
= get_surface_color(rt
, 320, 240);
5128 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
5129 ok(dst_data
[0].diffuse
== (tests
[i
].expected
| 0xff000000),
5130 "%s has color 0x%08x.\n", tests
[i
].message
, dst_data
[0].diffuse
);
5131 ok(!dst_data
[0].specular
,
5132 "%s has specular color 0x%08x.\n", tests
[i
].message
, dst_data
[0].specular
);
5134 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
5135 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5138 IDirect3DVertexBuffer_Release(src_vb1
);
5139 IDirect3DVertexBuffer_Release(src_vb2
);
5140 IDirect3DVertexBuffer_Release(dst_vb
);
5142 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
5143 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5144 IDirect3DLight_Release(light
);
5145 destroy_material(material
);
5146 IDirect3DViewport3_Release(viewport
);
5147 IDirectDrawSurface4_Release(rt
);
5148 refcount
= IDirect3DDevice3_Release(device
);
5149 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5150 IDirect3D3_Release(d3d
);
5151 DestroyWindow(window
);
5154 static void test_specular_lighting(void)
5156 static const unsigned int vertices_side
= 5;
5157 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
5158 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5159 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
5160 static D3DMATRIX mat
=
5162 1.0f
, 0.0f
, 0.0f
, 0.0f
,
5163 0.0f
, 1.0f
, 0.0f
, 0.0f
,
5164 0.0f
, 0.0f
, 1.0f
, 0.0f
,
5165 0.0f
, 0.0f
, 0.0f
, 1.0f
,
5167 static const struct vertex
5169 struct vec3 position
;
5174 {{-0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5175 {{ 0.0f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5176 {{ 0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5177 {{-0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5178 {{ 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5179 {{ 0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5180 {{-0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5181 {{ 0.0f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5182 {{ 0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
5185 static D3DLIGHT2 directional
=
5188 D3DLIGHT_DIRECTIONAL
,
5189 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5190 {{0.0f
}, {0.0f
}, {0.0f
}},
5191 {{0.0f
}, {0.0f
}, {1.0f
}},
5197 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5198 {{0.0f
}, {0.0f
}, {0.0f
}},
5199 {{0.0f
}, {0.0f
}, {0.0f
}},
5208 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5209 {{0.0f
}, {0.0f
}, {0.0f
}},
5210 {{0.0f
}, {0.0f
}, {1.0f
}},
5214 M_PI
/ 12.0f
, M_PI
/ 3.0f
5219 D3DLIGHT_PARALLELPOINT
,
5220 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5221 {{0.5f
}, {0.0f
}, {-1.0f
}},
5222 {{0.0f
}, {0.0f
}, {0.0f
}},
5228 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5229 {{-1.1f
}, {0.0f
}, {1.1f
}},
5230 {{0.0f
}, {0.0f
}, {0.0f
}},
5239 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
5240 {{0.0f
}, {0.0f
}, {0.1f
}},
5241 {{0.0f
}, {0.0f
}, {0.0f
}},
5246 static const struct expected_color
5248 unsigned int x
, y
, color
;
5250 expected_directional
[] =
5252 {160, 120, 0x003c3c3c},
5253 {320, 120, 0x00717171},
5254 {480, 120, 0x003c3c3c},
5255 {160, 240, 0x00717171},
5256 {320, 240, 0x00ffffff},
5257 {480, 240, 0x00717171},
5258 {160, 360, 0x003c3c3c},
5259 {320, 360, 0x00717171},
5260 {480, 360, 0x003c3c3c},
5264 {160, 120, 0x00000000},
5265 {320, 120, 0x00090909},
5266 {480, 120, 0x00000000},
5267 {160, 240, 0x00090909},
5268 {320, 240, 0x00fafafa},
5269 {480, 240, 0x00090909},
5270 {160, 360, 0x00000000},
5271 {320, 360, 0x00090909},
5272 {480, 360, 0x00000000},
5276 {160, 120, 0x00000000},
5277 {320, 120, 0x00020202},
5278 {480, 120, 0x00000000},
5279 {160, 240, 0x00020202},
5280 {320, 240, 0x00fafafa},
5281 {480, 240, 0x00020202},
5282 {160, 360, 0x00000000},
5283 {320, 360, 0x00020202},
5284 {480, 360, 0x00000000},
5286 expected_parallelpoint
[] =
5288 {160, 120, 0x00050505},
5289 {320, 120, 0x002c2c2c},
5290 {480, 120, 0x006e6e6e},
5291 {160, 240, 0x00090909},
5292 {320, 240, 0x00717171},
5293 {480, 240, 0x00ffffff},
5294 {160, 360, 0x00050505},
5295 {320, 360, 0x002c2c2c},
5296 {480, 360, 0x006e6e6e},
5298 expected_point_far
[] =
5300 {160, 120, 0x00000000},
5301 {320, 120, 0x00000000},
5302 {480, 120, 0x00000000},
5303 {160, 240, 0x00000000},
5304 {320, 240, 0x00ffffff},
5305 {480, 240, 0x00000000},
5306 {160, 360, 0x00000000},
5307 {320, 360, 0x00000000},
5308 {480, 360, 0x00000000},
5312 {160, 120, 0x00000000},
5313 {320, 120, 0x00000000},
5314 {480, 120, 0x00000000},
5315 {160, 240, 0x00000000},
5316 {320, 240, 0x00000000},
5317 {480, 240, 0x00000000},
5318 {160, 360, 0x00000000},
5319 {320, 360, 0x00000000},
5320 {480, 360, 0x00000000},
5326 float specular_power
;
5327 const struct expected_color
*expected
;
5328 unsigned int expected_count
;
5332 /* D3DRENDERSTATE_LOCALVIEWER does not exist in D3D < 7 (the behavior is
5333 * the one you get on newer D3D versions with it set as TRUE). */
5334 {&directional
, FALSE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
5335 {&directional
, TRUE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
5336 {&point
, TRUE
, 30.0f
, expected_point
, ARRAY_SIZE(expected_point
)},
5337 {&spot
, TRUE
, 30.0f
, expected_spot
, ARRAY_SIZE(expected_spot
)},
5338 {¶llelpoint
, TRUE
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
5339 {&point_side
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5340 {&point_far
, TRUE
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
5341 {&directional
, FALSE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5342 {&directional
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5343 {&point
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5344 {&spot
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5345 {¶llelpoint
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5346 {&point_far
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
5349 IDirect3DLight
*light
, *dummy_lights
[64];
5350 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
5351 struct vertex
*quad
, *src_data
;
5352 unsigned int color
, i
, j
, x
, y
;
5353 D3DVERTEXBUFFERDESC vb_desc
;
5354 D3DMATERIALHANDLE mat_handle
;
5355 IDirect3DViewport3
*viewport
;
5356 IDirect3DMaterial3
*material
;
5357 IDirect3DDevice3
*device
;
5358 IDirectDrawSurface4
*rt
;
5359 D3DLIGHT2 light_desc
;
5366 struct vec4 position
;
5367 unsigned int diffuse
, specular
;
5371 window
= create_window();
5372 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5374 skip("Failed to create a 3D device, skipping test.\n");
5375 DestroyWindow(window
);
5379 quad
= heap_alloc(vertices_side
* vertices_side
* sizeof(*quad
));
5380 indices
= heap_alloc(indices_count
* sizeof(*indices
));
5381 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
5383 for (x
= 0; x
< vertices_side
; ++x
)
5385 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
5386 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
5387 quad
[i
].position
.z
= 1.0f
;
5388 quad
[i
].normal
.x
= 0.0f
;
5389 quad
[i
].normal
.y
= 0.0f
;
5390 quad
[i
++].normal
.z
= -1.0f
;
5393 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
5395 for (x
= 0; x
< (vertices_side
- 1); ++x
)
5397 indices
[i
++] = y
* vertices_side
+ x
+ 1;
5398 indices
[i
++] = y
* vertices_side
+ x
;
5399 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
5400 indices
[i
++] = y
* vertices_side
+ x
+ 1;
5401 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
5402 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
5406 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5407 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5409 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
5410 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5412 viewport
= create_viewport(device
, 0, 0, 640, 480);
5413 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
5414 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5416 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
5417 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5418 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
5419 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5420 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
5421 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5422 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
5423 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5424 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
5425 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5427 memset(&light_desc
, 0, sizeof(light_desc
));
5428 light_desc
.dwSize
= sizeof(light_desc
);
5429 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
5430 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
5431 U3(light_desc
.dvDirection
).z
= 1.0f
;
5433 for (i
= 0; i
< ARRAY_SIZE(dummy_lights
); ++i
)
5435 hr
= IDirect3D3_CreateLight(d3d
, &dummy_lights
[i
], NULL
);
5436 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5437 hr
= IDirect3DViewport3_AddLight(viewport
, dummy_lights
[i
]);
5438 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5439 hr
= IDirect3DLight_SetLight(dummy_lights
[i
], (D3DLIGHT
*)&light_desc
);
5440 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5443 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
5444 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5445 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
5446 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5448 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
5449 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5451 memset(&vb_desc
, 0, sizeof(vb_desc
));
5452 vb_desc
.dwSize
= sizeof(vb_desc
);
5453 vb_desc
.dwFVF
= fvf
;
5454 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
5455 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0, NULL
);
5456 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5457 hr
= IDirect3DVertexBuffer_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
5458 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5459 memcpy(src_data
, vertices
, sizeof(vertices
));
5460 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
5461 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5463 memset(&vb_desc
, 0, sizeof(vb_desc
));
5464 vb_desc
.dwSize
= sizeof(vb_desc
);
5465 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
5466 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
5467 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0, NULL
);
5468 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5470 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
5472 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
5473 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
5474 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5476 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
5477 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5479 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 0.5f
, tests
[i
].specular_power
);
5480 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
5481 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5482 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
5483 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5485 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
5486 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5488 hr
= IDirect3DDevice3_BeginScene(device
);
5489 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5491 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5492 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5493 memset(dst_data
, 0, sizeof(*dst_data
) * ARRAY_SIZE(vertices
));
5494 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
5495 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5497 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
5498 ARRAY_SIZE(vertices
), src_vb
, 0, device
, 0);
5499 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5500 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
5501 vertices_side
* vertices_side
, indices
, indices_count
, 0);
5502 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5504 hr
= IDirect3DDevice3_EndScene(device
);
5505 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5507 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
5508 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5510 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
5512 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
5513 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
5514 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
5515 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
5516 tests
[i
].expected
[j
].y
, color
, i
);
5517 ok(!dst_data
[j
].diffuse
, "Expected color 0x00000000 for vertex %u, got 0x%08x, case %u.\n",
5518 j
, dst_data
[j
].diffuse
, i
);
5519 ok(compare_color(dst_data
[j
].specular
, tests
[i
].expected
[j
].color
, 1),
5520 "Expected color 0x%08x for vertex %u, got 0x%08x, case %u.\n",
5521 tests
[i
].expected
[j
].color
, j
, dst_data
[j
].specular
, i
);
5523 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
5524 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5526 destroy_material(material
);
5529 for (i
= 0; i
< ARRAY_SIZE(dummy_lights
); ++i
)
5530 IDirect3DLight_Release(dummy_lights
[i
]);
5532 IDirect3DVertexBuffer_Release(dst_vb
);
5533 IDirect3DVertexBuffer_Release(src_vb
);
5535 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
5536 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5537 IDirect3DLight_Release(light
);
5538 IDirect3DViewport3_Release(viewport
);
5539 IDirectDrawSurface4_Release(rt
);
5540 refcount
= IDirect3DDevice3_Release(device
);
5541 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5542 IDirect3D3_Release(d3d
);
5543 DestroyWindow(window
);
5548 static void test_clear_rect_count(void)
5550 IDirectDrawSurface4
*rt
;
5551 IDirect3DDevice3
*device
;
5555 IDirect3DViewport3
*viewport
;
5556 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5558 window
= create_window();
5559 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5561 skip("Failed to create a 3D device, skipping test.\n");
5562 DestroyWindow(window
);
5566 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
5567 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5569 viewport
= create_viewport(device
, 0, 0, 640, 480);
5570 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
5571 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
5572 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00ffffff, 0.0f
, 0);
5573 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#lx.\n", hr
);
5574 hr
= IDirect3DViewport3_Clear2(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
, 0x00ff0000, 0.0f
, 0);
5575 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#lx.\n", hr
);
5576 hr
= IDirect3DViewport3_Clear2(viewport
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
5577 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#lx.\n", hr
);
5578 hr
= IDirect3DViewport3_Clear2(viewport
, 1, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
5579 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#lx.\n", hr
);
5581 color
= get_surface_color(rt
, 320, 240);
5582 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
5583 "Got unexpected color 0x%08x.\n", color
);
5585 IDirect3DViewport3_Release(viewport
);
5586 IDirectDrawSurface4_Release(rt
);
5587 IDirect3DDevice3_Release(device
);
5588 DestroyWindow(window
);
5591 static BOOL
test_mode_restored(IDirectDraw4
*ddraw
, HWND window
)
5593 DDSURFACEDESC2 ddsd1
, ddsd2
;
5596 memset(&ddsd1
, 0, sizeof(ddsd1
));
5597 ddsd1
.dwSize
= sizeof(ddsd1
);
5598 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd1
);
5599 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
5601 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5602 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5603 hr
= set_display_mode(ddraw
, 640, 480);
5604 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
5605 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5606 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5608 memset(&ddsd2
, 0, sizeof(ddsd2
));
5609 ddsd2
.dwSize
= sizeof(ddsd2
);
5610 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd2
);
5611 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
5612 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
5613 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
5615 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
5618 static void test_coop_level_versions(void)
5624 IDirectDrawSurface
*surface
;
5625 IDirectDraw4
*ddraw4
;
5628 window
= create_window();
5629 ddraw4
= create_ddraw();
5630 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
5631 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
5632 restored
= test_mode_restored(ddraw4
, window
);
5633 ok(restored
, "Display mode not restored in new ddraw object\n");
5635 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
5636 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
5637 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
5639 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5640 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
5641 restored
= test_mode_restored(ddraw4
, window
);
5642 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
5644 /* A successful one does */
5645 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5646 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5647 restored
= test_mode_restored(ddraw4
, window
);
5648 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
5650 IDirectDraw_Release(ddraw
);
5651 IDirectDraw4_Release(ddraw4
);
5653 ddraw4
= create_ddraw();
5654 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
5655 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
5656 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
5658 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
5659 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5660 restored
= test_mode_restored(ddraw4
, window
);
5661 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
5663 IDirectDraw_Release(ddraw
);
5664 IDirectDraw4_Release(ddraw4
);
5666 /* A failing call does not restore the ddraw2+ behavior */
5667 ddraw4
= create_ddraw();
5668 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
5669 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
5670 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
5672 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5673 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5674 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5675 ok(FAILED(hr
), "SetCooperativeLevel returned %#lx, expected failure.\n", hr
);
5676 restored
= test_mode_restored(ddraw4
, window
);
5677 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
5679 IDirectDraw_Release(ddraw
);
5680 IDirectDraw4_Release(ddraw4
);
5682 /* Neither does a sequence of successful calls with the new interface */
5683 ddraw4
= create_ddraw();
5684 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
5685 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
5686 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
5688 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5689 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5690 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
5691 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5692 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
5693 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5695 restored
= test_mode_restored(ddraw4
, window
);
5696 ok(!restored
, "Display mode restored after ddraw1-ddraw4 SetCooperativeLevel() call sequence\n");
5697 IDirectDraw_Release(ddraw
);
5698 IDirectDraw4_Release(ddraw4
);
5700 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
5701 ddraw4
= create_ddraw();
5702 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
5703 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
5704 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#lx.\n", hr
);
5706 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
5707 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
5709 memset(&ddsd
, 0, sizeof(ddsd
));
5710 ddsd
.dwSize
= sizeof(ddsd
);
5711 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5712 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5713 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
5714 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5715 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#lx.\n", hr
);
5716 IDirectDrawSurface_Release(surface
);
5717 restored
= test_mode_restored(ddraw4
, window
);
5718 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
5720 IDirectDraw_Release(ddraw
);
5721 IDirectDraw4_Release(ddraw4
);
5722 DestroyWindow(window
);
5725 static void test_lighting_interface_versions(void)
5727 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
5728 IDirect3DMaterial3
*emissive
;
5729 IDirect3DViewport3
*viewport
;
5730 IDirect3DDevice3
*device
;
5731 IDirectDrawSurface4
*rt
;
5732 unsigned int color
, i
;
5735 D3DMATERIALHANDLE mat_handle
;
5738 static D3DVERTEX quad
[] =
5740 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5741 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5742 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5743 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
5746 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
5749 struct vec3 position
;
5751 DWORD diffuse
, specular
;
5755 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5756 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5757 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5758 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5761 static D3DLVERTEX lquad
[] =
5763 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5764 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5765 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5766 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
5769 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
5772 struct vec3 position
;
5773 DWORD diffuse
, specular
;
5774 struct vec2 texcoord
;
5778 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5779 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5780 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5781 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
5784 static D3DTLVERTEX tlquad
[] =
5786 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5787 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5788 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5789 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5796 DWORD d3drs_lighting
, d3drs_specular
;
5802 /* Lighting is enabled when all of these conditions are met:
5803 * 1) No pretransformed position(D3DFVF_XYZRHW)
5804 * 2) Normals are available (D3DFVF_NORMAL)
5805 * 3) D3DDP_DONOTLIGHT is not set.
5807 * D3DRENDERSTATE_LIGHTING is ignored, it is not defined
5808 * in this d3d version */
5811 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
5812 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
5813 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5814 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5815 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
5816 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
5817 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5818 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5821 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x0000ff00},
5822 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5823 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5824 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5825 /* The specular color in the vertex is ignored because
5826 * D3DRENDERSTATE_COLORVERTEX is not enabled */
5827 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x0000ff00},
5828 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5829 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5830 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5833 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
5834 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
5835 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5836 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5837 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
5838 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
5839 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5840 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5843 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5844 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x00ff0000},
5845 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5846 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5847 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5848 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x00ff8080},
5849 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5850 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5853 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
5854 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
5855 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5856 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5857 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
5858 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
5859 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5860 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5863 window
= create_window();
5864 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5866 skip("Failed to create a 3D device, skipping test.\n");
5867 DestroyWindow(window
);
5871 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
5872 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5874 viewport
= create_viewport(device
, 0, 0, 640, 480);
5875 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
5876 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
5878 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
5879 hr
= IDirect3DMaterial3_GetHandle(emissive
, device
, &mat_handle
);
5880 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
5881 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
5882 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
5883 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5884 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#lx.\n", hr
);
5886 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
5887 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#lx.\n", hr
);
5888 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#lx, expected FALSE.\n", rs
);
5890 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5892 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
5893 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
5895 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
5896 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#lx.\n", hr
);
5897 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
5898 tests
[i
].d3drs_specular
);
5899 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#lx.\n", hr
);
5901 hr
= IDirect3DDevice3_BeginScene(device
);
5902 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
5903 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
5904 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
5905 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
5906 hr
= IDirect3DDevice3_EndScene(device
);
5907 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
5909 color
= get_surface_color(rt
, 320, 240);
5910 ok(compare_color(color
, tests
[i
].color
, 1),
5911 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
5912 color
, tests
[i
].color
, i
);
5915 destroy_material(emissive
);
5916 destroy_viewport(device
, viewport
);
5917 IDirectDrawSurface4_Release(rt
);
5918 ref
= IDirect3DDevice3_Release(device
);
5919 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
5920 DestroyWindow(window
);
5926 IDirectDraw4
*ddraw
;
5929 } activateapp_testdata
;
5931 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
5933 if (message
== WM_ACTIVATEAPP
)
5935 if (activateapp_testdata
.ddraw
)
5938 activateapp_testdata
.received
= FALSE
;
5939 hr
= IDirectDraw4_SetCooperativeLevel(activateapp_testdata
.ddraw
,
5940 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
5941 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#lx.\n", hr
);
5942 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
5944 activateapp_testdata
.received
= TRUE
;
5947 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
5950 static void test_coop_level_activateapp(void)
5952 IDirectDraw4
*ddraw
;
5956 DDSURFACEDESC2 ddsd
;
5957 IDirectDrawSurface4
*surface
;
5959 ddraw
= create_ddraw();
5960 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5962 wc
.lpfnWndProc
= activateapp_test_proc
;
5963 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
5964 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
5966 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
5967 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
5969 /* Exclusive with window already active. */
5970 SetForegroundWindow(window
);
5971 activateapp_testdata
.received
= FALSE
;
5972 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5973 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5974 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
5975 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5976 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5978 /* Exclusive with window not active. */
5979 SetForegroundWindow(GetDesktopWindow());
5980 activateapp_testdata
.received
= FALSE
;
5981 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5982 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5983 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5984 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5985 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5987 /* Normal with window not active, then exclusive with the same window. */
5988 SetForegroundWindow(GetDesktopWindow());
5989 activateapp_testdata
.received
= FALSE
;
5990 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5991 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5992 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
5993 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5994 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5995 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5996 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5997 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5999 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
6000 SetForegroundWindow(GetDesktopWindow());
6001 activateapp_testdata
.received
= FALSE
;
6002 activateapp_testdata
.ddraw
= ddraw
;
6003 activateapp_testdata
.window
= window
;
6004 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
6005 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6006 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6007 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
6008 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
6009 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6011 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
6012 * succeeding. Another switch to exclusive and back to normal is needed to release the
6013 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
6014 * WM_ACTIVATEAPP messages. */
6015 activateapp_testdata
.ddraw
= NULL
;
6016 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6017 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6018 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
6019 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6021 /* Setting DDSCL_NORMAL with recursive invocation. */
6022 SetForegroundWindow(GetDesktopWindow());
6023 activateapp_testdata
.received
= FALSE
;
6024 activateapp_testdata
.ddraw
= ddraw
;
6025 activateapp_testdata
.window
= window
;
6026 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
6027 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6028 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6029 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
6031 /* DDraw is in exclusive mode now. */
6032 memset(&ddsd
, 0, sizeof(ddsd
));
6033 ddsd
.dwSize
= sizeof(ddsd
);
6034 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6035 U5(ddsd
).dwBackBufferCount
= 1;
6036 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6037 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6038 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6039 IDirectDrawSurface4_Release(surface
);
6041 /* Recover again, just to be sure. */
6042 activateapp_testdata
.ddraw
= NULL
;
6043 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6044 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6045 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
6046 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6048 DestroyWindow(window
);
6049 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
6050 IDirectDraw4_Release(ddraw
);
6053 static void test_texturemanage(void)
6055 IDirectDraw4
*ddraw
;
6057 DDSURFACEDESC2 ddsd
;
6058 IDirectDrawSurface4
*surface
;
6060 DDCAPS hal_caps
, hel_caps
;
6061 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
6064 DWORD caps_in
, caps2_in
;
6066 DWORD caps_out
, caps2_out
;
6070 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6072 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6074 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6076 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6078 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
6079 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
6080 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
6081 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
6082 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
6083 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
6084 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
6085 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
6087 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6089 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6091 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6093 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6095 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6097 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
6099 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
6100 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
6101 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
6102 DDSCAPS_SYSTEMMEMORY
, 0},
6105 ddraw
= create_ddraw();
6106 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6107 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
6108 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6110 memset(&hal_caps
, 0, sizeof(hal_caps
));
6111 hal_caps
.dwSize
= sizeof(hal_caps
);
6112 memset(&hel_caps
, 0, sizeof(hel_caps
));
6113 hel_caps
.dwSize
= sizeof(hel_caps
);
6114 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
6115 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6116 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
6118 skip("Managed textures not supported, skipping managed texture test.\n");
6119 IDirectDraw4_Release(ddraw
);
6123 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6125 memset(&ddsd
, 0, sizeof(ddsd
));
6126 ddsd
.dwSize
= sizeof(ddsd
);
6127 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
6128 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
6129 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
6133 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6134 ok(hr
== tests
[i
].hr
, "Got unexpected, hr %#lx, case %u.\n", hr
, i
);
6138 memset(&ddsd
, 0, sizeof(ddsd
));
6139 ddsd
.dwSize
= sizeof(ddsd
);
6140 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6141 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6143 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
6144 "Input caps %#lx, %#lx, expected output caps %#lx, got %#lx, case %u.\n",
6145 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
6146 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
6147 "Input caps %#lx, %#lx, expected output caps %#lx, got %#lx, case %u.\n",
6148 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
6150 IDirectDrawSurface4_Release(surface
);
6153 IDirectDraw4_Release(ddraw
);
6156 #define SUPPORT_DXT1 0x01
6157 #define SUPPORT_DXT2 0x02
6158 #define SUPPORT_DXT3 0x04
6159 #define SUPPORT_DXT4 0x08
6160 #define SUPPORT_DXT5 0x10
6161 #define SUPPORT_YUY2 0x20
6162 #define SUPPORT_UYVY 0x40
6164 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
6166 DWORD
*supported_fmts
= ctx
;
6168 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
6169 return DDENUMRET_OK
;
6171 switch (fmt
->dwFourCC
)
6173 case MAKEFOURCC('D','X','T','1'):
6174 *supported_fmts
|= SUPPORT_DXT1
;
6176 case MAKEFOURCC('D','X','T','2'):
6177 *supported_fmts
|= SUPPORT_DXT2
;
6179 case MAKEFOURCC('D','X','T','3'):
6180 *supported_fmts
|= SUPPORT_DXT3
;
6182 case MAKEFOURCC('D','X','T','4'):
6183 *supported_fmts
|= SUPPORT_DXT4
;
6185 case MAKEFOURCC('D','X','T','5'):
6186 *supported_fmts
|= SUPPORT_DXT5
;
6188 case MAKEFOURCC('Y','U','Y','2'):
6189 *supported_fmts
|= SUPPORT_YUY2
;
6191 case MAKEFOURCC('U','Y','V','Y'):
6192 *supported_fmts
|= SUPPORT_UYVY
;
6198 return DDENUMRET_OK
;
6201 static void test_block_formats_creation(void)
6203 HRESULT hr
, expect_hr
;
6204 unsigned int i
, j
, w
, h
;
6206 IDirectDraw4
*ddraw
;
6208 IDirect3DDevice3
*device
;
6209 IDirectDrawSurface4
*surface
;
6210 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
6211 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
6212 DDSURFACEDESC2 ddsd
;
6221 unsigned int block_width
;
6222 unsigned int block_height
;
6223 unsigned int block_size
;
6224 BOOL create_size_checked
, overlay
;
6228 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
6229 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
6230 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
6231 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
6232 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
6233 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
6234 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
6244 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
6245 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
6247 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
6248 * Other hw / drivers successfully create those surfaces. Ignore them, this
6249 * suggests that no game uses this, otherwise Nvidia would support it. */
6251 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
6252 "videomemory texture", FALSE
6255 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
6256 "videomemory overlay", TRUE
6259 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
6260 "systemmemory texture", FALSE
6263 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
6264 "managed texture", FALSE
6276 enum size_type size_type
;
6282 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
6283 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6284 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
6285 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
6286 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
6287 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
6288 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
6289 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6290 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
6291 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
6292 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
6293 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
6294 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6295 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
6298 window
= create_window();
6299 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6301 skip("Failed to create a 3D device, skipping test.\n");
6302 DestroyWindow(window
);
6306 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
6307 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
6308 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
6309 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
6310 IDirect3D3_Release(d3d
);
6312 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
,
6314 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6316 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
6317 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6318 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
6319 num_fourcc_codes
* sizeof(*fourcc_codes
));
6322 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
6323 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6324 for (i
= 0; i
< num_fourcc_codes
; i
++)
6326 for (j
= 0; j
< ARRAY_SIZE(formats
); j
++)
6328 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
6329 supported_overlay_fmts
|= formats
[j
].support_flag
;
6332 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
6334 memset(&hal_caps
, 0, sizeof(hal_caps
));
6335 hal_caps
.dwSize
= sizeof(hal_caps
);
6336 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
6337 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6339 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
6341 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
6343 for (j
= 0; j
< ARRAY_SIZE(types
); j
++)
6347 if (formats
[i
].overlay
!= types
[j
].overlay
6348 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
6351 if (formats
[i
].overlay
)
6352 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
6354 support
= supported_fmts
& formats
[i
].support_flag
;
6356 for (w
= 1; w
<= 8; w
++)
6358 for (h
= 1; h
<= 8; h
++)
6360 BOOL block_aligned
= TRUE
;
6363 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
6364 block_aligned
= FALSE
;
6366 memset(&ddsd
, 0, sizeof(ddsd
));
6367 ddsd
.dwSize
= sizeof(ddsd
);
6368 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
6369 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
6370 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
6371 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6372 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
6373 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
6377 /* TODO: Handle power of two limitations. I cannot test the pow2
6378 * behavior on windows because I have no hardware that doesn't at
6379 * least support np2_conditional. There's probably no HW that
6380 * supports DXTN textures but no conditional np2 textures. */
6381 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
6382 expect_hr
= DDERR_INVALIDPARAMS
;
6383 else if (formats
[i
].create_size_checked
&& !block_aligned
)
6385 expect_hr
= DDERR_INVALIDPARAMS
;
6386 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
6392 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6395 "Got unexpected hr %#lx for format %s, resource type %s, size %ux%u, expected %#lx.\n",
6396 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
6399 IDirectDrawSurface4_Release(surface
);
6404 if (formats
[i
].overlay
)
6407 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
6409 memset(&ddsd
, 0, sizeof(ddsd
));
6410 ddsd
.dwSize
= sizeof(ddsd
);
6411 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
6412 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
6414 switch (user_mem_tests
[j
].size_type
)
6416 case SIZE_TYPE_ZERO
:
6417 U1(ddsd
).dwLinearSize
= 0;
6420 case SIZE_TYPE_PITCH
:
6421 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
6424 case SIZE_TYPE_SIZE
:
6425 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
6428 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
6430 ddsd
.lpSurface
= mem
;
6431 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6432 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
6433 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
6437 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6438 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#lx, format %s.\n", j
, hr
, formats
[i
].name
);
6443 memset(&ddsd
, 0, sizeof(ddsd
));
6444 ddsd
.dwSize
= sizeof(ddsd
);
6445 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6446 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", j
, hr
);
6447 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
6448 "Test %u: Got unexpected flags %#lx.\n", j
, ddsd
.dwFlags
);
6449 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
6450 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#lx.\n",
6451 j
, U1(ddsd
).dwLinearSize
);
6453 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
6454 "Test %u: Got unexpected linear size %#lx, expected %#x.\n",
6455 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
6456 IDirectDrawSurface4_Release(surface
);
6460 HeapFree(GetProcessHeap(), 0, mem
);
6462 IDirectDraw4_Release(ddraw
);
6463 IDirect3DDevice3_Release(device
);
6464 DestroyWindow(window
);
6467 struct format_support_check
6469 const DDPIXELFORMAT
*format
;
6473 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
6475 struct format_support_check
*format
= ctx
;
6477 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
6479 format
->supported
= TRUE
;
6480 return DDENUMRET_CANCEL
;
6483 return DDENUMRET_OK
;
6486 static void test_unsupported_formats(void)
6489 BOOL expect_success
;
6491 IDirectDraw4
*ddraw
;
6493 IDirect3DDevice3
*device
;
6494 IDirectDrawSurface4
*surface
;
6495 DDSURFACEDESC2 ddsd
;
6497 DWORD expected_caps
;
6508 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
6509 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
6515 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6516 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
6520 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
6522 window
= create_window();
6523 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6525 skip("Failed to create a 3D device, skipping test.\n");
6526 DestroyWindow(window
);
6530 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
6531 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
6532 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
6533 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
6534 IDirect3D3_Release(d3d
);
6536 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
6538 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
6539 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
6540 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6542 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
6544 memset(&ddsd
, 0, sizeof(ddsd
));
6545 ddsd
.dwSize
= sizeof(ddsd
);
6546 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6547 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
6550 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
6552 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
6553 expect_success
= FALSE
;
6555 expect_success
= TRUE
;
6557 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6558 ok(SUCCEEDED(hr
) == expect_success
,
6559 "Got unexpected hr %#lx for format %s, caps %#lx, expected %s.\n",
6560 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
6564 memset(&ddsd
, 0, sizeof(ddsd
));
6565 ddsd
.dwSize
= sizeof(ddsd
);
6566 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6567 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6569 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
6570 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6571 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
6572 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6573 else if (check
.supported
)
6574 expected_caps
= DDSCAPS_VIDEOMEMORY
;
6576 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
6578 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
6579 "Expected caps %#lx, format %s, input caps %#lx.\n",
6580 expected_caps
, formats
[i
].name
, caps
[j
]);
6582 IDirectDrawSurface4_Release(surface
);
6586 IDirectDraw4_Release(ddraw
);
6587 IDirect3DDevice3_Release(device
);
6588 DestroyWindow(window
);
6591 static void test_rt_caps(const GUID
*device_guid
)
6593 PALETTEENTRY palette_entries
[256];
6594 IDirectDrawPalette
*palette
;
6595 BOOL software_device
;
6596 IDirectDraw4
*ddraw
;
6597 DDPIXELFORMAT z_fmt
;
6605 static const DDPIXELFORMAT p8_fmt
=
6607 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
6608 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
6613 const DDPIXELFORMAT
*pf
;
6616 HRESULT create_device_hr
;
6617 HRESULT set_rt_hr
, alternative_set_rt_hr
;
6623 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6631 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6639 DDSCAPS_OFFSCREENPLAIN
,
6647 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6649 D3DERR_SURFACENOTINVIDMEM
,
6655 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6663 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
6687 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6689 D3DERR_SURFACENOTINVIDMEM
,
6695 DDSCAPS_SYSTEMMEMORY
,
6703 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6704 DDSCAPS2_TEXTUREMANAGE
,
6705 D3DERR_SURFACENOTINVIDMEM
,
6711 DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
,
6712 DDSCAPS2_D3DTEXTUREMANAGE
,
6713 D3DERR_SURFACENOTINVIDMEM
,
6727 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6729 DDERR_NOPALETTEATTACHED
,
6735 DDSCAPS_OFFSCREENPLAIN
,
6743 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
6745 DDERR_NOPALETTEATTACHED
,
6751 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6759 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
6762 DDERR_INVALIDPIXELFORMAT
,
6767 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6770 DDERR_INVALIDPIXELFORMAT
,
6783 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
6786 DDERR_INVALIDPIXELFORMAT
,
6791 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
6799 software_device
= is_software_device_type(device_guid
);
6801 window
= create_window();
6802 ddraw
= create_ddraw();
6803 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6804 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6805 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6807 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
6809 skip("D3D interface is not available, skipping test.\n");
6813 memset(&z_fmt
, 0, sizeof(z_fmt
));
6814 hr
= IDirect3D3_EnumZBufferFormats(d3d
, device_guid
, enum_z_fmt
, &z_fmt
);
6815 if (FAILED(hr
) || !z_fmt
.dwSize
)
6817 skip("No depth buffer formats available, software_device %u, skipping test.\n", software_device
);
6818 IDirect3D3_Release(d3d
);
6822 memset(palette_entries
, 0, sizeof(palette_entries
));
6823 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6824 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6826 memset(&hal_caps
, 0, sizeof(hal_caps
));
6827 hal_caps
.dwSize
= sizeof(hal_caps
);
6828 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
6829 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
6831 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6833 IDirectDrawSurface4
*surface
, *rt
, *expected_rt
, *tmp
;
6834 DWORD caps_in
, expected_caps
;
6835 DDSURFACEDESC2 surface_desc
;
6836 IDirect3DDevice3
*device
;
6837 HRESULT expected_hr
;
6839 caps_in
= test_data
[i
].caps_in
;
6841 memset(&surface_desc
, 0, sizeof(surface_desc
));
6842 surface_desc
.dwSize
= sizeof(surface_desc
);
6843 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6844 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
6845 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6846 if (test_data
[i
].pf
)
6848 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6849 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6851 surface_desc
.dwWidth
= 640;
6852 surface_desc
.dwHeight
= 480;
6853 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6854 expected_hr
= DDERR_NODIRECTDRAWHW
;
6856 expected_hr
= DD_OK
;
6857 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6858 ok(hr
== expected_hr
|| (software_device
&& (surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
))
6859 == (DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
) && hr
== DDERR_UNSUPPORTED
)
6860 || broken(software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
),
6861 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6865 memset(&surface_desc
, 0, sizeof(surface_desc
));
6866 surface_desc
.dwSize
= sizeof(surface_desc
);
6867 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
6868 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6870 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || (test_data
[i
].caps2_in
& (DDSCAPS2_D3DTEXTUREMANAGE
6871 | DDSCAPS2_TEXTUREMANAGE
)) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6872 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
6874 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
6876 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
6877 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
6878 || (software_device
&& test_data
[i
].pf
== &z_fmt
6879 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
6880 "Got unexpected caps %#lx, expected %#lx, test %u, software_device %u.\n",
6881 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
6883 ok(surface_desc
.ddsCaps
.dwCaps2
== test_data
[i
].caps2_in
,
6884 "Got unexpected caps2 %#lx, expected %#lx, test %u, software_device %u.\n",
6885 surface_desc
.ddsCaps
.dwCaps2
, test_data
[i
].caps2_in
, i
, software_device
);
6887 hr
= IDirect3D3_CreateDevice(d3d
, device_guid
, surface
, &device
, NULL
);
6889 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
6890 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
6891 ? DD_OK
: test_data
[i
].create_device_hr
))),
6892 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6895 if (hr
== DDERR_NOPALETTEATTACHED
)
6897 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
6898 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6899 if (software_device
)
6901 /* _CreateDevice succeeds with software device, but the palette gets extra reference
6902 * on Windows (probably due to a bug) which doesn't go away on the device and surface
6903 * destruction and ddraw is not destroyed cleanly, so skipping this test. */
6904 IDirectDrawSurface4_Release(surface
);
6907 hr
= IDirect3D3_CreateDevice(d3d
, device_guid
, surface
, &device
, NULL
);
6908 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6909 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
6910 hr
, i
, software_device
);
6912 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
6913 hr
, i
, software_device
);
6915 IDirectDrawSurface4_Release(surface
);
6917 memset(&surface_desc
, 0, sizeof(surface_desc
));
6918 surface_desc
.dwSize
= sizeof(surface_desc
);
6919 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6920 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6921 surface_desc
.dwWidth
= 640;
6922 surface_desc
.dwHeight
= 480;
6923 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6924 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6926 hr
= IDirect3D3_CreateDevice(d3d
, device_guid
, surface
, &device
, NULL
);
6927 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6930 memset(&surface_desc
, 0, sizeof(surface_desc
));
6931 surface_desc
.dwSize
= sizeof(surface_desc
);
6932 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6933 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6934 surface_desc
.ddsCaps
.dwCaps2
= test_data
[i
].caps2_in
;
6935 if (test_data
[i
].pf
)
6937 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6938 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6940 surface_desc
.dwWidth
= 640;
6941 surface_desc
.dwHeight
= 480;
6942 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
6943 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6945 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
6946 ok(hr
== test_data
[i
].set_rt_hr
|| (software_device
&& hr
== DDERR_NOPALETTEATTACHED
)
6947 || broken(hr
== test_data
[i
].alternative_set_rt_hr
),
6948 "Got unexpected hr %#lx, test %u, software_device %u.\n",
6949 hr
, i
, software_device
);
6950 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
6953 expected_rt
= surface
;
6955 hr
= IDirect3DDevice3_GetRenderTarget(device
, &tmp
);
6956 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
6957 ok(tmp
== expected_rt
, "Got unexpected rt %p, test %u, software_device %u.\n", tmp
, i
, software_device
);
6959 IDirectDrawSurface4_Release(tmp
);
6960 IDirectDrawSurface4_Release(rt
);
6961 refcount
= IDirect3DDevice3_Release(device
);
6962 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
6963 refcount
= IDirectDrawSurface4_Release(surface
);
6964 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
6967 refcount
= IDirectDrawPalette_Release(palette
);
6968 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6969 IDirect3D3_Release(d3d
);
6972 refcount
= IDirectDraw4_Release(ddraw
);
6973 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
6974 DestroyWindow(window
);
6977 static void test_primary_caps(void)
6979 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6980 IDirectDrawSurface4
*surface
;
6981 DDSURFACEDESC2 surface_desc
;
6982 IDirectDraw4
*ddraw
;
6992 DWORD back_buffer_count
;
7000 DDSCAPS_PRIMARYSURFACE
,
7003 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
7007 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
7014 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
7021 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
7028 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
7035 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
7042 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
7049 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
7056 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
7058 DDERR_NOEXCLUSIVEMODE
,
7062 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
7063 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
7069 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
7070 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
7073 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
7076 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
7077 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
7083 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
7084 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
7091 window
= create_window();
7092 ddraw
= create_ddraw();
7093 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7095 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7097 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
7098 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7100 memset(&surface_desc
, 0, sizeof(surface_desc
));
7101 surface_desc
.dwSize
= sizeof(surface_desc
);
7102 surface_desc
.dwFlags
= DDSD_CAPS
;
7103 if (test_data
[i
].back_buffer_count
!= ~0u)
7104 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7105 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
7106 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
7107 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7108 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
7112 memset(&surface_desc
, 0, sizeof(surface_desc
));
7113 surface_desc
.dwSize
= sizeof(surface_desc
);
7114 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
7115 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
7116 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
7117 "Test %u: Got unexpected caps %#lx, expected %#lx.\n",
7118 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
7120 IDirectDrawSurface4_Release(surface
);
7123 refcount
= IDirectDraw4_Release(ddraw
);
7124 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
7125 DestroyWindow(window
);
7128 static void test_surface_lock(void)
7130 IDirectDraw4
*ddraw
;
7131 IDirect3D3
*d3d
= NULL
;
7132 IDirectDrawSurface4
*surface
;
7136 DDSURFACEDESC2 ddsd
;
7138 DDPIXELFORMAT z_fmt
;
7148 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
7150 "videomemory offscreenplain"
7153 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
7155 "systemmemory offscreenplain"
7158 DDSCAPS_PRIMARYSURFACE
,
7163 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
7165 "videomemory texture"
7168 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
7170 "opaque videomemory texture"
7173 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
7175 "systemmemory texture"
7179 DDSCAPS2_TEXTUREMANAGE
,
7184 DDSCAPS2_D3DTEXTUREMANAGE
,
7189 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
7190 "opaque managed texture"
7194 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
7195 "opaque managed texture"
7198 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
7209 window
= create_window();
7210 ddraw
= create_ddraw();
7211 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7212 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7213 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7215 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
7217 skip("D3D interface is not available, skipping test.\n");
7221 memset(&z_fmt
, 0, sizeof(z_fmt
));
7222 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
7223 if (FAILED(hr
) || !z_fmt
.dwSize
)
7225 skip("No depth buffer formats available, skipping test.\n");
7229 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
7231 memset(&ddsd
, 0, sizeof(ddsd
));
7232 ddsd
.dwSize
= sizeof(ddsd
);
7233 ddsd
.dwFlags
= DDSD_CAPS
;
7234 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7236 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
7240 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
7242 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
7243 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
7245 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7246 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
7248 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7249 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
7251 memset(&ddsd
, 0, sizeof(ddsd
));
7252 ddsd
.dwSize
= sizeof(ddsd
);
7253 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7254 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
7257 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
7258 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
7261 memset(&ddsd
, 0, sizeof(ddsd
));
7262 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7263 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, tests
[i
].name
);
7265 IDirectDrawSurface4_Release(surface
);
7270 IDirect3D3_Release(d3d
);
7271 refcount
= IDirectDraw4_Release(ddraw
);
7272 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
7273 DestroyWindow(window
);
7276 static void test_surface_discard(void)
7278 IDirect3DDevice3
*device
;
7280 IDirectDraw4
*ddraw
;
7283 DDSURFACEDESC2 ddsd
;
7284 IDirectDrawSurface4
*surface
, *target
;
7293 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
7294 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
7295 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
7296 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
7297 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
7298 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
7299 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
7300 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
7304 window
= create_window();
7306 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
7310 /* Sigh. Anything other than the first run of the loop randomly fails with
7311 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
7312 * the blit fails, but with sleeps added between surface creation and lock
7313 * the lock can fail too. Interestingly ddraw claims the render target has
7314 * been lost, not the test surface.
7316 * Recreating ddraw every iteration seems to fix this. */
7317 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
7319 skip("Failed to create a 3D device, skipping test.\n");
7320 DestroyWindow(window
);
7323 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
7324 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
7325 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
7326 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
7327 hr
= IDirect3DDevice3_GetRenderTarget(device
, &target
);
7328 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
7330 memset(&ddsd
, 0, sizeof(ddsd
));
7331 ddsd
.dwSize
= sizeof(ddsd
);
7332 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7333 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7334 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
7337 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7338 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#lx, case %u.\n", hr
, i
);
7340 memset(&ddsd
, 0, sizeof(ddsd
));
7341 ddsd
.dwSize
= sizeof(ddsd
);
7342 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7343 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
7344 addr
= ddsd
.lpSurface
;
7345 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
7346 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
7348 memset(&ddsd
, 0, sizeof(ddsd
));
7349 ddsd
.dwSize
= sizeof(ddsd
);
7350 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7351 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
7352 discarded
= ddsd
.lpSurface
!= addr
;
7353 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
7354 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
7356 hr
= IDirectDrawSurface4_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
7357 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
7359 memset(&ddsd
, 0, sizeof(ddsd
));
7360 ddsd
.dwSize
= sizeof(ddsd
);
7361 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
7362 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
7363 discarded
|= ddsd
.lpSurface
!= addr
;
7364 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
7365 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
7367 IDirectDrawSurface4_Release(surface
);
7369 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
7370 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
7371 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
7373 IDirectDrawSurface4_Release(target
);
7374 IDirectDraw4_Release(ddraw
);
7375 IDirect3D3_Release(d3d
);
7376 IDirect3DDevice3_Release(device
);
7379 DestroyWindow(window
);
7382 static void test_flip(void)
7384 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
7385 IDirectDrawSurface4
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
7386 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
7387 DDSURFACEDESC2 surface_desc
;
7388 unsigned int color
, i
;
7389 BOOL sysmem_primary
;
7390 IDirectDraw4
*ddraw
;
7391 DWORD expected_caps
;
7403 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
7404 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
7405 {"TEXTURE", DDSCAPS_TEXTURE
},
7408 window
= create_window();
7409 ddraw
= create_ddraw();
7410 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7412 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7413 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7415 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7417 /* Creating a flippable texture induces a BSoD on some versions of the
7418 * Intel graphics driver. At least Intel GMA 950 with driver version
7419 * 6.14.10.4926 on Windows XP SP3 is affected. */
7420 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
7422 win_skip("Skipping flippable texture test.\n");
7426 memset(&surface_desc
, 0, sizeof(surface_desc
));
7427 surface_desc
.dwSize
= sizeof(surface_desc
);
7428 surface_desc
.dwFlags
= DDSD_CAPS
;
7429 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7430 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
7431 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7432 surface_desc
.dwWidth
= 512;
7433 surface_desc
.dwHeight
= 512;
7434 U5(surface_desc
).dwBackBufferCount
= 3;
7435 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7436 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7438 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
7439 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
7440 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7441 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7443 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
7444 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
7445 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7446 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7448 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
7449 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
7450 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
7451 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7455 memset(&surface_desc
, 0, sizeof(surface_desc
));
7456 surface_desc
.dwSize
= sizeof(surface_desc
);
7457 hr
= IDirectDrawSurface4_GetSurfaceDesc(frontbuffer
, &surface_desc
);
7458 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
7459 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
7460 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7461 expected_caps
|= DDSCAPS_VISIBLE
;
7462 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7463 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7464 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
7466 hr
= IDirectDrawSurface4_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
7467 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7468 memset(&surface_desc
, 0, sizeof(surface_desc
));
7469 surface_desc
.dwSize
= sizeof(surface_desc
);
7470 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer1
, &surface_desc
);
7471 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
7472 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
7473 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7474 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
7475 expected_caps
|= DDSCAPS_BACKBUFFER
;
7476 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7477 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7479 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
7480 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7481 memset(&surface_desc
, 0, sizeof(surface_desc
));
7482 surface_desc
.dwSize
= sizeof(surface_desc
);
7483 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer2
, &surface_desc
);
7484 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
7485 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
7486 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7487 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
7488 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7489 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7491 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
7492 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7493 memset(&surface_desc
, 0, sizeof(surface_desc
));
7494 surface_desc
.dwSize
= sizeof(surface_desc
);
7495 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer3
, &surface_desc
);
7496 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
7497 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
7498 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
7499 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
7500 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
7502 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
7503 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7504 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
7505 test_data
[i
].name
, surface
, frontbuffer
);
7506 IDirectDrawSurface4_Release(surface
);
7508 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
7509 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
7510 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
7511 ok(hr
== DD_OK
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7512 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7513 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
7514 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7516 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7517 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7518 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
7519 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
7520 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7521 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
7522 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#lx.\n", test_data
[i
].name
, hr
);
7524 memset(&surface_desc
, 0, sizeof(surface_desc
));
7525 surface_desc
.dwSize
= sizeof(surface_desc
);
7526 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7527 surface_desc
.ddsCaps
.dwCaps
= 0;
7528 surface_desc
.dwWidth
= 640;
7529 surface_desc
.dwHeight
= 480;
7530 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7531 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7532 hr
= IDirectDrawSurface4_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
7533 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7534 IDirectDrawSurface4_Release(surface
);
7536 hr
= IDirectDrawSurface4_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
7537 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7538 hr
= IDirectDrawSurface4_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
7539 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7540 hr
= IDirectDrawSurface4_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
7541 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7542 hr
= IDirectDrawSurface4_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
7543 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
7545 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
7546 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
7547 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
7548 fill_surface(backbuffer1
, 0xffff0000);
7549 fill_surface(backbuffer2
, 0xff00ff00);
7550 fill_surface(backbuffer3
, 0xff0000ff);
7552 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7553 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7554 color
= get_surface_color(backbuffer1
, 320, 240);
7555 /* The testbot seems to just copy the contents of one surface to all the
7556 * others, instead of properly flipping. */
7557 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7558 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7559 color
= get_surface_color(backbuffer2
, 320, 240);
7560 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7561 fill_surface(backbuffer3
, 0xffff0000);
7563 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7564 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7565 color
= get_surface_color(backbuffer1
, 320, 240);
7566 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7567 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7568 color
= get_surface_color(backbuffer2
, 320, 240);
7569 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7570 fill_surface(backbuffer3
, 0xff00ff00);
7572 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
7573 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7574 color
= get_surface_color(backbuffer1
, 320, 240);
7575 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7576 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7577 color
= get_surface_color(backbuffer2
, 320, 240);
7578 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7579 fill_surface(backbuffer3
, 0xff0000ff);
7581 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
7582 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7583 color
= get_surface_color(backbuffer2
, 320, 240);
7584 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
7585 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7586 color
= get_surface_color(backbuffer3
, 320, 240);
7587 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7588 fill_surface(backbuffer1
, 0xffff0000);
7590 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
7591 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7592 color
= get_surface_color(backbuffer1
, 320, 240);
7593 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7594 color
= get_surface_color(backbuffer3
, 320, 240);
7595 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
7596 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7597 fill_surface(backbuffer2
, 0xff00ff00);
7599 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
7600 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
7601 color
= get_surface_color(backbuffer1
, 320, 240);
7602 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
7603 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7604 color
= get_surface_color(backbuffer2
, 320, 240);
7605 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
7607 IDirectDrawSurface4_Release(backbuffer3
);
7608 IDirectDrawSurface4_Release(backbuffer2
);
7609 IDirectDrawSurface4_Release(backbuffer1
);
7610 IDirectDrawSurface4_Release(frontbuffer
);
7613 refcount
= IDirectDraw4_Release(ddraw
);
7614 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
7615 DestroyWindow(window
);
7618 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
7620 memset(ddsd
, 0, sizeof(*ddsd
));
7621 ddsd
->dwSize
= sizeof(*ddsd
);
7624 static void test_set_surface_desc(void)
7626 IDirectDraw4
*ddraw
;
7629 DDSURFACEDESC2 ddsd
;
7630 IDirectDrawSurface4
*surface
;
7640 invalid_caps_tests
[] =
7642 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
7643 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
7644 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
7645 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
7646 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
7649 window
= create_window();
7650 ddraw
= create_ddraw();
7651 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7652 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7653 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7656 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7659 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7660 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7661 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7662 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7663 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7664 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7665 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7667 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7668 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7671 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7672 ddsd
.lpSurface
= data
;
7673 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7674 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7676 /* Redundantly setting the same lpSurface is not an error. */
7677 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7678 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7679 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
7680 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
7681 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7682 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
7684 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
7685 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
7686 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
7687 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
7688 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
7689 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
7692 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7693 ddsd
.lpSurface
= data
;
7694 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 1);
7695 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7697 ddsd
.lpSurface
= NULL
;
7698 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7699 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7701 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, NULL
, 0);
7702 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7704 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
7705 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
7706 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7707 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
7708 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#lx.\n", ddsd
.ddsCaps
.dwCaps2
);
7710 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
7711 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7712 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7714 ddsd
.dwFlags
= DDSD_CAPS
;
7715 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7716 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7718 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
7719 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
7720 ddsd
.lpSurface
= data
;
7721 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7722 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
7723 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7724 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7725 ok(hr
== DDERR_INVALIDCAPS
, "Got hr %#lx.\n", hr
);
7726 ddsd
.ddsCaps
.dwCaps
= 0;
7727 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
7728 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7729 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7731 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
7732 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
7733 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
7734 "Got unexpected caps %#lx.\n", ddsd
.ddsCaps
.dwCaps
);
7735 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#lx.\n", ddsd
.ddsCaps
.dwCaps2
);
7737 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
7739 ddsd
.dwFlags
= DDSD_HEIGHT
;
7741 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7742 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7744 ddsd
.lpSurface
= data
;
7745 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
7746 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7747 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7750 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7751 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7754 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
7755 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#lx.\n", hr
);
7756 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
7757 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
7759 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0 */
7761 ddsd
.dwFlags
= DDSD_PITCH
;
7762 U1(ddsd
).lPitch
= 8 * 4;
7763 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7764 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7766 ddsd
.dwFlags
= DDSD_WIDTH
;
7768 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7769 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7771 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
7772 ddsd
.lpSurface
= data
;
7773 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7774 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7776 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
7777 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7778 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7780 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7781 U1(ddsd
).lPitch
= 16 * 4;
7783 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7784 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7787 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
7788 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
7789 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %lu.\n", ddsd
.dwWidth
);
7790 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %lu.\n", ddsd
.dwHeight
);
7791 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %lu.\n", U1(ddsd
).lPitch
);
7793 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
7795 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
7796 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7797 U1(ddsd
).lPitch
= 4 * 4;
7798 ddsd
.lpSurface
= data
;
7799 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7800 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
7802 U1(ddsd
).lPitch
= 4;
7803 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7804 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#lx.\n", hr
);
7806 U1(ddsd
).lPitch
= 16 * 4 + 1;
7807 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7808 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7810 U1(ddsd
).lPitch
= 16 * 4 + 3;
7811 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7812 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7814 U1(ddsd
).lPitch
= -4;
7815 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7816 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7818 U1(ddsd
).lPitch
= 16 * 4;
7819 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7820 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7823 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7824 U1(ddsd
).lPitch
= 0;
7826 ddsd
.lpSurface
= data
;
7827 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7828 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7830 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
7831 U1(ddsd
).lPitch
= 16 * 4;
7833 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7834 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7836 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
7837 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
7838 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7839 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7840 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7841 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7842 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7843 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7844 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7845 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7847 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
7848 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7849 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
7851 /* Can't set color keys. */
7853 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
7854 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
7855 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
7856 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7857 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7859 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
7860 ddsd
.lpSurface
= data
;
7861 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7862 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
7864 IDirectDrawSurface4_Release(surface
);
7866 /* Test mipmap texture. */
7868 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7871 U2(ddsd
).dwMipMapCount
= 3;
7872 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7874 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7875 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
7879 skip("Mipmaps are not supported.\n");
7883 /* Changing surface desc for mipmap fails even without changing any
7885 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7886 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
7889 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7890 ddsd
.lpSurface
= data
;
7891 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7892 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
7893 IDirectDrawSurface4_Release(surface
);
7897 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_MIPMAPCOUNT
;
7900 U2(ddsd
).dwMipMapCount
= 3;
7901 ddsd
.lpSurface
= data
;
7902 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7904 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7905 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
|| hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
7909 static DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7910 IDirectDrawSurface4
*surface2
;
7912 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7913 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7915 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface2
, &ddsd
);
7916 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7917 ok(ddsd
.dwWidth
== 4, "Got unexpected dwWidth %lu.\n", ddsd
.dwWidth
);
7920 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7923 U1(ddsd
).lPitch
= 16 * 4;
7924 ddsd
.lpSurface
= data
;
7925 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7926 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7929 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7932 U1(ddsd
).lPitch
= 8 * 4;
7933 ddsd
.lpSurface
= data
;
7934 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7935 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7938 /* _Lock causes access violation on Windows. */
7940 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7941 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7942 IDirectDrawSurface4_Unlock(surface2
, NULL
);
7946 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7949 U1(ddsd
).lPitch
= 4 * 4;
7950 ddsd
.lpSurface
= data
;
7951 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface2
, &ddsd
, 0);
7952 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7955 /* Does not crash now after setting user memory for the level. */
7956 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
7957 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7958 ok(ddsd
.lpSurface
== data
, "Got unexpected lpSurface %p.\n", ddsd
.lpSurface
);
7959 IDirectDrawSurface4_Unlock(surface2
, NULL
);
7962 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_LPSURFACE
;
7965 U1(ddsd
).lPitch
= 16 * 4;
7966 ddsd
.lpSurface
= data
;
7967 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface2
, &ddsd
, 0);
7968 todo_wine
ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7970 IDirectDrawSurface4_Release(surface2
);
7971 IDirectDrawSurface4_Release(surface
);
7974 /* Test surface created with DDSD_LPSURFACE. */
7976 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_LPSURFACE
| DDSD_PITCH
;
7979 ddsd
.lpSurface
= data
;
7980 U1(ddsd
).lPitch
= 8 * 4;
7981 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7982 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7983 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7985 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7986 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#lx.\n", hr
);
7989 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
7992 /* Cannot reset lpSurface. */
7993 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7994 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
7997 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_LPSURFACE
| DDSD_PITCH
;
8000 ddsd
.lpSurface
= data
;
8001 U1(ddsd
).lPitch
= 8 * 4;
8002 /* Can change the parameters of surface created with DDSD_LPSURFACE. */
8003 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
8004 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8006 IDirectDrawSurface4_Release(surface
);
8008 /* SetSurfaceDesc needs systemmemory surfaces.
8010 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
8011 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
8014 ddsd
.dwFlags
= DDSD_CAPS
;
8015 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
8016 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
8017 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
8019 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8022 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
8023 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8024 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8025 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8026 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8027 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8030 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8031 ok(hr
== DD_OK
|| hr
== DDERR_NODIRECTDRAWHW
, "Got unexpected hr %#lx.\n", hr
);
8034 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
8035 invalid_caps_tests
[i
].name
);
8040 ddsd
.dwFlags
= DDSD_LPSURFACE
;
8041 ddsd
.lpSurface
= data
;
8042 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
8043 if (invalid_caps_tests
[i
].supported
)
8045 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8049 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
8050 invalid_caps_tests
[i
].name
, hr
);
8052 /* Check priority of error conditions. */
8053 ddsd
.dwFlags
= DDSD_WIDTH
;
8054 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
8055 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#lx.\n",
8056 invalid_caps_tests
[i
].name
, hr
);
8059 IDirectDrawSurface4_Release(surface
);
8063 ref
= IDirectDraw4_Release(ddraw
);
8064 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8065 DestroyWindow(window
);
8068 static void test_user_memory_getdc(void)
8070 unsigned int data
[16][16], x
, y
;
8071 IDirectDraw4
*ddraw
;
8074 DDSURFACEDESC2 ddsd
;
8075 IDirectDrawSurface4
*surface
;
8082 window
= create_window();
8083 ddraw
= create_ddraw();
8084 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8086 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8087 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8090 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
8093 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
8094 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8095 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8096 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8097 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8098 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8099 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8100 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8101 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8103 memset(data
, 0xaa, sizeof(data
));
8105 ddsd
.dwFlags
= DDSD_LPSURFACE
;
8106 ddsd
.lpSurface
= data
;
8107 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
8108 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
8110 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8111 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8112 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
8113 ok(!!bitmap
, "Failed to get bitmap.\n");
8114 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
8115 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
8116 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
8117 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
8118 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
8119 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8120 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8122 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
8123 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
8125 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
8126 ddsd
.lpSurface
= data
;
8129 U1(ddsd
).lPitch
= sizeof(*data
);
8130 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
8131 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#lx.\n", hr
);
8133 memset(data
, 0xaa, sizeof(data
));
8134 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8135 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
8136 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
8137 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
8138 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8139 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8141 for (y
= 0; y
< 4; y
++)
8143 for (x
= 0; x
< 4; x
++)
8145 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
8146 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
8149 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
8153 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
8155 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
8157 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
8159 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
8162 IDirectDrawSurface4_Release(surface
);
8163 ref
= IDirectDraw4_Release(ddraw
);
8164 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8165 DestroyWindow(window
);
8168 static void test_sysmem_overlay(void)
8170 IDirectDraw4
*ddraw
;
8173 DDSURFACEDESC2 ddsd
;
8174 IDirectDrawSurface4
*surface
;
8177 window
= create_window();
8178 ddraw
= create_ddraw();
8179 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8181 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8182 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8185 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
8188 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
8189 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
8190 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8191 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8192 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8193 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8194 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8195 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8196 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#lx.\n", hr
);
8198 ref
= IDirectDraw4_Release(ddraw
);
8199 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8200 DestroyWindow(window
);
8203 static void test_primary_palette(void)
8205 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
8206 IDirectDrawSurface4
*primary
, *backbuffer
;
8207 PALETTEENTRY palette_entries
[256];
8208 IDirectDrawPalette
*palette
, *tmp
;
8209 DDSURFACEDESC2 surface_desc
;
8210 IDirectDraw4
*ddraw
;
8216 window
= create_window();
8217 ddraw
= create_ddraw();
8218 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8219 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8221 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8222 IDirectDraw4_Release(ddraw
);
8223 DestroyWindow(window
);
8226 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8227 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8229 memset(&surface_desc
, 0, sizeof(surface_desc
));
8230 surface_desc
.dwSize
= sizeof(surface_desc
);
8231 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8232 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8233 U5(surface_desc
).dwBackBufferCount
= 1;
8234 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8235 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8236 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
8237 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
8239 memset(palette_entries
, 0, sizeof(palette_entries
));
8240 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
8241 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
8242 refcount
= get_refcount((IUnknown
*)palette
);
8243 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8245 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8246 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
8247 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
8249 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
8250 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8252 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
8253 * and is generally somewhat broken with respect to 8 bpp / palette
8255 if (SUCCEEDED(IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
)))
8257 win_skip("Broken palette handling detected, skipping tests.\n");
8258 IDirectDrawPalette_Release(tmp
);
8259 IDirectDrawPalette_Release(palette
);
8260 /* The Windows 8 testbot keeps extra references to the primary and
8261 * backbuffer while in 8 bpp mode. */
8262 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
8263 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
8267 refcount
= get_refcount((IUnknown
*)palette
);
8268 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
8270 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8271 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
8272 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
8273 "Got unexpected palette caps %#lx.\n", palette_caps
);
8275 hr
= IDirectDrawSurface4_SetPalette(primary
, NULL
);
8276 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8277 refcount
= get_refcount((IUnknown
*)palette
);
8278 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8280 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
8281 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
8282 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
8284 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
8285 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
8286 refcount
= get_refcount((IUnknown
*)palette
);
8287 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
8289 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
8290 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
8291 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
8292 IDirectDrawPalette_Release(tmp
);
8293 hr
= IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
);
8294 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8296 refcount
= IDirectDrawPalette_Release(palette
);
8297 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8298 refcount
= IDirectDrawPalette_Release(palette
);
8299 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8301 /* Note that this only seems to work when the palette is attached to the
8302 * primary surface. When attached to a regular surface, attempting to get
8303 * the palette here will cause an access violation. */
8304 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
8305 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8307 hr
= IDirectDrawSurface4_IsLost(primary
);
8308 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8310 memset(&surface_desc
, 0, sizeof(surface_desc
));
8311 surface_desc
.dwSize
= sizeof(surface_desc
);
8312 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
8313 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8314 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
8315 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
8316 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %lu.\n",
8317 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8319 hr
= set_display_mode(ddraw
, 640, 480);
8320 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
8322 memset(&surface_desc
, 0, sizeof(surface_desc
));
8323 surface_desc
.dwSize
= sizeof(surface_desc
);
8324 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
8325 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8326 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
8327 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
8328 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8329 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8330 "Got unexpected bit count %lu.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8332 hr
= IDirectDrawSurface4_IsLost(primary
);
8333 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8334 hr
= IDirectDrawSurface4_Restore(primary
);
8335 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8336 hr
= IDirectDrawSurface4_IsLost(primary
);
8337 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8339 memset(&surface_desc
, 0, sizeof(surface_desc
));
8340 surface_desc
.dwSize
= sizeof(surface_desc
);
8341 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
8342 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8343 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
8344 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
8345 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
8346 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
8347 "Got unexpected bit count %lu.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
8350 refcount
= IDirectDrawSurface4_Release(backbuffer
);
8351 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8352 refcount
= IDirectDrawSurface4_Release(primary
);
8353 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8354 refcount
= IDirectDraw4_Release(ddraw
);
8355 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8356 DestroyWindow(window
);
8359 static HRESULT WINAPI
surface_counter(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
8361 UINT
*surface_count
= context
;
8364 IDirectDrawSurface_Release(surface
);
8366 return DDENUMRET_OK
;
8369 static void test_surface_attachment(void)
8371 IDirectDrawSurface4
*surface1
, *surface2
, *surface3
, *surface4
;
8372 IDirectDrawSurface
*surface1v1
, *surface2v1
;
8373 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
8374 DDSURFACEDESC2 surface_desc
;
8375 IDirectDraw4
*ddraw
;
8381 window
= create_window();
8382 ddraw
= create_ddraw();
8383 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8384 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8385 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8387 memset(&surface_desc
, 0, sizeof(surface_desc
));
8388 surface_desc
.dwSize
= sizeof(surface_desc
);
8389 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
8390 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8391 U2(surface_desc
).dwMipMapCount
= 3;
8392 surface_desc
.dwWidth
= 128;
8393 surface_desc
.dwHeight
= 128;
8394 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8395 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8397 hr
= IDirectDrawSurface4_GetAttachedSurface(surface1
, &caps
, &surface2
);
8398 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
8399 hr
= IDirectDrawSurface4_GetAttachedSurface(surface2
, &caps
, &surface3
);
8400 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
8401 hr
= IDirectDrawSurface4_GetAttachedSurface(surface3
, &caps
, &surface4
);
8402 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
8405 IDirectDrawSurface4_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
8406 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8408 IDirectDrawSurface4_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
8409 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
8411 IDirectDrawSurface4_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
8412 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
8414 memset(&surface_desc
, 0, sizeof(surface_desc
));
8415 surface_desc
.dwSize
= sizeof(surface_desc
);
8416 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8417 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8418 surface_desc
.dwWidth
= 16;
8419 surface_desc
.dwHeight
= 16;
8420 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8421 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8423 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
8424 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8425 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
8426 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8427 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
8428 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8429 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
8430 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8431 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
8432 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8433 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
8434 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8436 IDirectDrawSurface4_Release(surface4
);
8438 memset(&surface_desc
, 0, sizeof(surface_desc
));
8439 surface_desc
.dwSize
= sizeof(surface_desc
);
8440 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8441 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8442 surface_desc
.dwWidth
= 16;
8443 surface_desc
.dwHeight
= 16;
8444 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8445 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8447 if (SUCCEEDED(hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
)))
8449 skip("Running on refrast, skipping some tests.\n");
8450 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface4
);
8451 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8455 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8456 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
8457 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8458 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
8459 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8460 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
8461 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8462 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
8463 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8464 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
8465 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8468 IDirectDrawSurface4_Release(surface4
);
8469 IDirectDrawSurface4_Release(surface3
);
8470 IDirectDrawSurface4_Release(surface2
);
8471 IDirectDrawSurface4_Release(surface1
);
8473 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8474 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8476 /* Try a single primary and two offscreen plain surfaces. */
8477 memset(&surface_desc
, 0, sizeof(surface_desc
));
8478 surface_desc
.dwSize
= sizeof(surface_desc
);
8479 surface_desc
.dwFlags
= DDSD_CAPS
;
8480 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8481 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8482 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8484 memset(&surface_desc
, 0, sizeof(surface_desc
));
8485 surface_desc
.dwSize
= sizeof(surface_desc
);
8486 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8487 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8488 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8489 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8490 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8491 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8493 memset(&surface_desc
, 0, sizeof(surface_desc
));
8494 surface_desc
.dwSize
= sizeof(surface_desc
);
8495 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8496 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8497 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
8498 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
8499 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8500 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8502 /* This one has a different size. */
8503 memset(&surface_desc
, 0, sizeof(surface_desc
));
8504 surface_desc
.dwSize
= sizeof(surface_desc
);
8505 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8506 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8507 surface_desc
.dwWidth
= 128;
8508 surface_desc
.dwHeight
= 128;
8509 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8510 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8512 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
8513 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8514 /* Try the reverse without detaching first. */
8515 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
8516 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8517 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
8518 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8520 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
8521 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8522 /* Try to detach reversed. */
8523 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
8524 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8525 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface1
);
8526 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8528 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface3
);
8529 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8530 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface3
);
8531 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8533 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
8534 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8535 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
8536 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8538 IDirectDrawSurface4_Release(surface4
);
8539 IDirectDrawSurface4_Release(surface3
);
8540 IDirectDrawSurface4_Release(surface2
);
8541 IDirectDrawSurface4_Release(surface1
);
8543 /* Test depth surfaces of different sizes. */
8544 memset(&surface_desc
, 0, sizeof(surface_desc
));
8545 surface_desc
.dwSize
= sizeof(surface_desc
);
8546 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8547 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8548 surface_desc
.dwWidth
= 64;
8549 surface_desc
.dwHeight
= 64;
8550 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8551 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
8553 memset(&surface_desc
, 0, sizeof(surface_desc
));
8554 surface_desc
.dwSize
= sizeof(surface_desc
);
8555 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
8556 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8557 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8558 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8559 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8560 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8561 surface_desc
.dwWidth
= 32;
8562 surface_desc
.dwHeight
= 32;
8563 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8564 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
8565 surface_desc
.dwWidth
= 64;
8566 surface_desc
.dwHeight
= 64;
8567 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8568 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
8569 surface_desc
.dwWidth
= 128;
8570 surface_desc
.dwHeight
= 128;
8571 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
8572 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
8574 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
8575 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8577 IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
8578 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
8579 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#lx.\n", hr
);
8580 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface3
);
8581 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#lx.\n", hr
);
8582 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
8583 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8585 IDirectDrawSurface4_Release(surface4
);
8586 IDirectDrawSurface4_Release(surface3
);
8587 IDirectDrawSurface4_Release(surface2
);
8588 IDirectDrawSurface4_Release(surface1
);
8590 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
8591 memset(&surface_desc
, 0, sizeof(surface_desc
));
8592 surface_desc
.dwSize
= sizeof(surface_desc
);
8593 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8594 surface_desc
.dwWidth
= 64;
8595 surface_desc
.dwHeight
= 64;
8596 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
8597 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8598 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
8599 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
8600 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
8601 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8602 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
8603 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
8604 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8605 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
8606 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8608 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8609 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
8610 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
8611 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
8612 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
8613 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8615 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
8616 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#lx.\n", hr
);
8617 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
8618 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#lx.\n", hr
);
8620 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
8621 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8622 refcount
= get_refcount((IUnknown
*)surface2
);
8623 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
8624 refcount
= get_refcount((IUnknown
*)surface2v1
);
8625 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8626 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
8627 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8628 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8629 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
8630 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8631 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8633 /* Attaching while already attached to other surface. */
8634 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface2
);
8635 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8636 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface3
, 0, surface2
);
8637 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8638 IDirectDrawSurface4_Release(surface3
);
8640 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
8641 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8642 refcount
= get_refcount((IUnknown
*)surface2
);
8643 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8644 refcount
= get_refcount((IUnknown
*)surface2v1
);
8645 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
8647 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
8648 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8649 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8650 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
8651 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#lx.\n", hr
);
8652 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
8653 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
8654 refcount
= IDirectDrawSurface4_Release(surface2
);
8655 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8656 refcount
= IDirectDrawSurface4_Release(surface1
);
8657 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8659 /* Automatic detachment on release. */
8660 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
8661 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
8662 refcount
= get_refcount((IUnknown
*)surface2v1
);
8663 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
8664 refcount
= IDirectDrawSurface_Release(surface1v1
);
8665 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8666 refcount
= IDirectDrawSurface_Release(surface2v1
);
8667 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8668 refcount
= IDirectDraw4_Release(ddraw
);
8669 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8670 DestroyWindow(window
);
8673 static void test_private_data(void)
8675 IDirectDraw4
*ddraw
;
8676 IDirectDrawSurface4
*surface
, *surface2
;
8677 DDSURFACEDESC2 surface_desc
;
8678 ULONG refcount
, refcount2
, refcount3
;
8680 DWORD size
= sizeof(ptr
);
8683 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8684 DWORD data
[] = {1, 2, 3, 4};
8686 static const GUID ddraw_private_data_test_guid
=
8691 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
8693 static const GUID ddraw_private_data_test_guid2
=
8698 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
8701 window
= create_window();
8702 ddraw
= create_ddraw();
8703 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8704 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8705 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8707 reset_ddsd(&surface_desc
);
8708 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
8709 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
8710 surface_desc
.dwHeight
= 4;
8711 surface_desc
.dwWidth
= 4;
8712 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8713 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8715 /* NULL pointers are not valid, but don't cause a crash. */
8716 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
8717 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
8718 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8719 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
8720 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8721 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
8722 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8724 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
8725 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8726 0, DDSPD_IUNKNOWNPOINTER
);
8727 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8728 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8729 5, DDSPD_IUNKNOWNPOINTER
);
8730 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8731 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8732 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
8733 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8735 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
8736 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
8737 * erases the old content and returns an error. This behavior has
8738 * been fixed in d3d8 and d3d9. Unless an application is found
8739 * that depends on this we don't care about this behavior. */
8740 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8741 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8742 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8743 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8744 0, DDSPD_IUNKNOWNPOINTER
);
8745 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8747 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8748 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#lx.\n", hr
);
8749 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8750 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#lx.\n", hr
);
8752 refcount
= get_refcount((IUnknown
*)ddraw
);
8753 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8754 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8755 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8756 refcount2
= get_refcount((IUnknown
*)ddraw
);
8757 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %lu.\n", refcount2
);
8759 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
8760 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#lx.\n", hr
);
8761 refcount2
= get_refcount((IUnknown
*)ddraw
);
8762 ok(refcount2
== refcount
, "Got unexpected refcount %lu.\n", refcount2
);
8764 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8765 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8766 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8767 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
8768 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
8769 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8770 refcount2
= get_refcount((IUnknown
*)ddraw
);
8771 ok(refcount2
== refcount
, "Got unexpected refcount %lu.\n", refcount2
);
8773 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
8774 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
8775 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8776 size
= 2 * sizeof(ptr
);
8777 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8778 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#lx.\n", hr
);
8779 ok(size
== sizeof(ddraw
), "Got unexpected size %lu.\n", size
);
8780 refcount2
= get_refcount(ptr
);
8781 /* Object is NOT addref'ed by the getter. */
8782 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
8783 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %lu.\n", refcount2
);
8785 ptr
= (IUnknown
*)0xdeadbeef;
8787 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8788 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#lx.\n", hr
);
8789 ok(size
== sizeof(ddraw
), "Got unexpected size %lu.\n", size
);
8790 size
= 2 * sizeof(ptr
);
8791 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
8792 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8793 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %lu.\n", size
);
8795 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
8796 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#lx.\n", hr
);
8797 ok(size
== sizeof(ddraw
), "Got unexpected size %lu.\n", size
);
8798 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8799 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
8800 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
8802 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
8803 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
8804 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
8805 ok(size
== 0xdeadbabe, "Got unexpected size %lu.\n", size
);
8806 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8807 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
8809 refcount3
= IDirectDrawSurface4_Release(surface
);
8810 ok(!refcount3
, "Got unexpected refcount %lu.\n", refcount3
);
8812 /* Destroying the surface frees the reference held on the private data. It also frees
8813 * the reference the surface is holding on its creating object. */
8814 refcount2
= get_refcount((IUnknown
*)ddraw
);
8815 ok(refcount2
== refcount
- 1, "Got unexpected refcount %lu.\n", refcount2
);
8817 memset(&hal_caps
, 0, sizeof(hal_caps
));
8818 hal_caps
.dwSize
= sizeof(hal_caps
);
8819 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
8820 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
8821 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
8823 reset_ddsd(&surface_desc
);
8824 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
8825 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8826 surface_desc
.dwHeight
= 4;
8827 surface_desc
.dwWidth
= 4;
8828 U2(surface_desc
).dwMipMapCount
= 2;
8829 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8830 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8831 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
8832 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
8834 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
8835 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
8836 hr
= IDirectDrawSurface4_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
8837 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
8839 IDirectDrawSurface4_Release(surface2
);
8840 IDirectDrawSurface4_Release(surface
);
8843 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
8845 refcount
= IDirectDraw4_Release(ddraw
);
8846 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8847 DestroyWindow(window
);
8850 static void test_pixel_format(void)
8852 HWND window
, window2
= NULL
;
8853 HDC hdc
, hdc2
= NULL
;
8855 int format
, test_format
;
8856 PIXELFORMATDESCRIPTOR pfd
;
8857 IDirectDraw4
*ddraw
= NULL
;
8858 IDirectDrawClipper
*clipper
= NULL
;
8859 DDSURFACEDESC2 ddsd
;
8860 IDirectDrawSurface4
*primary
= NULL
, *offscreen
;
8864 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8865 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8868 skip("Failed to create window\n");
8872 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8873 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
8875 hdc
= GetDC(window
);
8878 skip("Failed to get DC\n");
8883 hdc2
= GetDC(window2
);
8885 gl
= LoadLibraryA("opengl32.dll");
8886 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
8888 format
= GetPixelFormat(hdc
);
8889 ok(format
== 0, "new window has pixel format %d\n", format
);
8891 ZeroMemory(&pfd
, sizeof(pfd
));
8892 pfd
.nSize
= sizeof(pfd
);
8894 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
8895 pfd
.iPixelType
= PFD_TYPE_RGBA
;
8896 pfd
.iLayerType
= PFD_MAIN_PLANE
;
8897 format
= ChoosePixelFormat(hdc
, &pfd
);
8900 skip("no pixel format available\n");
8904 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
8906 skip("failed to set pixel format\n");
8910 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
8912 skip("failed to set pixel format on second window\n");
8915 ReleaseDC(window2
, hdc2
);
8920 ddraw
= create_ddraw();
8921 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8923 test_format
= GetPixelFormat(hdc
);
8924 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8926 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8929 skip("Failed to set cooperative level, hr %#lx.\n", hr
);
8933 test_format
= GetPixelFormat(hdc
);
8934 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8938 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
8939 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
8940 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
8941 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
8943 test_format
= GetPixelFormat(hdc
);
8944 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8946 test_format
= GetPixelFormat(hdc2
);
8947 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8950 memset(&ddsd
, 0, sizeof(ddsd
));
8951 ddsd
.dwSize
= sizeof(ddsd
);
8952 ddsd
.dwFlags
= DDSD_CAPS
;
8953 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8955 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
8956 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
8958 test_format
= GetPixelFormat(hdc
);
8959 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8963 test_format
= GetPixelFormat(hdc2
);
8964 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8969 hr
= IDirectDrawSurface4_SetClipper(primary
, clipper
);
8970 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
8972 test_format
= GetPixelFormat(hdc
);
8973 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8975 test_format
= GetPixelFormat(hdc2
);
8976 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8979 memset(&ddsd
, 0, sizeof(ddsd
));
8980 ddsd
.dwSize
= sizeof(ddsd
);
8981 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8982 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8983 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
8984 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
8985 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
8987 memset(&fx
, 0, sizeof(fx
));
8988 fx
.dwSize
= sizeof(fx
);
8989 hr
= IDirectDrawSurface4_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
8990 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
8992 test_format
= GetPixelFormat(hdc
);
8993 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8995 hr
= IDirectDrawSurface4_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
8996 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
8998 test_format
= GetPixelFormat(hdc
);
8999 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
9003 test_format
= GetPixelFormat(hdc2
);
9004 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
9007 IDirectDrawSurface4_Release(offscreen
);
9010 if (primary
) IDirectDrawSurface4_Release(primary
);
9011 if (clipper
) IDirectDrawClipper_Release(clipper
);
9012 if (ddraw
) IDirectDraw4_Release(ddraw
);
9013 if (gl
) FreeLibrary(gl
);
9014 if (hdc
) ReleaseDC(window
, hdc
);
9015 if (hdc2
) ReleaseDC(window2
, hdc2
);
9016 DestroyWindow(window
);
9017 if (window2
) DestroyWindow(window2
);
9020 static void test_create_surface_pitch(void)
9022 DWORD vidmem_total
= 0, vidmem_free
= 0, vidmem_free2
= 0;
9023 DDSCAPS2 vidmem_caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
9024 IDirectDrawSurface4
* surface
, *primary
;
9025 DDSURFACEDESC2 surface_desc
;
9026 IDirectDraw4
*ddraw
;
9046 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9048 DDSD_PITCH
, 0x100, 0x100},
9049 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9050 DDSD_PITCH
, 0x104, DD_OK
,
9051 DDSD_PITCH
, 0x100, 0x100},
9052 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9053 DDSD_PITCH
, 0x0f8, DD_OK
,
9054 DDSD_PITCH
, 0x100, 0x100},
9055 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9056 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
9058 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9060 DDSD_PITCH
, 0x100, 0x0fc},
9062 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9063 DDSD_PITCH
, 0x104, DD_OK
,
9064 DDSD_PITCH
, 0x100, 0x0fc},
9065 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9066 DDSD_PITCH
, 0x0f8, DD_OK
,
9067 DDSD_PITCH
, 0x100, 0x0fc},
9068 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9069 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
9070 DDSD_PITCH
, 0x100, 0x0fc},
9071 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9072 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
9074 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9075 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
9076 DDSD_PITCH
, 0x100, 0x100},
9078 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9079 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
9081 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9082 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
9083 DDSD_PITCH
, 0x0fc, 0x0fc},
9084 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9085 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
9087 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9088 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
9090 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9091 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
9094 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
9095 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
9096 DDSD_PITCH
, 0x100, 0x100},
9097 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
9098 0, 0, DDERR_INVALIDCAPS
,
9100 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
9102 DDSD_PITCH
, 0x100, 0 },
9103 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
,
9105 DDSD_PITCH
, 0x100, 0 },
9106 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
9107 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
9110 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
9111 0, 0, DDERR_INVALIDCAPS
,
9113 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
9115 DDSD_PITCH
, 0x100, 0 },
9116 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
9117 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
9118 DDSD_PITCH
, 0x100, 0 },
9120 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
9122 window
= create_window();
9123 ddraw
= create_ddraw();
9124 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9125 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
9126 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9128 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
9130 /* We need a primary surface and exclusive mode for video memory accounting to work
9131 * right on Windows. Otherwise it gives us junk data, like creating a video memory
9132 * surface freeing up memory. */
9133 memset(&surface_desc
, 0, sizeof(surface_desc
));
9134 surface_desc
.dwSize
= sizeof(surface_desc
);
9135 surface_desc
.dwFlags
= DDSD_CAPS
;
9136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9137 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9138 ok(SUCCEEDED(hr
), "Failed to create a primary surface, hr %#lx.\n", hr
);
9140 hr
= IDirectDraw4_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free
);
9141 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
9142 "Failed to get available video memory, hr %#lx.\n", hr
);
9144 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
9146 memset(&surface_desc
, 0, sizeof(surface_desc
));
9147 surface_desc
.dwSize
= sizeof(surface_desc
);
9148 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
9149 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
9150 surface_desc
.dwWidth
= 63;
9151 surface_desc
.dwHeight
= 63;
9152 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
9153 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9154 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9155 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9156 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9157 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9158 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9159 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9160 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
9162 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
9163 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, expected_hr
);
9164 surface_desc
.lpSurface
= mem
;
9165 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9167 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
9169 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
9173 memset(&surface_desc
, 0, sizeof(surface_desc
));
9174 surface_desc
.dwSize
= sizeof(surface_desc
);
9175 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9176 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
9177 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
9178 "Test %u: Got unexpected flags %#lx, expected %#lx.\n",
9179 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
9180 /* The pitch for textures seems to be implementation specific. */
9181 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
9183 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
9184 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
9185 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
9186 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
9188 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
9189 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
9190 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
9192 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
9194 hr
= IDirectDraw4_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
9195 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
9196 "Failed to get available video memory, hr %#lx.\n", hr
);
9197 if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
9199 /* Star Trek Starfleet Academy cares about this bit here: That creating a system memory
9200 * resource does not influence available video memory. */
9201 ok(vidmem_free2
== vidmem_free
, "Free video memory changed from %#lx to %#lx, test %u.\n",
9202 vidmem_free
, vidmem_free2
, i
);
9204 else if (SUCCEEDED(hr
) && surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
9206 /* DDSCAPS_ALLOCONLOAD does not seem to delay video memory allocation, at least not on
9209 * The amount of video memory consumed is different from what dwHeight * lPitch would
9210 * suggest, although not by much. */
9211 ok(vidmem_free2
< vidmem_free
,
9212 "Expected free video memory to change, but it did not, test %u.\n", i
);
9215 IDirectDrawSurface4_Release(surface
);
9217 hr
= IDirectDraw4_GetAvailableVidMem(ddraw
, &vidmem_caps
, &vidmem_total
, &vidmem_free2
);
9218 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
,
9219 "Failed to get available video memory, hr %#lx.\n", hr
);
9220 ok(hr
== DDERR_NODIRECTDRAWHW
|| vidmem_free2
== vidmem_free
,
9221 "Free video memory changed from %#lx to %#lx, test %u.\n",
9222 vidmem_free
, vidmem_free2
, i
);
9225 IDirectDrawSurface4_Release(primary
);
9226 HeapFree(GetProcessHeap(), 0, mem
);
9227 refcount
= IDirectDraw4_Release(ddraw
);
9228 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9229 DestroyWindow(window
);
9232 static void test_mipmap(void)
9234 IDirectDrawSurface4
*surface
, *surface_base
, *surface_mip
;
9235 unsigned int i
, mipmap_count
;
9236 DDSURFACEDESC2 surface_desc
;
9237 IDirectDraw4
*ddraw
;
9241 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
9250 DWORD mipmap_count_in
;
9252 DWORD mipmap_count_out
;
9256 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
9257 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
9258 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
9259 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
9260 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
9261 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
9264 window
= create_window();
9265 ddraw
= create_ddraw();
9266 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9267 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9268 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9270 memset(&hal_caps
, 0, sizeof(hal_caps
));
9271 hal_caps
.dwSize
= sizeof(hal_caps
);
9272 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
9273 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9274 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
9276 skip("Mipmapped textures not supported, skipping tests.\n");
9277 IDirectDraw4_Release(ddraw
);
9278 DestroyWindow(window
);
9282 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9284 memset(&surface_desc
, 0, sizeof(surface_desc
));
9285 surface_desc
.dwSize
= sizeof(surface_desc
);
9286 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
9287 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9288 surface_desc
.dwWidth
= tests
[i
].width
;
9289 surface_desc
.dwHeight
= tests
[i
].height
;
9290 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
9291 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
9292 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9293 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
9297 memset(&surface_desc
, 0, sizeof(surface_desc
));
9298 surface_desc
.dwSize
= sizeof(surface_desc
);
9299 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9300 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
9301 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
9302 "Test %u: Got unexpected flags %#lx.\n", i
, surface_desc
.dwFlags
);
9303 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
9304 "Test %u: Got unexpected mipmap count %lu.\n", i
, U2(surface_desc
).dwMipMapCount
);
9306 surface_base
= surface
;
9307 IDirectDrawSurface4_AddRef(surface_base
);
9308 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
9309 while (mipmap_count
> 1)
9311 hr
= IDirectDrawSurface4_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
9312 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#lx.\n", i
, mipmap_count
, hr
);
9314 memset(&surface_desc
, 0, sizeof(surface_desc
));
9315 surface_desc
.dwSize
= sizeof(surface_desc
);
9316 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface_base
, &surface_desc
);
9317 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#lx.\n", i
, mipmap_count
, hr
);
9318 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
9319 "Test %u, %u: Got unexpected flags %#lx.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
9320 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
9321 "Test %u, %u: Got unexpected mipmap count %lu.\n",
9322 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
9324 memset(&surface_desc
, 0, sizeof(surface_desc
));
9325 surface_desc
.dwSize
= sizeof(surface_desc
);
9326 hr
= IDirectDrawSurface4_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
9327 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
9328 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
9329 "Test %u, %u: unexpected change of mipmap count %lu.\n",
9330 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
9331 memset(&surface_desc
, 0, sizeof(surface_desc
));
9332 surface_desc
.dwSize
= sizeof(surface_desc
);
9333 hr
= IDirectDrawSurface4_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
9334 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
9335 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
9336 "Test %u, %u: Got unexpected child mipmap count %lu.\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
9337 IDirectDrawSurface4_Unlock(surface_mip
, NULL
);
9338 IDirectDrawSurface4_Unlock(surface_base
, NULL
);
9340 IDirectDrawSurface4_Release(surface_base
);
9341 surface_base
= surface_mip
;
9344 IDirectDrawSurface4_Release(surface_base
);
9346 IDirectDrawSurface4_Release(surface
);
9349 refcount
= IDirectDraw4_Release(ddraw
);
9350 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9351 DestroyWindow(window
);
9354 static void test_palette_complex(void)
9356 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
9357 DDSURFACEDESC2 surface_desc
;
9358 IDirectDraw4
*ddraw
;
9359 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
9363 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
9365 PALETTEENTRY palette_entries
[256];
9371 window
= create_window();
9372 ddraw
= create_ddraw();
9373 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9374 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9375 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9377 memset(&hal_caps
, 0, sizeof(hal_caps
));
9378 hal_caps
.dwSize
= sizeof(hal_caps
);
9379 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
9380 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9381 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
9383 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
9384 IDirectDraw4_Release(ddraw
);
9385 DestroyWindow(window
);
9389 memset(&surface_desc
, 0, sizeof(surface_desc
));
9390 surface_desc
.dwSize
= sizeof(surface_desc
);
9391 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9392 surface_desc
.dwWidth
= 128;
9393 surface_desc
.dwHeight
= 128;
9394 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
9395 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9396 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9397 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9398 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9399 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9401 memset(palette_entries
, 0, sizeof(palette_entries
));
9402 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9403 palette_entries
, &palette
, NULL
);
9404 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
9406 memset(palette_entries
, 0, sizeof(palette_entries
));
9407 palette_entries
[1].peRed
= 0xff;
9408 palette_entries
[1].peGreen
= 0x80;
9409 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9410 palette_entries
, &palette_mipmap
, NULL
);
9411 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
9413 palette2
= (void *)0xdeadbeef;
9414 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
9415 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
9416 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
9417 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
9418 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9419 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
9420 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
9421 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
9422 IDirectDrawPalette_Release(palette2
);
9425 IDirectDrawSurface4_AddRef(mipmap
);
9426 for (i
= 0; i
< 7; ++i
)
9428 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9429 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
9430 palette2
= (void *)0xdeadbeef;
9431 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
9432 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
9433 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
9435 hr
= IDirectDrawSurface4_SetPalette(tmp
, palette_mipmap
);
9436 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#lx.\n", i
, hr
);
9438 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
9439 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#lx.\n", i
, hr
);
9440 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
9441 IDirectDrawPalette_Release(palette2
);
9443 hr
= IDirectDrawSurface4_GetDC(tmp
, &dc
);
9444 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#lx.\n", i
, hr
);
9445 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
9446 ok(count
== 1, "Expected count 1, got %u.\n", count
);
9447 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
9448 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
9449 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
9450 hr
= IDirectDrawSurface4_ReleaseDC(tmp
, dc
);
9451 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#lx.\n", i
, hr
);
9453 IDirectDrawSurface4_Release(mipmap
);
9457 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
9458 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
9459 IDirectDrawSurface4_Release(mipmap
);
9460 refcount
= IDirectDrawSurface4_Release(surface
);
9461 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9462 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
9463 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9464 refcount
= IDirectDrawPalette_Release(palette
);
9465 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9467 refcount
= IDirectDraw4_Release(ddraw
);
9468 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9469 DestroyWindow(window
);
9472 static void test_p8_blit(void)
9474 IDirectDrawSurface4
*src
, *dst
, *dst_p8
;
9475 DDSURFACEDESC2 surface_desc
;
9476 unsigned int color
, x
;
9477 IDirectDraw4
*ddraw
;
9478 IDirectDrawPalette
*palette
, *palette2
;
9482 PALETTEENTRY palette_entries
[256];
9485 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
9486 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
9487 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
9488 static const unsigned int expected
[] =
9490 0x00101010, 0x00010101, 0x00020202, 0x00030303,
9491 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
9494 window
= create_window();
9495 ddraw
= create_ddraw();
9496 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9497 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9498 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9499 is_warp
= ddraw_is_warp(ddraw
);
9501 memset(palette_entries
, 0, sizeof(palette_entries
));
9502 palette_entries
[1].peGreen
= 0xff;
9503 palette_entries
[2].peBlue
= 0xff;
9504 palette_entries
[3].peFlags
= 0xff;
9505 palette_entries
[4].peRed
= 0xff;
9506 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9507 palette_entries
, &palette
, NULL
);
9508 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
9509 palette_entries
[1].peBlue
= 0xff;
9510 palette_entries
[2].peGreen
= 0xff;
9511 palette_entries
[3].peRed
= 0xff;
9512 palette_entries
[4].peFlags
= 0x0;
9513 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9514 palette_entries
, &palette2
, NULL
);
9515 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
9517 memset(&surface_desc
, 0, sizeof(surface_desc
));
9518 surface_desc
.dwSize
= sizeof(surface_desc
);
9519 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9520 surface_desc
.dwWidth
= 8;
9521 surface_desc
.dwHeight
= 1;
9522 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9523 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9524 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9525 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9526 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9527 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9528 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
9529 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9530 hr
= IDirectDrawSurface4_SetPalette(dst_p8
, palette2
);
9531 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9533 memset(&surface_desc
, 0, sizeof(surface_desc
));
9534 surface_desc
.dwSize
= sizeof(surface_desc
);
9535 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9536 surface_desc
.dwWidth
= 8;
9537 surface_desc
.dwHeight
= 1;
9538 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9539 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9540 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9541 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9542 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9543 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9544 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9545 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9546 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9547 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9549 memset(&surface_desc
, 0, sizeof(surface_desc
));
9550 surface_desc
.dwSize
= sizeof(surface_desc
);
9551 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9552 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
9553 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
9554 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
9555 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
9557 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
9558 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
9559 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
9560 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
9561 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
9563 fx
.dwSize
= sizeof(fx
);
9564 fx
.dwFillColor
= 0xdeadbeef;
9565 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
9566 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9568 hr
= IDirectDrawSurface4_SetPalette(src
, palette
);
9569 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9570 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9571 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
9572 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
9573 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
9574 "Failed to blit, hr %#lx.\n", hr
);
9578 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
9580 color
= get_surface_color(dst
, x
, 0);
9581 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
9582 * blits see below. */
9583 todo_wine
ok(compare_color(color
, expected
[x
], 0)
9584 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
9585 "Pixel %u: Got color %#x, expected %#x.\n",
9586 x
, color
, expected
[x
]);
9590 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
9591 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
9592 hr
= IDirectDrawSurface4_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
9593 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
9595 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
9596 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
9597 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
9598 * surface untouched. Error checking (DDBLT_KEYSRC without a key
9599 * for example) also works as expected.
9601 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
9602 * the display mode set to P8 doesn't help either. */
9603 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
9604 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
9605 "Got unexpected P8 color key blit result.\n");
9606 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
9607 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
9609 IDirectDrawSurface4_Release(src
);
9610 IDirectDrawSurface4_Release(dst
);
9611 IDirectDrawSurface4_Release(dst_p8
);
9612 IDirectDrawPalette_Release(palette
);
9613 IDirectDrawPalette_Release(palette2
);
9615 refcount
= IDirectDraw4_Release(ddraw
);
9616 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9617 DestroyWindow(window
);
9620 static void test_material(void)
9622 D3DMATERIALHANDLE mat_handle
, tmp
;
9623 IDirect3DMaterial3
*material
;
9624 IDirect3DViewport3
*viewport
;
9625 IDirect3DDevice3
*device
;
9626 IDirectDrawSurface4
*rt
;
9627 unsigned int color
, i
;
9635 struct vec3 position
;
9641 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
9642 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
9643 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
9644 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
9648 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
9649 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
9650 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
9651 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
9657 D3DCOLOR expected_color
;
9661 {quad1
, TRUE
, 0x0000ff00},
9662 {quad2
, TRUE
, 0x0000ff00},
9663 {quad1
, FALSE
, 0x00ffffff},
9664 {quad2
, FALSE
, 0x00ff0000},
9666 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9668 window
= create_window();
9669 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9671 skip("Failed to create a 3D device, skipping test.\n");
9672 DestroyWindow(window
);
9676 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9677 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9679 viewport
= create_viewport(device
, 0, 0, 640, 480);
9680 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9681 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
9683 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
9684 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
9685 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
9687 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
9688 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
9689 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
9690 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
9691 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
9692 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
9693 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
9694 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
9695 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
9696 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
9697 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
9698 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#lx.\n", hr
);
9699 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
9701 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
9703 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
9704 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
9705 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9707 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
9708 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#lx.\n", hr
);
9710 hr
= IDirect3DDevice3_BeginScene(device
);
9711 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9712 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9713 D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
, test_data
[i
].data
, 4, 0);
9714 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9715 hr
= IDirect3DDevice3_EndScene(device
);
9716 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9717 color
= get_surface_color(rt
, 320, 240);
9718 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
9719 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
9722 destroy_material(material
);
9723 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
9724 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
9725 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
9727 hr
= IDirect3DViewport3_SetBackground(viewport
, mat_handle
);
9728 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
9729 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
9730 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
9731 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
9732 ok(valid
, "Got unexpected valid %#x.\n", valid
);
9733 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9734 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9735 color
= get_surface_color(rt
, 320, 240);
9736 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9738 hr
= IDirect3DViewport3_SetBackground(viewport
, 0);
9739 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9740 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
9741 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
9742 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
9743 ok(valid
, "Got unexpected valid %#x.\n", valid
);
9744 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9745 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9746 color
= get_surface_color(rt
, 320, 240);
9747 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
9749 destroy_viewport(device
, viewport
);
9750 viewport
= create_viewport(device
, 0, 0, 640, 480);
9752 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
9753 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
9754 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
9755 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
9756 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9757 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9758 color
= get_surface_color(rt
, 320, 240);
9759 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
9761 destroy_viewport(device
, viewport
);
9762 destroy_material(material
);
9763 IDirectDrawSurface4_Release(rt
);
9764 refcount
= IDirect3DDevice3_Release(device
);
9765 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9766 DestroyWindow(window
);
9769 static void test_palette_gdi(void)
9771 IDirectDrawSurface4
*surface
, *primary
;
9772 DDSURFACEDESC2 surface_desc
;
9773 unsigned int color
, i
;
9774 IDirectDraw4
*ddraw
;
9775 IDirectDrawPalette
*palette
, *palette2
;
9779 PALETTEENTRY palette_entries
[256];
9784 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
9785 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
9786 * not the point of this test. */
9787 static const RGBQUAD expected1
[] =
9789 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9790 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
9792 static const RGBQUAD expected2
[] =
9794 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
9795 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
9797 static const RGBQUAD expected3
[] =
9799 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
9800 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
9802 HPALETTE ddraw_palette_handle
;
9803 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
9804 RGBQUAD rgbquad
[255];
9805 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
9807 window
= create_window();
9808 ddraw
= create_ddraw();
9809 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9810 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9811 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9813 memset(&surface_desc
, 0, sizeof(surface_desc
));
9814 surface_desc
.dwSize
= sizeof(surface_desc
);
9815 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9816 surface_desc
.dwWidth
= 16;
9817 surface_desc
.dwHeight
= 16;
9818 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9819 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9820 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
9821 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
9822 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9823 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9825 /* Avoid colors from the Windows default palette. */
9826 memset(palette_entries
, 0, sizeof(palette_entries
));
9827 palette_entries
[1].peRed
= 0x01;
9828 palette_entries
[2].peGreen
= 0x02;
9829 palette_entries
[3].peBlue
= 0x03;
9830 palette_entries
[4].peRed
= 0x13;
9831 palette_entries
[4].peGreen
= 0x14;
9832 palette_entries
[4].peBlue
= 0x15;
9833 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
9834 palette_entries
, &palette
, NULL
);
9835 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
9837 /* If there is no palette assigned and the display mode is not 8 bpp, some
9838 * drivers refuse to create a DC while others allow it. If a DC is created,
9839 * the DIB color table is uninitialized and contains random colors. No error
9840 * is generated when trying to read pixels and random garbage is returned.
9842 * The most likely explanation is that if the driver creates a DC, it (or
9843 * the higher-level runtime) uses GetSystemPaletteEntries to find the
9844 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
9845 * contains uninitialized garbage. See comments below for the P8 case. */
9847 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
9848 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9849 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
9850 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
9851 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9852 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9853 "Got unexpected palette %p, expected %p.\n",
9854 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9856 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9857 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9858 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
9860 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
9861 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9862 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9863 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
9865 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
9867 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9868 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9869 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9872 /* Update the palette while the DC is in use. This does not modify the DC. */
9873 palette_entries
[4].peRed
= 0x23;
9874 palette_entries
[4].peGreen
= 0x24;
9875 palette_entries
[4].peBlue
= 0x25;
9876 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
9877 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
9879 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9880 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9881 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9882 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9883 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9884 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9886 /* Neither does re-setting the palette. */
9887 hr
= IDirectDrawSurface4_SetPalette(surface
, NULL
);
9888 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9889 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
9890 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9892 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
9893 ok(i
== 1, "Expected count 1, got %u.\n", i
);
9894 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
9895 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9896 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
9897 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
9899 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
9900 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
9902 /* Refresh the DC. This updates the palette. */
9903 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
9904 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
9905 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9906 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9907 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
9909 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9910 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9911 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9912 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9914 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
9916 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9917 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9918 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9920 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
9921 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
9923 refcount
= IDirectDrawSurface4_Release(surface
);
9924 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9926 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
9927 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9928 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9930 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9931 IDirectDrawPalette_Release(palette
);
9932 IDirectDraw4_Release(ddraw
);
9933 DestroyWindow(window
);
9936 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
9938 memset(&surface_desc
, 0, sizeof(surface_desc
));
9939 surface_desc
.dwSize
= sizeof(surface_desc
);
9940 surface_desc
.dwFlags
= DDSD_CAPS
;
9941 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9942 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
9943 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9945 memset(&fx
, 0, sizeof(fx
));
9946 fx
.dwSize
= sizeof(fx
);
9947 U5(fx
).dwFillColor
= 3;
9948 SetRect(&r
, 0, 0, 319, 479);
9949 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9950 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
9951 SetRect(&r
, 320, 0, 639, 479);
9952 U5(fx
).dwFillColor
= 4;
9953 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9954 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
9956 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
9957 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
9958 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
9959 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
9961 color
= GetPixel(dc
, 160, 240);
9962 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
9963 color
= GetPixel(dc
, 480, 240);
9964 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
9966 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
9967 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
9968 "Got unexpected palette %p, expected %p.\n",
9969 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
9970 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
9972 /* The primary uses the system palette. In exclusive mode, the system palette matches
9973 * the ddraw palette attached to the primary, so the result is what you would expect
9974 * from a regular surface. Tests for the interaction between the ddraw palette and
9975 * the system palette are not included pending an application that depends on this.
9976 * The relation between those causes problems on Windows Vista and newer for games
9977 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
9978 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9979 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9980 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
9982 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
9983 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9984 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9985 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
9987 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
9989 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9990 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9991 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9993 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
9994 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
9996 memset(&surface_desc
, 0, sizeof(surface_desc
));
9997 surface_desc
.dwSize
= sizeof(surface_desc
);
9998 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9999 surface_desc
.dwWidth
= 16;
10000 surface_desc
.dwHeight
= 16;
10001 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10002 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10003 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10005 /* Here the offscreen surface appears to use the primary's palette,
10006 * but in all likelihood it is actually the system palette. */
10007 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
10008 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10009 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
10010 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
10011 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
10013 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
10014 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
10015 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
10016 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
10018 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
10020 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
10021 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
10022 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
10024 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
10025 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10027 /* On real hardware a change to the primary surface's palette applies immediately,
10028 * even on device contexts from offscreen surfaces that do not have their own
10029 * palette. On the testbot VMs this is not the case. Don't test this until we
10030 * know of an application that depends on this. */
10032 memset(palette_entries
, 0, sizeof(palette_entries
));
10033 palette_entries
[1].peBlue
= 0x40;
10034 palette_entries
[2].peRed
= 0x40;
10035 palette_entries
[3].peGreen
= 0x40;
10036 palette_entries
[4].peRed
= 0x12;
10037 palette_entries
[4].peGreen
= 0x34;
10038 palette_entries
[4].peBlue
= 0x56;
10039 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
10040 palette_entries
, &palette2
, NULL
);
10041 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
10042 hr
= IDirectDrawSurface4_SetPalette(surface
, palette2
);
10043 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
10045 /* A palette assigned to the offscreen surface overrides the primary / system
10047 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
10048 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10049 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
10050 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
10051 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
10053 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
10054 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
10055 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
10056 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
10058 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
10060 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
10061 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
10062 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
10064 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
10065 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10067 refcount
= IDirectDrawSurface4_Release(surface
);
10068 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10070 /* The Windows 8 testbot keeps extra references to the primary and
10071 * backbuffer while in 8 bpp mode. */
10072 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
10073 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
10075 refcount
= IDirectDrawSurface4_Release(primary
);
10076 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10077 refcount
= IDirectDrawPalette_Release(palette2
);
10078 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10079 refcount
= IDirectDrawPalette_Release(palette
);
10080 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10081 refcount
= IDirectDraw4_Release(ddraw
);
10082 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10083 DestroyWindow(window
);
10086 static void test_palette_alpha(void)
10088 IDirectDrawSurface4
*surface
;
10089 DDSURFACEDESC2 surface_desc
;
10090 IDirectDraw4
*ddraw
;
10091 IDirectDrawPalette
*palette
;
10095 PALETTEENTRY palette_entries
[256];
10097 static const struct
10100 BOOL attach_allowed
;
10105 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
10106 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
10107 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
10110 window
= create_window();
10111 ddraw
= create_ddraw();
10112 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10113 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
10115 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
10116 IDirectDraw4_Release(ddraw
);
10117 DestroyWindow(window
);
10120 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10121 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10123 memset(palette_entries
, 0, sizeof(palette_entries
));
10124 palette_entries
[1].peFlags
= 0x42;
10125 palette_entries
[2].peFlags
= 0xff;
10126 palette_entries
[3].peFlags
= 0x80;
10127 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
10128 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
10130 memset(palette_entries
, 0x66, sizeof(palette_entries
));
10131 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
10132 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
10133 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
10134 palette_entries
[0].peFlags
);
10135 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
10136 palette_entries
[1].peFlags
);
10137 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
10138 palette_entries
[2].peFlags
);
10139 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
10140 palette_entries
[3].peFlags
);
10142 IDirectDrawPalette_Release(palette
);
10144 memset(palette_entries
, 0, sizeof(palette_entries
));
10145 palette_entries
[1].peFlags
= 0x42;
10146 palette_entries
[1].peRed
= 0xff;
10147 palette_entries
[2].peFlags
= 0xff;
10148 palette_entries
[3].peFlags
= 0x80;
10149 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
10150 palette_entries
, &palette
, NULL
);
10151 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
10153 memset(palette_entries
, 0x66, sizeof(palette_entries
));
10154 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
10155 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
10156 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
10157 palette_entries
[0].peFlags
);
10158 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
10159 palette_entries
[1].peFlags
);
10160 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
10161 palette_entries
[2].peFlags
);
10162 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
10163 palette_entries
[3].peFlags
);
10165 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
10167 memset(&surface_desc
, 0, sizeof(surface_desc
));
10168 surface_desc
.dwSize
= sizeof(surface_desc
);
10169 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
10170 surface_desc
.dwWidth
= 128;
10171 surface_desc
.dwHeight
= 128;
10172 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
10173 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10174 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
10176 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
10177 if (test_data
[i
].attach_allowed
)
10178 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
10180 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
10188 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
10189 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
10190 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
10191 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
10192 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
10193 rgbquad
.rgbRed
, test_data
[i
].name
);
10194 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
10195 rgbquad
.rgbGreen
, test_data
[i
].name
);
10196 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
10197 rgbquad
.rgbBlue
, test_data
[i
].name
);
10198 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
10199 rgbquad
.rgbReserved
, test_data
[i
].name
);
10200 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
10201 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10203 IDirectDrawSurface4_Release(surface
);
10206 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
10207 memset(&surface_desc
, 0, sizeof(surface_desc
));
10208 surface_desc
.dwSize
= sizeof(surface_desc
);
10209 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10210 surface_desc
.dwWidth
= 128;
10211 surface_desc
.dwHeight
= 128;
10212 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10213 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10214 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10215 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10216 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10217 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10218 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10219 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10220 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10221 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
10222 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
10223 IDirectDrawSurface4_Release(surface
);
10225 /* The Windows 8 testbot keeps extra references to the primary
10226 * while in 8 bpp mode. */
10227 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
10228 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
10230 refcount
= IDirectDrawPalette_Release(palette
);
10231 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10232 refcount
= IDirectDraw4_Release(ddraw
);
10233 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10234 DestroyWindow(window
);
10237 static void test_vb_writeonly(void)
10239 IDirect3DDevice3
*device
;
10241 IDirect3DVertexBuffer
*buffer
;
10244 D3DVERTEXBUFFERDESC desc
;
10246 static const struct vec4 quad
[] =
10248 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
10249 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
10250 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
10251 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
10254 window
= create_window();
10255 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10257 skip("Failed to create a 3D device, skipping test.\n");
10258 DestroyWindow(window
);
10262 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10263 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
10265 memset(&desc
, 0, sizeof(desc
));
10266 desc
.dwSize
= sizeof(desc
);
10267 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
10268 desc
.dwFVF
= D3DFVF_XYZRHW
;
10269 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
10270 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
10271 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
10273 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
10274 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
10275 memcpy(ptr
, quad
, sizeof(quad
));
10276 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
10277 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
10279 hr
= IDirect3DDevice3_BeginScene(device
);
10280 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
10281 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
10282 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
10283 hr
= IDirect3DDevice3_EndScene(device
);
10284 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10286 hr
= IDirect3DVertexBuffer_Lock(buffer
, 0, &ptr
, NULL
);
10287 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
10288 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
10289 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
10290 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
10292 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
10293 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
10294 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
10295 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
10296 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
10298 IDirect3DVertexBuffer_Release(buffer
);
10299 IDirect3D3_Release(d3d
);
10300 IDirect3DDevice3_Release(device
);
10301 DestroyWindow(window
);
10304 static void test_lost_device(void)
10306 IDirectDrawSurface4
*surface
, *back_buffer
, *back_buffer2
, *ds
;
10307 IDirectDrawSurface4
*sysmem_surface
, *vidmem_surface
;
10308 DDSURFACEDESC2 surface_desc
;
10309 HWND window1
, window2
;
10310 IDirectDraw4
*ddraw
;
10311 DDPIXELFORMAT z_fmt
;
10319 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10320 0, 0, 640, 480, 0, 0, 0, 0);
10321 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
10322 0, 0, 640, 480, 0, 0, 0, 0);
10323 ddraw
= create_ddraw();
10324 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10325 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10326 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10328 memset(&surface_desc
, 0, sizeof(surface_desc
));
10329 surface_desc
.dwSize
= sizeof(surface_desc
);
10330 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10331 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
10332 U5(surface_desc
).dwBackBufferCount
= 1;
10333 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10334 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10336 memset(&surface_desc
, 0, sizeof(surface_desc
));
10337 surface_desc
.dwSize
= sizeof(surface_desc
);
10338 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
10339 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10340 surface_desc
.dwWidth
= 100;
10341 surface_desc
.dwHeight
= 100;
10342 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
10343 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10345 memset(&surface_desc
, 0, sizeof(surface_desc
));
10346 surface_desc
.dwSize
= sizeof(surface_desc
);
10347 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10348 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
10349 surface_desc
.dwWidth
= 64;
10350 surface_desc
.dwHeight
= 64;
10351 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10352 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10353 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10354 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10355 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10356 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10357 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
10359 skip("Failed to create video memory surface, skipping related tests.\n");
10360 vidmem_surface
= NULL
;
10363 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10364 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10365 hr
= IDirectDrawSurface4_IsLost(surface
);
10366 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10367 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10368 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10369 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10370 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10371 if (vidmem_surface
)
10373 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10374 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10377 ret
= SetForegroundWindow(GetDesktopWindow());
10378 ok(ret
, "Failed to set foreground window.\n");
10379 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10380 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
10381 hr
= IDirectDrawSurface4_IsLost(surface
);
10382 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10383 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10384 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10385 hr
= IDirectDrawSurface4_Restore(surface
);
10386 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
10387 hr
= IDirectDrawSurface4_IsLost(surface
);
10388 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10389 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10390 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10391 hr
= IDirectDrawSurface4_Restore(sysmem_surface
);
10392 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10393 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10394 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10395 if (vidmem_surface
)
10397 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10398 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10399 hr
= IDirectDrawSurface4_Restore(vidmem_surface
);
10400 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
10401 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10402 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10405 ret
= SetForegroundWindow(window1
);
10406 ok(ret
, "Failed to set foreground window.\n");
10407 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10408 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10409 hr
= IDirectDrawSurface4_IsLost(surface
);
10410 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10411 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10412 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10413 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10414 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10415 if (vidmem_surface
)
10417 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10418 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10421 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
10422 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10423 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10424 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10425 hr
= IDirectDrawSurface4_IsLost(surface
);
10426 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10427 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10428 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10429 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10430 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10431 if (vidmem_surface
)
10433 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10434 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10437 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
10438 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10439 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10440 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10441 hr
= IDirectDrawSurface4_IsLost(surface
);
10442 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10443 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10444 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10445 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10446 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10447 if (vidmem_surface
)
10449 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10450 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10453 /* Trying to restore the primary will crash, probably because flippable
10454 * surfaces can't exist in DDSCL_NORMAL. */
10455 IDirectDrawSurface4_Release(surface
);
10456 memset(&surface_desc
, 0, sizeof(surface_desc
));
10457 surface_desc
.dwSize
= sizeof(surface_desc
);
10458 surface_desc
.dwFlags
= DDSD_CAPS
;
10459 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10460 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10461 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10462 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
10463 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10465 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10466 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10467 hr
= IDirectDrawSurface4_IsLost(surface
);
10468 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10469 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10470 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10471 if (vidmem_surface
)
10473 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10474 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10477 ret
= SetForegroundWindow(GetDesktopWindow());
10478 ok(ret
, "Failed to set foreground window.\n");
10479 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10480 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10481 hr
= IDirectDrawSurface4_IsLost(surface
);
10482 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10483 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10484 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10485 if (vidmem_surface
)
10487 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10488 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10491 ret
= SetForegroundWindow(window1
);
10492 ok(ret
, "Failed to set foreground window.\n");
10493 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10494 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10495 hr
= IDirectDrawSurface4_IsLost(surface
);
10496 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10497 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10498 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10499 if (vidmem_surface
)
10501 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10502 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10505 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10506 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10507 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10508 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10509 hr
= IDirectDrawSurface4_IsLost(surface
);
10510 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10511 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10512 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10513 if (vidmem_surface
)
10515 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10516 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10519 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
10520 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10521 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10522 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10523 hr
= IDirectDrawSurface4_IsLost(surface
);
10524 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10525 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10526 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10527 if (vidmem_surface
)
10529 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10530 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10533 IDirectDrawSurface4_Release(surface
);
10534 memset(&surface_desc
, 0, sizeof(surface_desc
));
10535 surface_desc
.dwSize
= sizeof(surface_desc
);
10536 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10537 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
10538 U5(surface_desc
).dwBackBufferCount
= 2;
10539 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10540 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10544 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
10547 memset(&z_fmt
, 0, sizeof(z_fmt
));
10548 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
10549 if (FAILED(hr
) || !z_fmt
.dwSize
)
10551 skip("No depth buffer formats available, skipping Z buffer restore test.\n");
10555 memset(&surface_desc
, 0, sizeof(surface_desc
));
10556 surface_desc
.dwSize
= sizeof(surface_desc
);
10557 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
10558 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10560 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
10561 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10562 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
10563 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
10564 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10566 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
10567 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10569 IDirect3D3_Release(d3d
);
10571 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10572 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10573 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10574 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10575 hr
= IDirectDrawSurface4_IsLost(surface
);
10576 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10577 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10578 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10579 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10580 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10581 if (vidmem_surface
)
10583 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10584 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10587 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10588 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10589 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10590 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10591 hr
= IDirectDrawSurface4_IsLost(surface
);
10592 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10593 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10594 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
10595 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10596 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10597 if (vidmem_surface
)
10599 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10600 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10603 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
10604 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10605 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10606 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10607 hr
= IDirectDrawSurface4_IsLost(surface
);
10608 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10609 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10610 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
10611 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10612 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10613 if (vidmem_surface
)
10615 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10616 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10619 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
10620 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10621 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10622 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10623 hr
= IDirectDrawSurface4_IsLost(surface
);
10624 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10625 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10626 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
10627 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10628 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10629 if (vidmem_surface
)
10631 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10632 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10635 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
10636 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10637 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10638 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10639 hr
= IDirectDrawSurface4_IsLost(surface
);
10640 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10641 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10642 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
10643 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10644 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10645 if (vidmem_surface
)
10647 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10648 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10651 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
10652 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10653 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
10654 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10655 hr
= IDirectDrawSurface4_IsLost(surface
);
10656 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10657 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
10658 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10659 if (vidmem_surface
)
10661 hr
= IDirectDrawSurface4_IsLost(vidmem_surface
);
10662 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10665 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
10666 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10668 memset(&caps
, 0, sizeof(caps
));
10669 caps
.dwCaps
= DDSCAPS_FLIP
;
10671 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10672 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10673 hr
= IDirectDrawSurface4_Restore(surface
);
10674 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10675 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &back_buffer
);
10676 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10677 ok(back_buffer
!= surface
, "Got the same surface.\n");
10678 hr
= IDirectDrawSurface4_IsLost(back_buffer
);
10679 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10680 IDirectDrawSurface4_Release(back_buffer
);
10682 hr
= IDirectDrawSurface4_GetAttachedSurface(back_buffer
, &caps
, &back_buffer2
);
10683 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10684 ok(back_buffer2
!= back_buffer
, "Got the same surface.\n");
10685 ok(back_buffer2
!= surface
, "Got the same surface.\n");
10686 hr
= IDirectDrawSurface4_IsLost(back_buffer2
);
10687 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10688 IDirectDrawSurface4_Release(back_buffer2
);
10692 hr
= IDirectDrawSurface4_IsLost(ds
);
10693 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
10694 hr
= IDirectDrawSurface4_Restore(ds
);
10695 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10696 hr
= IDirectDrawSurface4_IsLost(ds
);
10697 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10698 IDirectDrawSurface4_Release(ds
);
10701 if (vidmem_surface
)
10702 IDirectDrawSurface4_Release(vidmem_surface
);
10703 IDirectDrawSurface4_Release(sysmem_surface
);
10704 IDirectDrawSurface4_Release(surface
);
10705 refcount
= IDirectDraw4_Release(ddraw
);
10706 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10707 DestroyWindow(window2
);
10708 DestroyWindow(window1
);
10711 static void test_surface_desc_lock(void)
10713 IDirectDrawSurface4
*surface
;
10714 DDSURFACEDESC2 surface_desc
;
10715 IDirectDraw4
*ddraw
;
10720 window
= create_window();
10721 ddraw
= create_ddraw();
10722 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10723 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10724 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10726 memset(&surface_desc
, 0, sizeof(surface_desc
));
10727 surface_desc
.dwSize
= sizeof(surface_desc
);
10728 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
10729 surface_desc
.dwWidth
= 16;
10730 surface_desc
.dwHeight
= 16;
10731 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10732 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10733 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10735 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10736 surface_desc
.dwSize
= sizeof(surface_desc
);
10737 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
10738 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
10739 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10741 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10742 surface_desc
.dwSize
= sizeof(surface_desc
);
10743 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
10744 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10745 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10746 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10747 surface_desc
.dwSize
= sizeof(surface_desc
);
10748 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
10749 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
10750 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10751 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10752 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10754 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
10755 surface_desc
.dwSize
= sizeof(surface_desc
);
10756 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
10757 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
10758 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10760 IDirectDrawSurface4_Release(surface
);
10761 refcount
= IDirectDraw4_Release(ddraw
);
10762 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
10763 DestroyWindow(window
);
10766 static void test_texturemapblend(void)
10768 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10769 static RECT rect
= {0, 0, 64, 128};
10770 IDirectDrawSurface4
*surface
, *rt
;
10771 IDirect3DViewport3
*viewport
;
10772 DDSURFACEDESC2 surface_desc
;
10773 IDirect3DTexture2
*texture
;
10774 IDirect3DDevice3
*device
;
10775 DWORD texturemapblend
;
10776 IDirectDraw4
*ddraw
;
10777 unsigned int color
;
10788 struct vec4 position
;
10790 struct vec2 texcoord
;
10794 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 0.0f
}},
10795 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 1.0f
}},
10796 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 0.0f
}},
10797 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 1.0f
}},
10798 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 0.0f
}},
10799 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 1.0f
}},
10800 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 0.0f
}},
10801 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 1.0f
}},
10805 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 0.0f
}},
10806 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 1.0f
}},
10807 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 0.0f
}},
10808 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 1.0f
}},
10809 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 0.0f
}},
10810 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 1.0f
}},
10811 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 0.0f
}},
10812 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 1.0f
}},
10815 window
= create_window();
10816 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10818 skip("Failed to create a 3D device, skipping test.\n");
10819 DestroyWindow(window
);
10823 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10824 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10825 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10826 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10827 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10828 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10830 viewport
= create_viewport(device
, 0, 0, 640, 480);
10831 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10832 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10834 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texturemapblend
);
10835 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10836 ok(texturemapblend
== D3DTBLEND_MODULATE
, "Got unexpected texture map blend %#lx.\n", texturemapblend
);
10838 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
10839 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10840 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#lx.\n", value
);
10842 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture
10845 * The vertex alpha is completely ignored in this case, so case 1 and 2
10846 * combined are not a D3DTOP_MODULATE with texture alpha = 0xff in case 2
10847 * (no alpha in texture). */
10848 memset(&surface_desc
, 0, sizeof(surface_desc
));
10849 surface_desc
.dwSize
= sizeof(surface_desc
);
10850 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
10851 surface_desc
.dwHeight
= 128;
10852 surface_desc
.dwWidth
= 128;
10853 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10854 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10855 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10856 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10857 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10858 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10859 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10860 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10861 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10862 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10864 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
10865 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10866 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
10867 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10869 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
10870 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10871 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#lx.\n", value
);
10873 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
10874 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10876 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
10877 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10878 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#lx.\n", value
);
10880 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
10881 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10883 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10884 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10886 memset(&fx
, 0, sizeof(fx
));
10887 fx
.dwSize
= sizeof(fx
);
10888 U5(fx
).dwFillColor
= 0xff0000ff;
10889 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10890 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10891 U5(fx
).dwFillColor
= 0x800000ff;
10892 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10893 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10895 /* Note that the ddraw1 version of this test runs tests 1-3 with
10896 * D3DRENDERSTATE_COLORKEYENABLE enabled, whereas this version only runs
10897 * test 4 with color keying on. Because no color key is set on the texture
10898 * this should not result in different behavior. */
10899 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
10900 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10901 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10902 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10903 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
10904 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10905 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
10906 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10907 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
10908 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10911 /* Disable the call to test that the device has this state by default. */
10912 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
10913 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10916 /* Texture stage state does not change so legacy texture blending stays enabled. */
10917 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
10918 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10920 hr
= IDirect3DDevice3_BeginScene(device
);
10921 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10922 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10923 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
10924 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10925 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10926 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
10927 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10928 hr
= IDirect3DDevice3_EndScene(device
);
10929 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10931 color
= get_surface_color(rt
, 5, 5);
10932 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10933 color
= get_surface_color(rt
, 400, 5);
10934 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10935 color
= get_surface_color(rt
, 5, 245);
10936 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10937 color
= get_surface_color(rt
, 400, 245);
10938 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10940 /* Turn legacy texture blending off. */
10941 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG2
);
10942 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10943 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
10944 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10945 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10946 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10947 hr
= IDirect3DDevice3_BeginScene(device
);
10948 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10949 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10950 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
10951 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10952 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10953 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
10954 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10955 hr
= IDirect3DDevice3_EndScene(device
);
10956 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10958 color
= get_surface_color(rt
, 5, 5);
10959 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10960 color
= get_surface_color(rt
, 400, 5);
10961 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10962 color
= get_surface_color(rt
, 5, 245);
10963 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10964 color
= get_surface_color(rt
, 400, 245);
10965 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10967 /* This doesn't turn legacy texture blending on again, as setting the same
10968 * _TEXTUREMAPBLEND value. */
10969 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
10970 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10971 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
10972 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10973 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10974 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10975 hr
= IDirect3DDevice3_BeginScene(device
);
10976 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10977 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10978 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
10979 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10980 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10981 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
10982 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10983 hr
= IDirect3DDevice3_EndScene(device
);
10984 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10986 color
= get_surface_color(rt
, 5, 5);
10987 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10988 color
= get_surface_color(rt
, 400, 5);
10989 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10990 color
= get_surface_color(rt
, 5, 245);
10991 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10992 color
= get_surface_color(rt
, 400, 245);
10993 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
10995 /* Turn legacy texture blending on again. */
10996 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_ADD
);
10997 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10998 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
10999 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11000 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
11001 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11002 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11003 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11004 hr
= IDirect3DDevice3_BeginScene(device
);
11005 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11006 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11007 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
11008 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11009 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11010 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
11011 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11012 hr
= IDirect3DDevice3_EndScene(device
);
11013 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11015 color
= get_surface_color(rt
, 5, 5);
11016 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
11017 color
= get_surface_color(rt
, 400, 5);
11018 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11019 color
= get_surface_color(rt
, 5, 245);
11020 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
11021 color
= get_surface_color(rt
, 400, 245);
11022 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11024 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
11025 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11026 IDirect3DTexture2_Release(texture
);
11027 refcount
= IDirectDrawSurface4_Release(surface
);
11028 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
11030 /* Test alpha with texture that has no alpha channel - alpha should be
11031 * taken from diffuse vertex color. */
11032 memset(&surface_desc
, 0, sizeof(surface_desc
));
11033 surface_desc
.dwSize
= sizeof(surface_desc
);
11034 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11035 surface_desc
.dwHeight
= 128;
11036 surface_desc
.dwWidth
= 128;
11037 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11038 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11039 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11040 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11041 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11042 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11043 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11045 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11046 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11048 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
11049 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11050 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
11051 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11053 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
11054 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11055 ok(value
== D3DTOP_SELECTARG2
, "Got unexpected D3DTSS_ALPHAOP value %#lx.\n", value
);
11057 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11058 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11060 U5(fx
).dwFillColor
= 0xff0000ff;
11061 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11062 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11063 U5(fx
).dwFillColor
= 0x800000ff;
11064 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11065 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11067 hr
= IDirect3DDevice3_BeginScene(device
);
11068 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11069 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11070 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
11071 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11072 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11073 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
11074 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11075 hr
= IDirect3DDevice3_EndScene(device
);
11076 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
11078 color
= get_surface_color(rt
, 5, 5);
11079 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11080 color
= get_surface_color(rt
, 400, 5);
11081 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11082 color
= get_surface_color(rt
, 5, 245);
11083 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
11084 color
= get_surface_color(rt
, 400, 245);
11085 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
11087 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
11088 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11089 IDirect3DTexture2_Release(texture
);
11090 refcount
= IDirectDrawSurface4_Release(surface
);
11091 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
11093 /* Test RGB - should multiply color components from diffuse vertex color
11095 memset(&surface_desc
, 0, sizeof(surface_desc
));
11096 surface_desc
.dwSize
= sizeof(surface_desc
);
11097 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11098 surface_desc
.dwHeight
= 128;
11099 surface_desc
.dwWidth
= 128;
11100 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11101 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11102 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11103 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11104 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11105 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11106 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11107 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
11108 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11109 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11111 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
11112 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
11113 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
11114 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11116 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11117 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
11119 U5(fx
).dwFillColor
= 0x00ffffff;
11120 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11121 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
11122 U5(fx
).dwFillColor
= 0x00ffff80;
11123 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11124 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
11126 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
11127 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
11129 hr
= IDirect3DDevice3_BeginScene(device
);
11130 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11131 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11132 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[0], 4, 0);
11133 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11134 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11135 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[4], 4, 0);
11136 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11137 hr
= IDirect3DDevice3_EndScene(device
);
11138 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11140 color
= get_surface_color(rt
, 5, 5);
11141 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
11142 color
= get_surface_color(rt
, 400, 5);
11143 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
11144 color
= get_surface_color(rt
, 5, 245);
11145 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
11146 color
= get_surface_color(rt
, 400, 245);
11147 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
11149 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
11150 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11151 IDirect3DTexture2_Release(texture
);
11152 refcount
= IDirectDrawSurface4_Release(surface
);
11153 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
11155 /* Test alpha again, now with color keyed texture (colorkey emulation in
11156 * wine can interfere). */
11157 memset(&surface_desc
, 0, sizeof(surface_desc
));
11158 surface_desc
.dwSize
= sizeof(surface_desc
);
11159 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11160 surface_desc
.dwHeight
= 128;
11161 surface_desc
.dwWidth
= 128;
11162 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11163 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11164 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11165 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
11166 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
11167 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
11168 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
11170 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11171 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11173 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
11174 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
11175 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
11176 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11178 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11179 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
11181 U5(fx
).dwFillColor
= 0xf800;
11182 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11183 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
11184 U5(fx
).dwFillColor
= 0x001f;
11185 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11186 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
11188 ckey
.dwColorSpaceLowValue
= 0x001f;
11189 ckey
.dwColorSpaceHighValue
= 0x001f;
11190 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11191 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
11193 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
11194 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
11195 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
11196 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
11198 hr
= IDirect3DDevice3_BeginScene(device
);
11199 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11200 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11201 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
11202 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11203 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11204 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
11205 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11206 hr
= IDirect3DDevice3_EndScene(device
);
11207 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11209 color
= get_surface_color(rt
, 5, 5);
11210 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
11211 color
= get_surface_color(rt
, 400, 5);
11212 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
11213 color
= get_surface_color(rt
, 5, 245);
11214 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
11215 color
= get_surface_color(rt
, 400, 245);
11216 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
11218 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
11219 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11220 IDirect3DTexture2_Release(texture
);
11221 refcount
= IDirectDrawSurface4_Release(surface
);
11222 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
11224 destroy_viewport(device
, viewport
);
11225 IDirectDrawSurface4_Release(rt
);
11226 IDirect3DDevice3_Release(device
);
11227 IDirect3D3_Release(d3d
);
11228 refcount
= IDirectDraw4_Release(ddraw
);
11229 ok(!refcount
, "Ddraw object not properly released, refcount %lu.\n", refcount
);
11230 DestroyWindow(window
);
11233 static void test_signed_formats(void)
11235 unsigned int color
, expected_color
;
11237 IDirect3DDevice3
*device
;
11239 IDirectDraw4
*ddraw
;
11240 IDirectDrawSurface4
*surface
, *rt
;
11241 IDirect3DTexture2
*texture
;
11242 IDirect3DViewport3
*viewport
;
11243 DDSURFACEDESC2 surface_desc
;
11246 D3DRECT clear_rect
;
11249 struct vec3 position
;
11250 struct vec2 texcoord
;
11254 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
11255 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
11256 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
11257 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
11259 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
11260 * of these values. */
11261 static const USHORT content_v8u8
[4][4] =
11263 {0x0000, 0x7f7f, 0x8880, 0x0000},
11264 {0x0080, 0x8000, 0x7f00, 0x007f},
11265 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
11266 {0x4444, 0xc0c0, 0xa066, 0x22e0},
11268 static const DWORD content_x8l8v8u8
[4][4] =
11270 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
11271 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
11272 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
11273 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
11275 static const USHORT content_l6v5u5
[4][4] =
11277 {0x0000, 0xfdef, 0x0230, 0xfc00},
11278 {0x0010, 0x0200, 0x01e0, 0x000f},
11279 {0x4067, 0x53b9, 0x0421, 0xffff},
11280 {0x8108, 0x0318, 0xc28c, 0x909c},
11282 static const struct
11285 const void *content
;
11288 unsigned int slop
, slop_broken
;
11289 DDPIXELFORMAT format
;
11294 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
11296 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
11297 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
11301 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
11303 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11304 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
11308 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
11310 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
11311 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
11315 /* No V16U16 or Q8W8V8U8 support in ddraw. */
11317 static const unsigned int expected_colors
[4][4] =
11319 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
11320 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
11321 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
11322 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
11324 unsigned int i
, width
, x
, y
;
11325 D3DDEVICEDESC device_desc
, hel_desc
;
11327 window
= create_window();
11328 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11330 skip("Failed to create a 3D device, skipping test.\n");
11331 DestroyWindow(window
);
11335 memset(&device_desc
, 0, sizeof(device_desc
));
11336 device_desc
.dwSize
= sizeof(device_desc
);
11337 memset(&hel_desc
, 0, sizeof(hel_desc
));
11338 hel_desc
.dwSize
= sizeof(hel_desc
);
11339 hr
= IDirect3DDevice3_GetCaps(device
, &device_desc
, &hel_desc
);
11340 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
11341 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
11343 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
11347 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11348 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
11349 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
11350 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
11351 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11352 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11354 memset(&surface_desc
, 0, sizeof(surface_desc
));
11355 surface_desc
.dwSize
= sizeof(surface_desc
);
11356 hr
= IDirectDrawSurface4_GetSurfaceDesc(rt
, &surface_desc
);
11357 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
11358 viewport
= create_viewport(device
, 0, 0, surface_desc
.dwWidth
, surface_desc
.dwHeight
);
11359 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
11360 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
11361 U1(clear_rect
).x1
= 0;
11362 U2(clear_rect
).y1
= 0;
11363 U3(clear_rect
).x2
= surface_desc
.dwWidth
;
11364 U4(clear_rect
).y2
= surface_desc
.dwHeight
;
11366 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
11367 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
11369 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
11370 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
11371 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
11372 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
11373 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#lx.\n", hr
);
11374 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11375 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#lx.\n", hr
);
11376 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
11377 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#lx.\n", hr
);
11379 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
11381 for (width
= 1; width
< 5; width
+= 3)
11383 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
11384 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
11386 memset(&surface_desc
, 0, sizeof(surface_desc
));
11387 surface_desc
.dwSize
= sizeof(surface_desc
);
11388 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
11389 surface_desc
.dwWidth
= width
;
11390 surface_desc
.dwHeight
= 4;
11391 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
11392 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
11393 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11396 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
11399 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, format %s.\n", hr
, formats
[i
].name
);
11401 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
11402 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#lx, format %s.\n",
11403 hr
, formats
[i
].name
);
11404 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
11405 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx, format %s.\n", hr
, formats
[i
].name
);
11406 IDirect3DTexture2_Release(texture
);
11408 memset(&surface_desc
, 0, sizeof(surface_desc
));
11409 surface_desc
.dwSize
= sizeof(surface_desc
);
11410 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
11411 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, format %s.\n", hr
, formats
[i
].name
);
11412 for (y
= 0; y
< 4; y
++)
11414 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
11415 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
11416 width
* formats
[i
].pixel_size
);
11418 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11419 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, format %s.\n", hr
, formats
[i
].name
);
11421 hr
= IDirect3DDevice3_BeginScene(device
);
11422 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11423 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
11424 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
11425 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
11426 hr
= IDirect3DDevice3_EndScene(device
);
11427 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11429 for (y
= 0; y
< 4; y
++)
11431 for (x
= 0; x
< width
; x
++)
11433 expected_color
= expected_colors
[y
][x
];
11434 if (!formats
[i
].blue
)
11435 expected_color
|= 0x000000ff;
11437 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
11438 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
11439 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
11440 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
11441 expected_color
, color
, formats
[i
].name
, x
, y
);
11445 IDirectDrawSurface4_Release(surface
);
11449 destroy_viewport(device
, viewport
);
11450 IDirectDrawSurface4_Release(rt
);
11451 IDirectDraw4_Release(ddraw
);
11452 IDirect3D3_Release(d3d
);
11455 refcount
= IDirect3DDevice3_Release(device
);
11456 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11457 DestroyWindow(window
);
11460 static void test_color_fill(void)
11463 IDirect3DDevice3
*device
;
11465 IDirectDraw4
*ddraw
;
11466 IDirectDrawSurface4
*surface
, *surface2
;
11467 DDSURFACEDESC2 surface_desc
;
11468 unsigned int i
, *color
;
11469 DDPIXELFORMAT z_fmt
;
11473 RECT rect
= {5, 5, 7, 7};
11474 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
11476 static const struct
11479 HRESULT colorfill_hr
, depthfill_hr
;
11482 unsigned int result
;
11484 DDPIXELFORMAT format
;
11489 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11490 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11492 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11493 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11497 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11498 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
11500 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11501 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11505 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11506 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
11508 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11509 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11513 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11514 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
11516 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11517 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11521 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
11522 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
11524 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
11525 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
11529 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
11530 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
11531 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11534 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
11535 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
11536 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
11539 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
11540 * different afterwards. DX9+ GPUs set one of the two luminance values
11541 * in each block, but AMD and Nvidia GPUs disagree on which luminance
11542 * value they set. r200 (dx8) just sets the entire block to the clear
11544 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11545 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
11547 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11548 {0}, {0}, {0}, {0}, {0}
11552 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11553 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
11555 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11556 {0}, {0}, {0}, {0}, {0}
11560 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11561 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
11563 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
11564 {0}, {0}, {0}, {0}, {0}
11568 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
11569 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
11571 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
11572 {0}, {0}, {0}, {0}, {0}
11576 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
11577 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
11579 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11580 {0}, {0}, {0}, {0}, {0}
11584 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
11585 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
11587 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
11588 {0}, {0}, {0}, {0}, {0}
11592 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
11593 * surface works, presumably because it is handled by the runtime instead of
11595 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
11596 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
11598 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11599 {8}, {0}, {0}, {0}, {0}
11603 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
11604 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
11606 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
11607 {8}, {0}, {0}, {0}, {0}
11611 static const struct
11619 {SRCCOPY
, "SRCCOPY", DD_OK
},
11620 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
11621 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
11622 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
11623 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
11624 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
11625 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
11626 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
11627 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
11628 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
11629 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
11630 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
11631 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
11632 {BLACKNESS
, "BLACKNESS", DD_OK
},
11633 {WHITENESS
, "WHITENESS", DD_OK
},
11634 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
11637 window
= create_window();
11638 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11640 skip("Failed to create a 3D device, skipping test.\n");
11641 DestroyWindow(window
);
11645 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11646 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
11647 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
11648 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
11650 memset(&z_fmt
, 0, sizeof(z_fmt
));
11651 IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
11653 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
11655 IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
11656 if (!(supported_fmts
& SUPPORT_DXT1
))
11657 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
11659 IDirect3D3_Release(d3d
);
11661 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
11662 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
11663 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
11664 num_fourcc_codes
* sizeof(*fourcc_codes
));
11667 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
11668 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
11669 for (i
= 0; i
< num_fourcc_codes
; i
++)
11671 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
11672 supported_fmts
|= SUPPORT_YUY2
;
11673 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
11674 supported_fmts
|= SUPPORT_UYVY
;
11676 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
11678 memset(&hal_caps
, 0, sizeof(hal_caps
));
11679 hal_caps
.dwSize
= sizeof(hal_caps
);
11680 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
11681 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
11683 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11684 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
11686 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
11688 DWORD expected_broken
= tests
[i
].result
;
11690 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
11691 memset(&fx
, 0, sizeof(fx
));
11692 fx
.dwSize
= sizeof(fx
);
11693 U5(fx
).dwFillColor
= 0xdeadbeef;
11695 memset(&surface_desc
, 0, sizeof(surface_desc
));
11696 surface_desc
.dwSize
= sizeof(surface_desc
);
11697 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11698 surface_desc
.dwWidth
= 64;
11699 surface_desc
.dwHeight
= 64;
11700 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
11701 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
11702 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
11704 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
11706 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
11708 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
11710 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
11713 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
11718 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11719 /* Some drivers seem to convert depth values incorrectly or not at
11720 * all. Affects at least AMD PALM, 8.17.10.1247. */
11721 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
11726 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
11727 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
11728 g
= (f
+ 1.0f
) / 2.0f
;
11730 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
11731 expected_broken
*= 0x01010101;
11735 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11736 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11738 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11739 todo_wine_if (tests
[i
].format
.dwFourCC
)
11740 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
11741 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11743 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11744 todo_wine_if (tests
[i
].format
.dwFourCC
)
11745 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
11746 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
11748 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11750 memset(&surface_desc
, 0, sizeof(surface_desc
));
11751 surface_desc
.dwSize
= sizeof(surface_desc
);
11752 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11753 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11754 color
= surface_desc
.lpSurface
;
11755 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
11756 *color
, tests
[i
].result
, tests
[i
].name
);
11757 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11758 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11761 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11762 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
11763 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11764 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11765 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
11766 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
11768 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11770 memset(&surface_desc
, 0, sizeof(surface_desc
));
11771 surface_desc
.dwSize
= sizeof(surface_desc
);
11772 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11773 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11774 color
= surface_desc
.lpSurface
;
11775 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
11776 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
11777 "Got clear result 0x%08lx, expected 0x%08lx, surface %s.\n",
11778 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
11779 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11780 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11783 U5(fx
).dwFillColor
= 0xdeadbeef;
11784 fx
.dwROP
= BLACKNESS
;
11785 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11786 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
11787 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11788 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
11789 U5(fx
).dwFillColor
, tests
[i
].name
);
11791 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11793 memset(&surface_desc
, 0, sizeof(surface_desc
));
11794 surface_desc
.dwSize
= sizeof(surface_desc
);
11795 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11796 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11797 color
= surface_desc
.lpSurface
;
11798 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
11799 *color
, tests
[i
].name
);
11800 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11801 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11804 fx
.dwROP
= WHITENESS
;
11805 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11806 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
11807 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
11808 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
11809 U5(fx
).dwFillColor
, tests
[i
].name
);
11811 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
11813 memset(&surface_desc
, 0, sizeof(surface_desc
));
11814 surface_desc
.dwSize
= sizeof(surface_desc
);
11815 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
11816 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11817 color
= surface_desc
.lpSurface
;
11818 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
11819 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
11820 *color
, tests
[i
].name
);
11821 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11822 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
11825 IDirectDrawSurface4_Release(surface
);
11828 memset(&fx
, 0, sizeof(fx
));
11829 fx
.dwSize
= sizeof(fx
);
11830 U5(fx
).dwFillColor
= 0xdeadbeef;
11831 fx
.dwROP
= WHITENESS
;
11833 memset(&surface_desc
, 0, sizeof(surface_desc
));
11834 surface_desc
.dwSize
= sizeof(surface_desc
);
11835 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11836 surface_desc
.dwWidth
= 64;
11837 surface_desc
.dwHeight
= 64;
11838 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11839 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11840 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11841 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11842 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11843 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11844 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
11845 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11846 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11847 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11848 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11851 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
11852 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11853 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
11854 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11856 /* Unused source rectangle. */
11857 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11858 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11859 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11860 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11862 /* Unused source surface. */
11863 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11864 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11865 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11866 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11867 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11868 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11869 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11870 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11872 /* Inverted destination or source rectangle. */
11873 SetRect(&rect
, 5, 7, 7, 5);
11874 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11875 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11876 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11877 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11878 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11879 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11880 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11881 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11882 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11883 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11885 /* Negative rectangle. */
11886 SetRect(&rect
, -1, -1, 5, 5);
11887 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11888 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11889 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11890 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11891 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11892 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11893 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11894 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11895 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11896 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11898 /* Out of bounds rectangle. */
11899 SetRect(&rect
, 0, 0, 65, 65);
11900 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11901 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11902 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11903 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11905 /* Combine multiple flags. */
11906 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11907 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11908 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11909 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11910 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11911 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11913 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
11915 fx
.dwROP
= rops
[i
].rop
;
11916 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
11917 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#lx for rop %s.\n", hr
, rops
[i
].name
);
11920 IDirectDrawSurface4_Release(surface2
);
11921 IDirectDrawSurface4_Release(surface
);
11926 memset(&surface_desc
, 0, sizeof(surface_desc
));
11927 surface_desc
.dwSize
= sizeof(surface_desc
);
11928 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11929 surface_desc
.dwWidth
= 64;
11930 surface_desc
.dwHeight
= 64;
11931 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
11932 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
11933 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11934 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11935 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
11936 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11939 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
11940 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11942 /* Unused source rectangle. */
11943 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11944 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11946 /* Unused source surface. */
11947 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11948 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11949 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11950 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11952 /* Inverted destination or source rectangle. */
11953 SetRect(&rect
, 5, 7, 7, 5);
11954 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11955 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11956 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11957 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11958 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11959 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11960 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11961 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11963 /* Negative rectangle. */
11964 SetRect(&rect
, -1, -1, 5, 5);
11965 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11966 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11967 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11968 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
11969 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11970 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11971 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11972 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11974 /* Out of bounds rectangle. */
11975 SetRect(&rect
, 0, 0, 65, 65);
11976 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11977 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
11979 /* Combine multiple flags. */
11980 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
11981 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
11983 IDirectDrawSurface4_Release(surface2
);
11984 IDirectDrawSurface4_Release(surface
);
11987 IDirectDraw4_Release(ddraw
);
11988 refcount
= IDirect3DDevice3_Release(device
);
11989 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11990 DestroyWindow(window
);
11993 static void test_texcoordindex(void)
11998 struct vec2 texcoord1
;
11999 struct vec2 texcoord2
;
12000 struct vec2 texcoord3
;
12004 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
12005 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
12006 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
12007 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
12009 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
12010 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12011 IDirect3DDevice3
*device
;
12012 unsigned int color
;
12014 IDirectDraw4
*ddraw
;
12015 IDirectDrawSurface4
*rt
;
12016 IDirect3DViewport3
*viewport
;
12019 IDirectDrawSurface4
*surface1
, *surface2
;
12020 IDirect3DTexture2
*texture1
, *texture2
;
12021 DDSURFACEDESC2 surface_desc
;
12025 window
= create_window();
12026 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12028 skip("Failed to create a 3D device, skipping test.\n");
12029 DestroyWindow(window
);
12033 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12034 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
12035 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12036 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
12037 IDirect3D3_Release(d3d
);
12039 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12040 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12042 memset(&surface_desc
, 0, sizeof(surface_desc
));
12043 surface_desc
.dwSize
= sizeof(surface_desc
);
12044 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12045 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12046 surface_desc
.dwWidth
= 2;
12047 surface_desc
.dwHeight
= 2;
12048 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12049 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12050 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12051 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12052 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12053 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12054 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12055 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
12056 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12057 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
12058 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12060 memset(&surface_desc
, 0, sizeof(surface_desc
));
12061 surface_desc
.dwSize
= sizeof(surface_desc
);
12062 hr
= IDirectDrawSurface4_Lock(surface1
, 0, &surface_desc
, 0, NULL
);
12063 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12064 ptr
= surface_desc
.lpSurface
;
12065 ptr
[0] = 0xff000000;
12066 ptr
[1] = 0xff00ff00;
12067 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
12068 ptr
[0] = 0xff0000ff;
12069 ptr
[1] = 0xff00ffff;
12070 hr
= IDirectDrawSurface4_Unlock(surface1
, NULL
);
12071 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12073 memset(&surface_desc
, 0, sizeof(surface_desc
));
12074 surface_desc
.dwSize
= sizeof(surface_desc
);
12075 hr
= IDirectDrawSurface4_Lock(surface2
, 0, &surface_desc
, 0, NULL
);
12076 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12077 ptr
= surface_desc
.lpSurface
;
12078 ptr
[0] = 0xff000000;
12079 ptr
[1] = 0xff0000ff;
12080 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
12081 ptr
[0] = 0xffff0000;
12082 ptr
[1] = 0xffff00ff;
12083 hr
= IDirectDrawSurface4_Unlock(surface2
, 0);
12084 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12086 viewport
= create_viewport(device
, 0, 0, 640, 480);
12087 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12088 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
12090 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirect3DTexture2
, (void **)&texture1
);
12091 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
12092 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirect3DTexture2
, (void **)&texture2
);
12093 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
12094 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture1
);
12095 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
12096 hr
= IDirect3DDevice3_SetTexture(device
, 1, texture2
);
12097 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
12098 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
12099 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
12100 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
12101 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
12102 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
12103 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
12104 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
12105 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
12106 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
12107 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
12108 hr
= IDirect3DDevice3_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
12109 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
12111 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
12112 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#lx.\n", hr
);
12113 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
12114 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#lx.\n", hr
);
12116 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12117 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
12119 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
12120 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12122 hr
= IDirect3DDevice3_BeginScene(device
);
12123 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12124 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
12125 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12126 hr
= IDirect3DDevice3_EndScene(device
);
12127 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12129 color
= get_surface_color(rt
, 160, 120);
12130 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
12131 color
= get_surface_color(rt
, 480, 120);
12132 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
12133 color
= get_surface_color(rt
, 160, 360);
12134 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
12135 color
= get_surface_color(rt
, 480, 360);
12136 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
12138 /* D3DTSS_TEXTURETRANSFORMFLAGS was introduced in D3D7, can't test it here. */
12140 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
12141 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#lx.\n", hr
);
12143 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
12144 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12146 hr
= IDirect3DDevice3_BeginScene(device
);
12147 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12148 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
12149 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12150 hr
= IDirect3DDevice3_EndScene(device
);
12151 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12153 color
= get_surface_color(rt
, 160, 120);
12154 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
12155 color
= get_surface_color(rt
, 480, 120);
12156 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
12157 color
= get_surface_color(rt
, 160, 360);
12158 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
12159 color
= get_surface_color(rt
, 480, 360);
12160 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
12162 IDirect3DTexture2_Release(texture2
);
12163 IDirect3DTexture2_Release(texture1
);
12164 IDirectDrawSurface4_Release(surface2
);
12165 IDirectDrawSurface4_Release(surface1
);
12167 destroy_viewport(device
, viewport
);
12169 IDirectDrawSurface4_Release(rt
);
12170 IDirectDraw4_Release(ddraw
);
12171 refcount
= IDirect3DDevice3_Release(device
);
12172 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12173 DestroyWindow(window
);
12176 static void test_colorkey_precision(void)
12181 struct vec2 texcoord
;
12185 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
12186 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
12187 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
12188 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
12190 unsigned int data
[4] = {0}, color_mask
, color
, t
, c
;
12191 IDirect3DDevice3
*device
;
12193 IDirectDraw4
*ddraw
;
12194 IDirectDrawSurface4
*rt
;
12195 IDirect3DViewport3
*viewport
;
12198 IDirectDrawSurface4
*src
, *dst
, *texture
;
12199 IDirect3DTexture2
*d3d_texture
;
12200 DDSURFACEDESC2 surface_desc
, lock_desc
;
12204 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12205 BOOL is_nvidia
, is_warp
;
12206 static const struct
12208 unsigned int max
, shift
, bpp
, clear
;
12216 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
12218 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12219 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
12224 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
12226 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12227 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
12232 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
12234 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
12235 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
12240 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
12242 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
12243 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
12248 window
= create_window();
12249 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12251 skip("Failed to create a 3D device, skipping test.\n");
12252 DestroyWindow(window
);
12256 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12257 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
12258 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12259 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
12260 IDirect3D3_Release(d3d
);
12261 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12262 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12264 is_nvidia
= ddraw_is_nvidia(ddraw
);
12265 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
12266 * (color key doesn't match although the values are equal), and a false
12267 * positive when the color key is 0 and the texture contains the value 1.
12268 * I don't want to mark this broken unconditionally since this would
12269 * essentially disable the test on Windows. Also on random occasions
12270 * 254 == 255 and 255 != 255.*/
12271 is_warp
= ddraw_is_warp(ddraw
);
12273 viewport
= create_viewport(device
, 0, 0, 640, 480);
12274 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12275 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
12277 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
12278 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#lx.\n", hr
);
12279 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
12280 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#lx.\n", hr
);
12281 /* Multiply the texture read result with 0, that way the result color if the key doesn't
12282 * match is constant. In theory color keying works without reading the texture result
12283 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
12285 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
12286 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
12287 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
12288 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
12289 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
12290 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
12291 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
12292 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
12294 memset(&fx
, 0, sizeof(fx
));
12295 fx
.dwSize
= sizeof(fx
);
12296 memset(&lock_desc
, 0, sizeof(lock_desc
));
12297 lock_desc
.dwSize
= sizeof(lock_desc
);
12299 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
12301 if (is_nvidia
&& tests
[t
].skip_nv
)
12303 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
12307 memset(&surface_desc
, 0, sizeof(surface_desc
));
12308 surface_desc
.dwSize
= sizeof(surface_desc
);
12309 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12310 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12311 surface_desc
.dwWidth
= 4;
12312 surface_desc
.dwHeight
= 1;
12313 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
12314 /* Windows XP (at least with the r200 driver, other drivers untested) produces
12315 * garbage when doing color keyed texture->texture blits. */
12316 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12317 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12318 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12319 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12321 U5(fx
).dwFillColor
= tests
[t
].clear
;
12322 /* On the w8 testbot (WARP driver) the blit result has different values in the
12324 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
12325 | U3(tests
[t
].fmt
).dwGBitMask
12326 | U4(tests
[t
].fmt
).dwBBitMask
;
12328 for (c
= 0; c
<= tests
[t
].max
; ++c
)
12330 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
12331 * texture after it has been set once... */
12332 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12333 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12334 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12335 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12336 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
12337 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12338 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
12339 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
12340 hr
= IDirect3DDevice3_SetTexture(device
, 0, d3d_texture
);
12341 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
12343 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12344 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
12346 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12347 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12348 switch (tests
[t
].bpp
)
12351 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12352 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12353 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12354 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
12358 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
12359 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
12360 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
12361 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
12364 hr
= IDirectDrawSurface4_Unlock(src
, 0);
12365 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12366 hr
= IDirectDrawSurface4_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
12367 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12369 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
12370 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
12371 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12372 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12374 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
12375 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12377 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
12378 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
12379 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12380 switch (tests
[t
].bpp
)
12383 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12384 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12385 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12386 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12390 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
12391 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
12392 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
12393 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
12396 hr
= IDirectDrawSurface4_Unlock(dst
, 0);
12397 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12401 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12402 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
12404 if (data
[3] == tests
[t
].clear
)
12406 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
12407 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
12408 * even when a different surface is used. The blit itself doesn't draw anything,
12409 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
12410 * never be masked out by the key.
12412 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
12413 * test is disabled entirely.
12415 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
12416 * terrible on WARP. */
12417 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
12418 IDirect3DTexture2_Release(d3d_texture
);
12419 IDirectDrawSurface4_Release(texture
);
12420 IDirectDrawSurface4_Release(src
);
12421 IDirectDrawSurface4_Release(dst
);
12426 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12427 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
12429 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12430 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
12432 if (c
== tests
[t
].max
)
12433 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12434 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
12436 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
12437 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
12439 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
12440 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12442 hr
= IDirect3DDevice3_BeginScene(device
);
12443 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12444 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
12445 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12446 hr
= IDirect3DDevice3_EndScene(device
);
12447 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12449 color
= get_surface_color(rt
, 80, 240);
12451 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
12452 "Got unexpected color 0x%08x, format %s, c=%u.\n",
12453 color
, tests
[t
].name
, c
);
12455 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
12456 "Got unexpected color 0x%08x, format %s, c=%u.\n",
12457 color
, tests
[t
].name
, c
);
12459 color
= get_surface_color(rt
, 240, 240);
12460 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
12461 "Got unexpected color 0x%08x, format %s, c=%u.\n",
12462 color
, tests
[t
].name
, c
);
12464 color
= get_surface_color(rt
, 400, 240);
12465 if (c
== tests
[t
].max
)
12466 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
12467 "Got unexpected color 0x%08x, format %s, c=%u.\n",
12468 color
, tests
[t
].name
, c
);
12470 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
12471 "Got unexpected color 0x%08x, format %s, c=%u.\n",
12472 color
, tests
[t
].name
, c
);
12474 IDirect3DTexture2_Release(d3d_texture
);
12475 IDirectDrawSurface4_Release(texture
);
12477 IDirectDrawSurface4_Release(src
);
12478 IDirectDrawSurface4_Release(dst
);
12482 destroy_viewport(device
, viewport
);
12483 IDirectDrawSurface4_Release(rt
);
12484 IDirectDraw4_Release(ddraw
);
12485 refcount
= IDirect3DDevice3_Release(device
);
12486 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12487 DestroyWindow(window
);
12490 static void test_range_colorkey(void)
12492 IDirectDraw4
*ddraw
;
12495 IDirectDrawSurface4
*surface
;
12496 DDSURFACEDESC2 surface_desc
;
12500 window
= create_window();
12501 ddraw
= create_ddraw();
12502 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12503 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12504 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12506 memset(&surface_desc
, 0, sizeof(surface_desc
));
12507 surface_desc
.dwSize
= sizeof(surface_desc
);
12508 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
12509 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12510 surface_desc
.dwWidth
= 1;
12511 surface_desc
.dwHeight
= 1;
12512 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12513 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12514 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12515 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12516 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12517 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
12519 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
12520 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12521 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12522 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12523 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12525 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12526 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12527 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12528 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12530 /* Same for DDSCAPS_OFFSCREENPLAIN. */
12531 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12532 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12533 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
12534 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12535 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12537 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
12538 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12539 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12540 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12542 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
12543 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
12544 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12545 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12547 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
12548 ckey
.dwColorSpaceLowValue
= 0x00000000;
12549 ckey
.dwColorSpaceHighValue
= 0x00000001;
12550 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12551 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12553 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12554 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12555 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
12556 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
12558 ckey
.dwColorSpaceLowValue
= 0x00000001;
12559 ckey
.dwColorSpaceHighValue
= 0x00000000;
12560 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12561 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12563 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12564 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12565 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
12566 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
12568 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
12569 ckey
.dwColorSpaceLowValue
= 0x00000000;
12570 ckey
.dwColorSpaceHighValue
= 0x00000000;
12571 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12572 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12574 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
12575 ckey
.dwColorSpaceLowValue
= 0x00000001;
12576 ckey
.dwColorSpaceHighValue
= 0x00000000;
12577 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12578 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12579 ckey
.dwColorSpaceLowValue
= 0x00000000;
12580 ckey
.dwColorSpaceHighValue
= 0x00000001;
12581 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12582 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12583 /* Range destination keys don't work either. */
12584 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
12585 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12587 /* Just to show it's not because of A, R, and G having equal values. */
12588 ckey
.dwColorSpaceLowValue
= 0x00000000;
12589 ckey
.dwColorSpaceHighValue
= 0x01010101;
12590 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
12591 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
12593 /* None of these operations modified the key. */
12594 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
12595 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12596 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
12597 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
12599 IDirectDrawSurface4_Release(surface
);
12600 refcount
= IDirectDraw4_Release(ddraw
);
12601 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
12602 DestroyWindow(window
);
12605 static void test_shademode(void)
12607 IDirect3DVertexBuffer
*vb_strip
, *vb_list
, *buffer
;
12608 unsigned int color0
, color1
, count
, i
;
12609 IDirect3DViewport3
*viewport
;
12610 IDirect3DDevice3
*device
;
12611 D3DVERTEXBUFFERDESC desc
;
12612 IDirectDrawSurface4
*rt
;
12618 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12619 static const struct
12621 struct vec3 position
;
12626 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12627 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12628 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12629 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12633 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
12634 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12635 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12637 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
12638 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
12639 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
12641 static const struct
12645 unsigned int color0
, color1
;
12649 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
12650 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12651 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12652 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
12653 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
12654 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
12657 window
= create_window();
12658 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12660 skip("Failed to create a 3D device, skipping test.\n");
12661 DestroyWindow(window
);
12665 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12666 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
12667 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12668 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12670 viewport
= create_viewport(device
, 0, 0, 640, 480);
12671 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12672 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
12674 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12675 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
12677 memset(&desc
, 0, sizeof(desc
));
12678 desc
.dwSize
= sizeof(desc
);
12679 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
12680 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
12681 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
12682 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0, NULL
);
12683 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#lx.\n", hr
);
12684 hr
= IDirect3DVertexBuffer_Lock(vb_strip
, 0, &data
, NULL
);
12685 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#lx.\n", hr
);
12686 memcpy(data
, quad_strip
, sizeof(quad_strip
));
12687 hr
= IDirect3DVertexBuffer_Unlock(vb_strip
);
12688 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
12690 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
12691 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0, NULL
);
12692 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#lx.\n", hr
);
12693 hr
= IDirect3DVertexBuffer_Lock(vb_list
, 0, &data
, NULL
);
12694 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#lx.\n", hr
);
12695 memcpy(data
, quad_list
, sizeof(quad_list
));
12696 hr
= IDirect3DVertexBuffer_Unlock(vb_list
);
12697 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
12699 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
12700 * the color fixups we have to do for FLAT shading will be dependent on that. */
12702 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
12704 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
12705 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12707 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
12708 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#lx.\n", hr
);
12710 hr
= IDirect3DDevice3_BeginScene(device
);
12711 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12712 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
12713 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
12714 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
12715 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
12716 hr
= IDirect3DDevice3_EndScene(device
);
12717 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12719 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
12720 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
12722 /* For D3DSHADE_FLAT it should take the color of the first vertex of
12723 * each triangle. This requires EXT_provoking_vertex or similar
12724 * functionality being available. */
12725 /* PHONG should be the same as GOURAUD, since no hardware implements
12727 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
12728 i
, color0
, tests
[i
].color0
);
12729 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
12730 i
, color1
, tests
[i
].color1
);
12733 IDirect3DVertexBuffer_Release(vb_strip
);
12734 IDirect3DVertexBuffer_Release(vb_list
);
12735 destroy_viewport(device
, viewport
);
12736 IDirectDrawSurface4_Release(rt
);
12737 IDirect3D3_Release(d3d
);
12738 refcount
= IDirect3DDevice3_Release(device
);
12739 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12740 DestroyWindow(window
);
12743 static void test_lockrect_invalid(void)
12746 IDirectDraw4
*ddraw
;
12747 IDirectDrawSurface4
*surface
;
12750 DDSURFACEDESC2 surface_desc
;
12752 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
12753 static RECT valid
[] =
12758 {120, 60, 128, 68},
12759 {60, 120, 68, 128},
12761 static RECT invalid
[] =
12763 {68, 60, 60, 68}, /* left > right */
12764 {60, 68, 68, 60}, /* top > bottom */
12765 {-8, 60, 0, 68}, /* left < surface */
12766 {60, -8, 68, 0}, /* top < surface */
12767 {-16, 60, -8, 68}, /* right < surface */
12768 {60, -16, 68, -8}, /* bottom < surface */
12769 {60, 60, 136, 68}, /* right > surface */
12770 {60, 60, 68, 136}, /* bottom > surface */
12771 {136, 60, 144, 68}, /* left > surface */
12772 {60, 136, 68, 144}, /* top > surface */
12774 static const struct
12783 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12784 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
12785 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", TRUE
, DDERR_INVALIDPARAMS
},
12786 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", TRUE
, DDERR_INVALIDPARAMS
},
12787 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", TRUE
, DDERR_INVALIDPARAMS
},
12789 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12790 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12791 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12792 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
12793 {DDSCAPS_TEXTURE
| DDSCAPS_WRITEONLY
, DDSCAPS2_TEXTUREMANAGE
, "managed texture writeonly", TRUE
, DDERR_INVALIDPARAMS
},
12796 window
= create_window();
12797 ddraw
= create_ddraw();
12798 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12799 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12800 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12802 memset(&hal_caps
, 0, sizeof(hal_caps
));
12803 hal_caps
.dwSize
= sizeof(hal_caps
);
12804 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
12805 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
12806 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
12807 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
12809 skip("Required surface types not supported, skipping test.\n");
12813 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
12815 memset(&surface_desc
, 0, sizeof(surface_desc
));
12816 surface_desc
.dwSize
= sizeof(surface_desc
);
12817 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12818 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
12819 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
12820 surface_desc
.dwWidth
= 128;
12821 surface_desc
.dwHeight
= 128;
12822 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12823 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12824 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12825 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
12826 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
12827 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
12829 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12830 if (!resources
[r
].allowed
)
12832 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12835 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12837 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
12838 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12840 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
12842 RECT
*rect
= &valid
[i
];
12844 memset(&surface_desc
, 0, sizeof(surface_desc
));
12845 surface_desc
.dwSize
= sizeof(surface_desc
);
12847 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12848 ok(SUCCEEDED(hr
), "Lock failed (%#lx) for rect %s, type %s.\n",
12849 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12851 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12852 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12855 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
12857 RECT
*rect
= &invalid
[i
];
12859 memset(&surface_desc
, 1, sizeof(surface_desc
));
12860 surface_desc
.dwSize
= sizeof(surface_desc
);
12862 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12863 ok(hr
== resources
[r
].hr
, "Lock returned %#lx for rect %s, type %s.\n",
12864 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
12867 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12868 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12871 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
12874 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12875 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#lx, type %s.\n",
12876 hr
, resources
[r
].name
);
12877 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12878 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#lx, type %s.\n",
12879 hr
, resources
[r
].name
);
12880 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12881 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12883 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
12884 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#lx).\n", wine_dbgstr_rect(&valid
[0]), hr
);
12885 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
12886 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#lx).\n",
12887 wine_dbgstr_rect(&valid
[0]), hr
);
12889 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
12890 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
12892 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12893 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
12895 IDirectDrawSurface4_Release(surface
);
12899 IDirectDraw4_Release(ddraw
);
12900 DestroyWindow(window
);
12903 static void test_yv12_overlay(void)
12905 IDirectDrawSurface4
*src_surface
, *dst_surface
;
12906 RECT rect
= {13, 17, 14, 18};
12907 unsigned int offset
, y
;
12908 DDSURFACEDESC2 desc
;
12909 unsigned char *base
;
12910 IDirectDraw4
*ddraw
;
12914 window
= create_window();
12915 ddraw
= create_ddraw();
12916 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12917 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12918 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12920 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12922 skip("Failed to create a YV12 overlay, skipping test.\n");
12926 memset(&desc
, 0, sizeof(desc
));
12927 desc
.dwSize
= sizeof(desc
);
12928 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12929 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12931 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
12932 "Got unexpected flags %#lx.\n", desc
.dwFlags
);
12933 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
12934 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
12935 "Got unexpected caps %#lx.\n", desc
.ddsCaps
.dwCaps
);
12936 ok(desc
.dwWidth
== 256, "Got unexpected width %lu.\n", desc
.dwWidth
);
12937 ok(desc
.dwHeight
== 256, "Got unexpected height %lu.\n", desc
.dwHeight
);
12938 /* The overlay pitch seems to have 256 byte alignment. */
12939 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %lu.\n", U1(desc
).lPitch
);
12941 /* Fill the surface with some data for the blit test. */
12942 base
= desc
.lpSurface
;
12944 for (y
= 0; y
< desc
.dwHeight
; ++y
)
12946 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
12949 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
12951 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
12954 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
12956 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
12959 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
12960 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12962 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
12963 * other block-based formats like DXT the entire Y channel is stored in
12964 * one big chunk of memory, followed by the chroma channels. So partial
12965 * locks do not really make sense. Show that they are allowed nevertheless
12966 * and the offset points into the luminance data. */
12967 hr
= IDirectDrawSurface4_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
12968 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12969 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
12970 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %lu.\n",
12971 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
12972 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
12973 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12975 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
12977 /* Windows XP with a Radeon X1600 GPU refuses to create a second
12978 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
12979 skip("Failed to create a second YV12 surface, skipping blit test.\n");
12980 IDirectDrawSurface4_Release(src_surface
);
12984 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
12985 /* VMware rejects YV12 blits. This behavior has not been seen on real
12986 * hardware yet, so mark it broken. */
12987 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#lx.\n", hr
);
12991 memset(&desc
, 0, sizeof(desc
));
12992 desc
.dwSize
= sizeof(desc
);
12993 hr
= IDirectDrawSurface4_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
12994 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12996 base
= desc
.lpSurface
;
12997 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
12998 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
12999 ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
13000 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
13001 ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
13003 hr
= IDirectDrawSurface4_Unlock(dst_surface
, NULL
);
13004 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
13007 IDirectDrawSurface4_Release(dst_surface
);
13008 IDirectDrawSurface4_Release(src_surface
);
13010 IDirectDraw4_Release(ddraw
);
13011 DestroyWindow(window
);
13014 static BOOL
dwm_enabled(void)
13018 if (!strcmp(winetest_platform
, "wine"))
13020 if (!pDwmIsCompositionEnabled
)
13022 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
13027 static void test_offscreen_overlay(void)
13029 IDirectDrawSurface4
*overlay
, *offscreen
, *primary
;
13030 DDSURFACEDESC2 surface_desc
;
13031 IDirectDraw4
*ddraw
;
13036 window
= create_window();
13037 ddraw
= create_ddraw();
13038 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13039 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13040 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13042 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
13044 skip("Failed to create a UYVY overlay, skipping test.\n");
13048 memset(&surface_desc
, 0, sizeof(surface_desc
));
13049 surface_desc
.dwSize
= sizeof(surface_desc
);
13050 surface_desc
.dwFlags
= DDSD_CAPS
;
13051 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13052 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13053 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
13055 /* On Windows 7, and probably Vista, UpdateOverlay() will return
13056 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
13057 * surface prevents this by disabling the dwm. */
13058 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
13059 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
13060 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
13061 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
13063 /* Try to overlay a NULL surface. */
13064 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
13065 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13066 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
13067 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13069 /* Try to overlay an offscreen surface. */
13070 memset(&surface_desc
, 0, sizeof(surface_desc
));
13071 surface_desc
.dwSize
= sizeof(surface_desc
);
13072 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
13073 surface_desc
.dwWidth
= 64;
13074 surface_desc
.dwHeight
= 64;
13075 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13076 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
13077 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13078 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
13079 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
13080 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
13081 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
13082 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
13083 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
13084 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
13086 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
13087 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
13088 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
13089 "Failed to update overlay, hr %#lx.\n", hr
);
13091 /* Try to overlay the primary with a non-overlay surface. */
13092 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
13093 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
13094 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
13095 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
13097 IDirectDrawSurface4_Release(offscreen
);
13098 IDirectDrawSurface4_Release(primary
);
13099 IDirectDrawSurface4_Release(overlay
);
13101 IDirectDraw4_Release(ddraw
);
13102 DestroyWindow(window
);
13105 static void test_overlay_rect(void)
13107 IDirectDrawSurface4
*overlay
, *primary
= NULL
;
13108 DDSURFACEDESC2 surface_desc
;
13109 RECT rect
= {0, 0, 64, 64};
13110 IDirectDraw4
*ddraw
;
13116 window
= create_window();
13117 ddraw
= create_ddraw();
13118 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13119 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13120 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13122 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
13124 skip("Failed to create a UYVY overlay, skipping test.\n");
13128 memset(&surface_desc
, 0, sizeof(surface_desc
));
13129 surface_desc
.dwSize
= sizeof(surface_desc
);
13130 surface_desc
.dwFlags
= DDSD_CAPS
;
13131 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13132 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13133 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
13135 /* On Windows 7, and probably Vista, UpdateOverlay() will return
13136 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
13137 * surface prevents this by disabling the dwm. */
13138 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
13139 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
13140 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
13141 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
13143 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
13146 win_skip("Cannot disable DWM, skipping overlay test.\n");
13150 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
13151 * used. This is not true in Windows Vista and earlier, but changed in
13153 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
13154 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
13155 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
13156 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
13157 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
13158 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13160 /* Show that the overlay position is the (top, left) coordinate of the
13161 * destination rectangle. */
13162 OffsetRect(&rect
, 32, 16);
13163 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
13164 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
13165 pos_x
= -1; pos_y
= -1;
13166 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13167 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
13168 ok(pos_x
== rect
.left
, "Got unexpected pos_x %ld, expected %ld.\n", pos_x
, rect
.left
);
13169 ok(pos_y
== rect
.top
, "Got unexpected pos_y %ld, expected %ld.\n", pos_y
, rect
.top
);
13171 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
13172 * seen that the overlay overlays the whole primary(==screen). */
13173 hr2
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
13174 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#lx.\n", hr2
);
13175 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13176 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
13177 if (SUCCEEDED(hr2
))
13179 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
13180 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
13184 ok(pos_x
== 32, "Got unexpected pos_x %ld.\n", pos_x
);
13185 ok(pos_y
== 16, "Got unexpected pos_y %ld.\n", pos_y
);
13188 /* The position cannot be retrieved when the overlay is not shown. */
13189 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
13190 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
13191 pos_x
= -1; pos_y
= -1;
13192 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
13193 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#lx.\n", hr
);
13194 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
13195 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
13199 IDirectDrawSurface4_Release(primary
);
13201 IDirectDrawSurface4_Release(overlay
);
13202 IDirectDraw4_Release(ddraw
);
13203 DestroyWindow(window
);
13206 static void test_blt(void)
13208 IDirectDrawSurface4
*surface
, *rt
;
13209 DDSURFACEDESC2 surface_desc
;
13210 IDirect3DDevice3
*device
;
13211 IDirectDraw4
*ddraw
;
13226 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
13227 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
13228 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
13229 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
13230 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
13231 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
13232 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
13233 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
13234 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
13235 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
13238 window
= create_window();
13239 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13241 skip("Failed to create a 3D device, skipping test.\n");
13242 DestroyWindow(window
);
13246 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
13247 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
13248 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
13249 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
13250 IDirect3D3_Release(d3d
);
13251 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
13252 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13254 memset(&surface_desc
, 0, sizeof(surface_desc
));
13255 surface_desc
.dwSize
= sizeof(surface_desc
);
13256 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13257 surface_desc
.dwWidth
= 640;
13258 surface_desc
.dwHeight
= 480;
13259 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13260 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13261 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13263 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
13264 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13266 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
13267 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
13269 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13271 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
13272 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13273 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
13275 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
13276 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13277 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
13279 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
13280 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
13281 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13283 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
13284 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13287 IDirectDrawSurface4_Release(surface
);
13288 IDirectDrawSurface4_Release(rt
);
13289 IDirectDraw4_Release(ddraw
);
13290 refcount
= IDirect3DDevice3_Release(device
);
13291 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13292 DestroyWindow(window
);
13295 static void test_blt_z_alpha(void)
13297 DWORD blt_flags
[] =
13301 DDBLT_ALPHADESTCONSTOVERRIDE
,
13302 DDBLT_ALPHADESTNEG
,
13303 DDBLT_ALPHADESTSURFACEOVERRIDE
,
13304 DDBLT_ALPHAEDGEBLEND
,
13307 DDBLT_ALPHASRCCONSTOVERRIDE
,
13309 DDBLT_ALPHASRCSURFACEOVERRIDE
,
13312 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
13313 DDBLT_ZBUFFERDESTOVERRIDE
,
13314 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
13315 DDBLT_ZBUFFERSRCOVERRIDE
,
13317 IDirectDrawSurface4
*src_surface
, *dst_surface
;
13318 DDSURFACEDESC2 surface_desc
;
13319 unsigned int color
, i
;
13320 IDirectDraw4
*ddraw
;
13327 window
= create_window();
13328 ddraw
= create_ddraw();
13329 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13330 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13331 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13333 memset(&pf
, 0, sizeof(pf
));
13334 pf
.dwSize
= sizeof(pf
);
13335 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13336 U1(pf
).dwRGBBitCount
= 32;
13337 U2(pf
).dwRBitMask
= 0x00ff0000;
13338 U3(pf
).dwGBitMask
= 0x0000ff00;
13339 U4(pf
).dwBBitMask
= 0x000000ff;
13340 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
13342 memset(&surface_desc
, 0, sizeof(surface_desc
));
13343 surface_desc
.dwSize
= sizeof(surface_desc
);
13344 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13345 surface_desc
.dwWidth
= 64;
13346 surface_desc
.dwHeight
= 64;
13347 U4(surface_desc
).ddpfPixelFormat
= pf
;
13348 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13350 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
13351 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
13352 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
13353 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
13355 memset(&fx
, 0, sizeof(fx
));
13356 fx
.dwSize
= sizeof(fx
);
13357 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
13358 fx
.dwZDestConstBitDepth
= 32;
13359 U1(fx
).dwZDestConst
= 0x11111111;
13360 fx
.dwZSrcConstBitDepth
= 32;
13361 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
13362 fx
.dwAlphaEdgeBlendBitDepth
= 8;
13363 fx
.dwAlphaEdgeBlend
= 0x7f;
13364 fx
.dwAlphaDestConstBitDepth
= 8;
13365 U3(fx
).dwAlphaDestConst
= 0xdd;
13366 fx
.dwAlphaSrcConstBitDepth
= 8;
13367 U4(fx
).dwAlphaSrcConst
= 0x22;
13369 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
13371 U5(fx
).dwFillColor
= 0x3300ff00;
13372 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13373 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13375 U5(fx
).dwFillColor
= 0xccff0000;
13376 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13377 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13379 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
13380 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13382 color
= get_surface_color(dst_surface
, 32, 32);
13383 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
13386 IDirectDrawSurface4_Release(dst_surface
);
13387 IDirectDrawSurface4_Release(src_surface
);
13388 refcount
= IDirectDraw4_Release(ddraw
);
13389 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13390 DestroyWindow(window
);
13393 static void test_cross_device_blt(void)
13395 IDirectDrawSurface4
*surface
, *surface2
, *sysmem_surface
;
13396 IDirect3DDevice3
*device
, *device2
;
13397 IDirectDraw4
*ddraw
, *ddraw2
;
13398 DDSURFACEDESC2 surface_desc
;
13399 HWND window
, window2
;
13400 unsigned int color
;
13406 window
= create_window();
13407 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
13409 skip("Failed to create a 3D device.\n");
13410 DestroyWindow(window
);
13414 window2
= create_window();
13415 if (!(device2
= create_device(window2
, DDSCL_NORMAL
)))
13417 skip("Failed to create a 3D device.\n");
13418 IDirect3DDevice3_Release(device
);
13419 DestroyWindow(window
);
13420 DestroyWindow(window2
);
13424 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
13425 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
13426 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
13427 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
13428 IDirect3D3_Release(d3d
);
13430 hr
= IDirect3DDevice3_GetDirect3D(device2
, &d3d
);
13431 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
13432 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw2
);
13433 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
13434 IDirect3D3_Release(d3d
);
13436 memset(&surface_desc
, 0, sizeof(surface_desc
));
13437 surface_desc
.dwSize
= sizeof(surface_desc
);
13438 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13439 surface_desc
.dwWidth
= 640;
13440 surface_desc
.dwHeight
= 480;
13441 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13442 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
13443 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13445 memset(&surface_desc
, 0, sizeof(surface_desc
));
13446 surface_desc
.dwSize
= sizeof(surface_desc
);
13447 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13448 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
13449 U5(surface_desc
).dwBackBufferCount
= 2;
13450 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13451 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13453 memset(&surface_desc
, 0, sizeof(surface_desc
));
13454 surface_desc
.dwSize
= sizeof(surface_desc
);
13455 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
13456 surface_desc
.dwWidth
= 640;
13457 surface_desc
.dwHeight
= 480;
13458 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13459 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
13460 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13461 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
13462 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
13463 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
13464 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
13465 hr
= IDirectDraw4_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13466 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13468 memset(&fx
, 0, sizeof(fx
));
13469 fx
.dwSize
= sizeof(fx
);
13470 U5(fx
).dwFillColor
= 0xff0000ff;
13471 hr
= IDirectDrawSurface4_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13472 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
13474 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13475 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
13476 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
13477 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13478 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13479 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
13480 color
= get_surface_color(surface
, 320, 240);
13481 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13483 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13484 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
13485 color
= get_surface_color(sysmem_surface
, 320, 240);
13486 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13488 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13489 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13490 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
13491 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13493 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13494 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
13495 color
= get_surface_color(sysmem_surface
, 320, 240);
13496 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
13498 IDirectDrawSurface4_Release(surface2
);
13499 memset(&surface_desc
, 0, sizeof(surface_desc
));
13500 surface_desc
.dwSize
= sizeof(surface_desc
);
13501 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
13502 surface_desc
.dwWidth
= 640;
13503 surface_desc
.dwHeight
= 480;
13504 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
13505 hr
= IDirectDraw4_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
13506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13507 hr
= IDirectDrawSurface4_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
13508 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
13510 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
13511 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#lx.\n", hr
);
13512 color
= get_surface_color(sysmem_surface
, 320, 240);
13513 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13515 IDirectDrawSurface4_Release(surface
);
13516 IDirectDrawSurface4_Release(surface2
);
13517 IDirectDrawSurface4_Release(sysmem_surface
);
13518 IDirectDraw4_Release(ddraw
);
13519 IDirectDraw4_Release(ddraw2
);
13520 refcount
= IDirect3DDevice3_Release(device
);
13521 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13522 refcount
= IDirect3DDevice3_Release(device2
);
13523 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13524 DestroyWindow(window
);
13525 DestroyWindow(window2
);
13528 static void test_color_clamping(void)
13530 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
13531 static D3DMATRIX mat
=
13533 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13534 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13535 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13536 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13538 static struct vec3 quad
[] =
13540 {-1.0f
, -1.0f
, 0.1f
},
13541 {-1.0f
, 1.0f
, 0.1f
},
13542 { 1.0f
, -1.0f
, 0.1f
},
13543 { 1.0f
, 1.0f
, 0.1f
},
13545 IDirect3DViewport3
*viewport
;
13546 IDirect3DDevice3
*device
;
13547 IDirectDrawSurface4
*rt
;
13548 unsigned int color
;
13553 window
= create_window();
13554 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13556 skip("Failed to create a 3D device, skipping test.\n");
13557 DestroyWindow(window
);
13561 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
13562 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13564 viewport
= create_viewport(device
, 0, 0, 640, 480);
13565 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
13566 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
13568 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
13569 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
13570 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
13571 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
13572 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
13573 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
13574 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13575 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#lx.\n", hr
);
13576 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13577 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
13578 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
13579 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#lx.\n", hr
);
13580 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13581 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
13583 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
13584 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#lx.\n", hr
);
13585 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
13586 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
13587 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
13588 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
13589 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
13590 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
13591 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
13592 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
13593 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
13594 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
13595 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
13596 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
13598 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
13599 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
13601 hr
= IDirect3DDevice3_BeginScene(device
);
13602 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
13604 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
13605 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
13607 hr
= IDirect3DDevice3_EndScene(device
);
13608 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
13610 color
= get_surface_color(rt
, 320, 240);
13611 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
13613 destroy_viewport(device
, viewport
);
13614 IDirectDrawSurface4_Release(rt
);
13615 refcount
= IDirect3DDevice3_Release(device
);
13616 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13617 DestroyWindow(window
);
13620 static void test_getdc(void)
13622 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
13623 IDirectDrawSurface4
*surface
, *surface2
, *tmp
;
13624 DDSURFACEDESC2 surface_desc
, map_desc
;
13625 IDirectDraw4
*ddraw
;
13626 unsigned int i
, screen_bpp
;
13631 static const struct
13634 DDPIXELFORMAT format
;
13635 BOOL getdc_supported
;
13636 HRESULT alt_result
;
13640 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13641 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
13642 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13643 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
13644 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13645 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13646 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13647 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
13648 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13649 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
13650 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
13651 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13652 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
13653 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13654 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13655 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
13656 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
13657 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13658 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
13659 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
13660 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
13661 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
13662 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
13663 * This is not implemented in wine yet, so disable the test for now.
13664 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
13665 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
13666 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
13668 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
13669 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13670 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
13671 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
13672 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
13673 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13674 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
13675 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13676 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
13677 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13678 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
13679 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13680 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
13681 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
13684 window
= create_window();
13685 ddraw
= create_ddraw();
13686 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13687 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13688 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13690 surface_desc
.dwSize
= sizeof(surface_desc
);
13691 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13692 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
13693 screen_bpp
= U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
;
13695 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13697 memset(&surface_desc
, 0, sizeof(surface_desc
));
13698 surface_desc
.dwSize
= sizeof(surface_desc
);
13699 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13700 surface_desc
.dwWidth
= 64;
13701 surface_desc
.dwHeight
= 64;
13702 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
13703 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13705 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13707 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13708 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
13709 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13711 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", test_data
[i
].name
, hr
);
13716 dc
= (void *)0x1234;
13717 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13718 if (test_data
[i
].getdc_supported
)
13719 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
13720 "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13722 ok(FAILED(hr
), "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13726 unsigned int width_bytes
;
13732 type
= GetObjectType(dc
);
13733 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
13734 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
13735 type
= GetObjectType(bitmap
);
13736 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
13738 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
13739 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
13740 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
13741 dib
.dsBm
.bmType
, test_data
[i
].name
);
13742 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
13743 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
13744 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
13745 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
13746 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
13747 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
13748 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
13749 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
13750 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
13751 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
13752 "Got unexpected bit count %d for format %s.\n",
13753 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
13754 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
13755 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
13756 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
13757 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
13758 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
13760 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %lu for format %s.\n",
13761 dib
.dsBmih
.biSize
, test_data
[i
].name
);
13762 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %ld for format %s.\n",
13763 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13764 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %ld for format %s.\n",
13765 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
13766 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
13767 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
13768 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
13769 "Got unexpected bit count %u for format %s.\n",
13770 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
13771 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
13772 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
13773 "Got unexpected compression %#lx for format %s.\n",
13774 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
13775 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %lu for format %s.\n",
13776 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
13777 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %ld for format %s.\n",
13778 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
13779 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %ld for format %s.\n",
13780 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
13781 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %lu for format %s.\n",
13782 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
13783 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %lu for format %s.\n",
13784 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
13786 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
13788 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
13789 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
13790 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
13791 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
13792 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
13793 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13797 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
13798 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
13799 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
13801 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
13802 ok(!dib
.dsOffset
, "Got unexpected offset %lu for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
13804 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13805 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13809 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13812 IDirectDrawSurface4_Release(surface
);
13817 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
13818 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
13819 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
13821 skip("Failed to create mip-mapped texture for format %s (hr %#lx), skipping tests.\n",
13822 test_data
[i
].name
, hr
);
13826 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
13827 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13828 hr
= IDirectDrawSurface4_GetAttachedSurface(tmp
, &caps
, &surface2
);
13829 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13830 IDirectDrawSurface4_Release(tmp
);
13832 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13833 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13834 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13835 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13836 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
13837 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13838 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
13839 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13841 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13842 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13843 dc2
= (void *)0x1234;
13844 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
13845 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13846 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
13847 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13848 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13849 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13850 ok(hr
== DDERR_NODC
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13852 map_desc
.dwSize
= sizeof(map_desc
);
13853 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13854 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13855 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13856 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13857 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13858 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13859 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13860 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13862 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13863 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13864 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13865 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13866 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13867 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13869 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13870 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13871 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13872 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13873 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13874 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13875 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13876 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13878 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13879 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13880 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc2
);
13881 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13882 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc2
);
13883 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13884 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13885 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13887 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
13888 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13889 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
13890 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13891 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc2
);
13892 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13893 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
13894 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13896 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13897 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13898 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13899 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13900 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13901 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13902 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13903 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13905 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13906 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13907 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13908 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13909 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13910 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13911 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13912 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13914 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13915 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13916 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13917 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13918 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13919 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13920 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13921 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13923 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13924 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13925 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13926 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13927 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13928 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13929 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13930 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13932 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
13933 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13934 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
13935 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13936 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13937 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13938 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
13939 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13941 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13942 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13943 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
13944 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13945 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13946 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13947 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
13948 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13949 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
13950 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13952 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13953 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13954 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13955 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13956 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13957 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13958 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13959 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
13960 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
13961 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
13963 IDirectDrawSurface4_Release(surface2
);
13964 IDirectDrawSurface4_Release(surface
);
13967 IDirectDraw4_Release(ddraw
);
13968 DestroyWindow(window
);
13971 static void test_draw_primitive(void)
13973 static WORD indices
[] = {0, 1, 2, 3};
13974 static struct vec3 quad
[] =
13976 {-1.0f
, -1.0f
, 0.0f
},
13977 {-1.0f
, 1.0f
, 0.0f
},
13978 { 1.0f
, -1.0f
, 0.0f
},
13979 { 1.0f
, 1.0f
, 0.0f
},
13981 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
13982 IDirect3DViewport3
*viewport
;
13983 D3DVERTEXBUFFERDESC vb_desc
;
13984 IDirect3DVertexBuffer
*vb
;
13985 IDirect3DDevice3
*device
;
13992 window
= create_window();
13993 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13995 skip("Failed to create a 3D device, skipping test.\n");
13996 DestroyWindow(window
);
14000 viewport
= create_viewport(device
, 0, 0, 640, 480);
14001 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14002 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
14004 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14005 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
14007 memset(&vb_desc
, 0, sizeof(vb_desc
));
14008 vb_desc
.dwSize
= sizeof(vb_desc
);
14009 vb_desc
.dwFVF
= D3DFVF_XYZ
;
14010 vb_desc
.dwNumVertices
= 4;
14011 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
14012 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
14014 IDirect3D3_Release(d3d
);
14016 memset(&strided
, 0, sizeof(strided
));
14018 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
14019 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14020 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
14021 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
14022 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14023 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
14024 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14025 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
14026 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14027 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
14028 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14029 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
14030 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14032 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
14033 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14034 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
14035 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
14036 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14037 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
14038 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14040 strided
.position
.lpvData
= quad
;
14041 strided
.position
.dwStride
= sizeof(*quad
);
14042 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, &data
, NULL
);
14043 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
14044 memcpy(data
, quad
, sizeof(quad
));
14045 hr
= IDirect3DVertexBuffer_Unlock(vb
);
14046 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
14048 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
14049 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14050 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
14051 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
14052 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14053 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
14054 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14055 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
14056 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14057 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
14058 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14059 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
14060 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14061 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
14062 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14063 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
14064 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
14065 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14066 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
14067 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14069 IDirect3DVertexBuffer_Release(vb
);
14070 destroy_viewport(device
, viewport
);
14071 refcount
= IDirect3DDevice3_Release(device
);
14072 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14073 DestroyWindow(window
);
14076 static void test_edge_antialiasing_blending(void)
14078 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14079 IDirectDrawSurface4
*offscreen
, *ds
;
14080 D3DDEVICEDESC hal_desc
, hel_desc
;
14081 IDirect3DViewport3
*viewport
;
14082 DDSURFACEDESC2 surface_desc
;
14083 IDirect3DDevice3
*device
;
14084 IDirectDraw4
*ddraw
;
14085 unsigned int color
;
14091 static D3DMATRIX mat
=
14093 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14094 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14095 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14096 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14100 struct vec3 position
;
14105 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
14106 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
14107 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
14108 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
14112 struct vec3 position
;
14117 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
14118 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
14119 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
14120 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
14123 window
= create_window();
14124 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14126 skip("Failed to create a 3D device.\n");
14127 DestroyWindow(window
);
14131 memset(&hal_desc
, 0, sizeof(hal_desc
));
14132 hal_desc
.dwSize
= sizeof(hal_desc
);
14133 memset(&hel_desc
, 0, sizeof(hel_desc
));
14134 hel_desc
.dwSize
= sizeof(hel_desc
);
14135 hr
= IDirect3DDevice3_GetCaps(device
, &hal_desc
, &hel_desc
);
14136 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
14137 trace("HAL line edge antialiasing support: %#lx.\n",
14138 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14139 trace("HAL triangle edge antialiasing support: %#lx.\n",
14140 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14141 trace("HEL line edge antialiasing support: %#lx.\n",
14142 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14143 trace("HEL triangle edge antialiasing support: %#lx.\n",
14144 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
14146 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14147 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#lx.\n", hr
);
14148 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14149 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#lx.\n", hr
);
14150 IDirect3D3_Release(d3d
);
14152 memset(&surface_desc
, 0, sizeof(surface_desc
));
14153 surface_desc
.dwSize
= sizeof(surface_desc
);
14154 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
14155 surface_desc
.dwWidth
= 640;
14156 surface_desc
.dwHeight
= 480;
14157 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
14158 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
14159 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14160 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14161 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14162 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14163 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
14164 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
14165 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#lx.\n", hr
);
14167 ds
= get_depth_stencil(device
);
14168 hr
= IDirectDrawSurface4_AddAttachedSurface(offscreen
, ds
);
14169 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
14170 IDirectDrawSurface4_Release(ds
);
14172 hr
= IDirect3DDevice3_SetRenderTarget(device
, offscreen
, 0);
14173 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
14175 viewport
= create_viewport(device
, 0, 0, 640, 480);
14176 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14177 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
14179 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
14180 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14181 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
14182 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
14183 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
14184 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
14185 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
14186 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#lx.\n", hr
);
14187 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
14188 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#lx.\n", hr
);
14189 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
14190 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#lx.\n", hr
);
14191 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
14192 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
14194 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
14195 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#lx.\n", hr
);
14196 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
14197 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#lx.\n", hr
);
14198 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
14199 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#lx.\n", hr
);
14201 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
14202 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#lx.\n", hr
);
14203 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
14204 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#lx.\n", hr
);
14205 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
14206 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#lx.\n", hr
);
14207 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
14208 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#lx.\n", hr
);
14210 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14211 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14212 hr
= IDirect3DDevice3_BeginScene(device
);
14213 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14214 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14216 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14217 hr
= IDirect3DDevice3_EndScene(device
);
14218 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14219 color
= get_surface_color(offscreen
, 320, 240);
14220 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
14222 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14223 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14224 hr
= IDirect3DDevice3_BeginScene(device
);
14225 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14226 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14228 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14229 hr
= IDirect3DDevice3_EndScene(device
);
14230 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14231 color
= get_surface_color(offscreen
, 320, 240);
14232 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
14234 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
14235 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#lx.\n", hr
);
14237 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14238 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14239 hr
= IDirect3DDevice3_BeginScene(device
);
14240 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14241 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14243 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14244 hr
= IDirect3DDevice3_EndScene(device
);
14245 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14246 color
= get_surface_color(offscreen
, 320, 240);
14247 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14249 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14250 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14251 hr
= IDirect3DDevice3_BeginScene(device
);
14252 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14253 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14255 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14256 hr
= IDirect3DDevice3_EndScene(device
);
14257 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14258 color
= get_surface_color(offscreen
, 320, 240);
14259 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14261 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
14262 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#lx.\n", hr
);
14264 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
14265 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14266 hr
= IDirect3DDevice3_BeginScene(device
);
14267 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14268 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14270 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14271 hr
= IDirect3DDevice3_EndScene(device
);
14272 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14273 color
= get_surface_color(offscreen
, 320, 240);
14274 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14276 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
14277 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14278 hr
= IDirect3DDevice3_BeginScene(device
);
14279 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14280 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14282 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14283 hr
= IDirect3DDevice3_EndScene(device
);
14284 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14285 color
= get_surface_color(offscreen
, 320, 240);
14286 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14288 IDirectDrawSurface4_Release(offscreen
);
14289 IDirectDraw4_Release(ddraw
);
14290 destroy_viewport(device
, viewport
);
14291 refcount
= IDirect3DDevice3_Release(device
);
14292 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14293 DestroyWindow(window
);
14296 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
14297 * The stride is honored for navigating to the next vertex. 3 floats input position
14298 * are read, and 16 bytes extra vertex data are copied around. */
14299 struct transform_input
14301 float x
, y
, z
, unused1
; /* Position data, transformed. */
14302 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
14306 struct transform_output
14309 unsigned int v1
, v2
, v3
, v4
;
14310 unsigned int unused3
, unused4
;
14313 static void test_transform_vertices(void)
14315 IDirect3DDevice3
*device
;
14316 IDirectDrawSurface4
*rt
;
14317 unsigned int color
;
14321 IDirect3DViewport3
*viewport
;
14322 static struct transform_input position_tests
[] =
14324 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
14325 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
14326 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
14327 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
14328 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
14329 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
14331 static struct transform_input cliptest
[] =
14333 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
14334 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
14335 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
14336 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
14338 static struct transform_input offscreentest
[] =
14340 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
14342 struct transform_output out
[ARRAY_SIZE(position_tests
)];
14343 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
14344 D3DTRANSFORMDATA transformdata
;
14345 static const D3DVIEWPORT vp_template
=
14347 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
14349 D3DVIEWPORT vp_data
=
14351 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
14353 D3DVIEWPORT2 vp2_data
;
14356 static D3DMATRIX mat_scale
=
14358 2.0f
, 0.0f
, 0.0f
, 0.0f
,
14359 0.0f
, 2.0f
, 0.0f
, 0.0f
,
14360 0.0f
, 0.0f
, 2.0f
, 0.0f
,
14361 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14365 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14366 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14367 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14368 1.0f
, 0.0f
, 0.0f
, 1.0f
,
14372 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14373 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14374 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14375 0.0f
, 1.0f
, 0.0f
, 1.0f
,
14379 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14380 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14381 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14382 0.0f
, 19.2f
, 0.0f
, 2.0f
,
14386 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14387 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14388 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14389 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14393 struct vec3 position
;
14398 {{-0.75f
, -0.5f
, 0.0f
}, 0xffff0000},
14399 {{-0.75f
, 0.25f
, 0.0f
}, 0xffff0000},
14400 {{ 0.5f
, -0.5f
, 0.0f
}, 0xffff0000},
14401 {{ 0.5f
, 0.25f
, 0.0f
}, 0xffff0000},
14403 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14405 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
14407 out
[i
].unused3
= 0xdeadbeef;
14408 out
[i
].unused4
= 0xcafecafe;
14411 window
= create_window();
14412 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14414 skip("Failed to create a 3D device.\n");
14415 DestroyWindow(window
);
14418 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14419 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
14421 viewport
= create_viewport(device
, 0, 0, 256, 256);
14422 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14423 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14425 memset(&transformdata
, 0, sizeof(transformdata
));
14426 transformdata
.dwSize
= sizeof(transformdata
);
14427 transformdata
.lpIn
= position_tests
;
14428 transformdata
.dwInSize
= sizeof(position_tests
[0]);
14429 transformdata
.lpOut
= out
;
14430 transformdata
.dwOutSize
= sizeof(out
[0]);
14431 transformdata
.lpHOut
= NULL
;
14433 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14434 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14435 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14436 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14438 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14440 static const struct vec4 cmp
[] =
14442 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
14443 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
14446 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14447 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14448 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14449 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
14450 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
14451 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
14452 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
14453 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
14456 vp_data
= vp_template
;
14457 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14458 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14459 offscreen
= 0xdeadbeef;
14460 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14461 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14462 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14463 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14465 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14467 static const struct vec4 cmp
[] =
14469 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
14470 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
14472 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14473 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14474 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14479 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14480 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14481 offscreen
= 0xdeadbeef;
14482 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14483 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14484 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14485 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14486 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14488 static const struct vec4 cmp
[] =
14490 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
14491 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
14493 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14494 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14495 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14498 transformdata
.lpHOut
= out_h
;
14499 offscreen
= 0xdeadbeef;
14500 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14501 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14502 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14503 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14504 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14506 static const D3DHVERTEX cmp_h
[] =
14508 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
14509 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
14510 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
14512 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
14513 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
14514 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
14515 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
14516 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
14517 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
14519 /* No scheme has been found behind those return values. It seems to be
14520 * whatever data windows has when throwing the vertex away. Modify the
14521 * input test vertices to test this more. Depending on the input data
14522 * it can happen that the z coord gets written into y, or similar things. */
14525 static const struct vec4 cmp
[] =
14527 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
14528 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
14530 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14531 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14532 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14536 transformdata
.lpIn
= cliptest
;
14537 transformdata
.dwInSize
= sizeof(cliptest
[0]);
14538 offscreen
= 0xdeadbeef;
14539 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
14540 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14541 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14542 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14543 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
14545 static const DWORD flags
[] =
14548 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
14550 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
14552 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
14555 vp_data
= vp_template
;
14556 vp_data
.dwWidth
= 10;
14557 vp_data
.dwHeight
= 480;
14558 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14559 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14560 offscreen
= 0xdeadbeef;
14561 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
14562 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14563 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14564 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14565 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
14567 static const DWORD flags
[] =
14570 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
14572 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
14574 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
14577 vp_data
= vp_template
;
14578 vp_data
.dwWidth
= 256;
14579 vp_data
.dwHeight
= 256;
14580 vp_data
.dvScaleX
= 1;
14581 vp_data
.dvScaleY
= 1;
14582 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14583 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14584 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
14585 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14586 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14587 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14588 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
14590 static const DWORD flags
[] =
14597 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
14600 /* Finally try to figure out how the DWORD dwOffscreen works.
14601 * It is a logical AND of the vertices' dwFlags members. */
14602 vp_data
= vp_template
;
14603 vp_data
.dwWidth
= 5;
14604 vp_data
.dwHeight
= 5;
14605 vp_data
.dvScaleX
= 10000.0f
;
14606 vp_data
.dvScaleY
= 10000.0f
;
14607 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14608 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14609 transformdata
.lpIn
= cliptest
;
14610 offscreen
= 0xdeadbeef;
14611 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14612 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14613 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14614 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14616 offscreen
= 0xdeadbeef;
14617 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14618 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14619 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14620 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
14621 offscreen
= 0xdeadbeef;
14622 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
14623 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14624 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14625 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
14626 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
14627 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14628 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14629 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14631 transformdata
.lpIn
= cliptest
+ 1;
14632 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14633 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14634 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14635 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
14637 transformdata
.lpIn
= cliptest
+ 2;
14638 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14639 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14640 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14641 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
14642 offscreen
= 0xdeadbeef;
14643 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
14644 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14645 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14646 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
14648 transformdata
.lpIn
= cliptest
+ 3;
14649 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14650 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14651 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14652 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
14654 transformdata
.lpIn
= offscreentest
;
14655 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
14656 vp_data
= vp_template
;
14657 vp_data
.dwWidth
= 257;
14658 vp_data
.dwHeight
= 257;
14659 vp_data
.dvScaleX
= 1.0f
;
14660 vp_data
.dvScaleY
= 1.0f
;
14661 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14662 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14663 offscreen
= 0xdeadbeef;
14664 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14665 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14666 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14667 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14669 vp_data
.dwWidth
= 256;
14670 vp_data
.dwHeight
= 256;
14671 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14672 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14673 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14674 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14675 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14676 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %#lx.\n", offscreen
);
14678 /* Test the effect of Matrices.
14680 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
14681 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
14682 * the view matrix and the +1's from the world and projection matrix. */
14685 vp_data
.dwWidth
= 256;
14686 vp_data
.dwHeight
= 256;
14687 vp_data
.dvScaleX
= 5.0f
;
14688 vp_data
.dvScaleY
= 5.0f
;
14689 vp_data
.dvMinZ
= 0.0f
;
14690 vp_data
.dvMaxZ
= 1.0f
;
14691 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
14692 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14694 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
14695 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14696 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
14697 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14698 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
14699 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14701 transformdata
.lpIn
= position_tests
;
14702 transformdata
.dwInSize
= sizeof(position_tests
[0]);
14703 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14704 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14705 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14707 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14709 static const struct vec4 cmp
[] =
14711 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
14712 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
14715 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14716 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14717 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14720 /* Invalid flags. */
14721 offscreen
= 0xdeadbeef;
14722 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14723 &transformdata
, 0, &offscreen
);
14724 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14725 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
14727 /* NULL transform data. */
14728 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14729 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14730 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14731 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
14732 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
14733 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14734 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14735 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
14737 /* NULL transform data and NULL dwOffscreen.
14739 * Valid transform data + NULL dwOffscreen -> crash. */
14740 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14741 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
14742 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14745 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
14746 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14747 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14748 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14749 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
14750 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14751 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14752 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
14754 /* Invalid sizes. */
14755 offscreen
= 0xdeadbeef;
14756 transformdata
.dwSize
= sizeof(transformdata
) - 1;
14757 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14758 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14759 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14760 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
14761 transformdata
.dwSize
= sizeof(transformdata
) + 1;
14762 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
14763 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14764 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
14765 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
14767 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
14768 transformdata
.dwSize
= sizeof(transformdata
);
14769 transformdata
.lpIn
= NULL
;
14770 transformdata
.lpOut
= NULL
;
14771 offscreen
= 0xdeadbeef;
14772 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
14773 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14774 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14775 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
14777 /* Test how vertices are transformed during draws. */
14780 vp_data
.dwWidth
= 200;
14781 vp_data
.dwHeight
= 400;
14782 vp_data
.dvScaleX
= 20.0f
;
14783 vp_data
.dvScaleY
= 50.0f
;
14784 vp_data
.dvMinZ
= 0.0f
;
14785 vp_data
.dvMaxZ
= 1.0f
;
14786 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp_data
);
14787 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
14788 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14789 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#lx.\n", hr
);
14791 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
14792 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14794 hr
= IDirect3DDevice3_BeginScene(device
);
14795 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14796 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14798 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14799 hr
= IDirect3DDevice3_EndScene(device
);
14800 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14802 color
= get_surface_color(rt
, 128, 143);
14803 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14804 color
= get_surface_color(rt
, 132, 143);
14805 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14806 color
= get_surface_color(rt
, 128, 147);
14807 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14808 color
= get_surface_color(rt
, 132, 147);
14809 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14811 color
= get_surface_color(rt
, 177, 217);
14812 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14813 color
= get_surface_color(rt
, 181, 217);
14814 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14815 color
= get_surface_color(rt
, 177, 221);
14816 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14817 color
= get_surface_color(rt
, 181, 221);
14818 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
14820 /* Test D3DVIEWPORT2 behavior. */
14821 vp2_data
.dwSize
= sizeof(vp2_data
);
14824 vp2_data
.dwWidth
= 200;
14825 vp2_data
.dwHeight
= 400;
14826 vp2_data
.dvClipX
= -0.5f
;
14827 vp2_data
.dvClipY
= 4.0f
;
14828 vp2_data
.dvClipWidth
= 5.0f
;
14829 vp2_data
.dvClipHeight
= 10.0f
;
14830 vp2_data
.dvMinZ
= 0.0f
;
14831 vp2_data
.dvMaxZ
= 2.0f
;
14832 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
14833 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
14834 transformdata
.lpIn
= position_tests
;
14835 transformdata
.lpOut
= out
;
14836 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
14837 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
14838 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14839 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
14841 static const struct vec4 cmp
[] =
14843 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
14844 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
14847 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
14848 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
14849 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
14852 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
14853 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
14855 hr
= IDirect3DDevice3_BeginScene(device
);
14856 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
14857 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
14859 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
14860 hr
= IDirect3DDevice3_EndScene(device
);
14861 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
14863 color
= get_surface_color(rt
, 58, 118);
14864 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14865 color
= get_surface_color(rt
, 62, 118);
14866 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14867 color
= get_surface_color(rt
, 58, 122);
14868 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14869 color
= get_surface_color(rt
, 62, 122);
14870 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14872 color
= get_surface_color(rt
, 157, 177);
14873 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
14874 color
= get_surface_color(rt
, 161, 177);
14875 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14876 color
= get_surface_color(rt
, 157, 181);
14877 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14878 color
= get_surface_color(rt
, 161, 181);
14879 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
14881 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
14882 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14883 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
14884 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14885 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
14886 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
14888 vp2_data
.dwX
= 0.0;
14889 vp2_data
.dwY
= 0.0;
14890 vp2_data
.dwWidth
= 1;
14891 vp2_data
.dwHeight
= 1;
14892 vp2_data
.dvClipX
= -12.8f
;
14893 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
14894 vp2_data
.dvClipWidth
= 25.6f
;
14895 vp2_data
.dvClipHeight
= 25.6f
;
14896 vp2_data
.dvMinZ
= 0.0f
;
14897 vp2_data
.dvMaxZ
= 0.5f
;
14898 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
14899 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
14900 transformdata
.lpIn
= cliptest
;
14901 transformdata
.dwInSize
= sizeof(cliptest
[0]);
14902 offscreen
= 0xdeadbeef;
14903 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
14904 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
14905 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
14906 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
14907 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
14909 static const D3DHVERTEX cmp_h
[] =
14911 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
14912 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
14913 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
14914 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
14916 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
14917 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
14918 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
14919 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
14920 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
14921 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
14924 destroy_viewport(device
, viewport
);
14925 IDirectDrawSurface4_Release(rt
);
14926 refcount
= IDirect3DDevice3_Release(device
);
14927 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14928 DestroyWindow(window
);
14931 static void test_display_mode_surface_pixel_format(void)
14933 unsigned int width
, height
, bpp
;
14934 IDirectDrawSurface4
*surface
;
14935 DDSURFACEDESC2 surface_desc
;
14936 IDirectDraw4
*ddraw
;
14941 if (!(ddraw
= create_ddraw()))
14943 skip("Failed to create ddraw.\n");
14947 surface_desc
.dwSize
= sizeof(surface_desc
);
14948 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
14949 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
14950 width
= surface_desc
.dwWidth
;
14951 height
= surface_desc
.dwHeight
;
14953 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
14954 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
14955 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14956 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
14959 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
14961 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
14963 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
14965 ok(bpp
, "Set display mode failed.\n");
14967 surface_desc
.dwSize
= sizeof(surface_desc
);
14968 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
14969 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
14970 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
14971 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
14972 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
14973 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14975 memset(&surface_desc
, 0, sizeof(surface_desc
));
14976 surface_desc
.dwSize
= sizeof(surface_desc
);
14977 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
14978 U5(surface_desc
).dwBackBufferCount
= 1;
14979 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
14980 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14981 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
14982 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
14983 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
14984 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
14985 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
14986 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
14987 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
14988 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
14989 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
14990 IDirectDrawSurface4_Release(surface
);
14992 memset(&surface_desc
, 0, sizeof(surface_desc
));
14993 surface_desc
.dwSize
= sizeof(surface_desc
);
14994 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
14995 surface_desc
.dwWidth
= width
;
14996 surface_desc
.dwHeight
= height
;
14997 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14998 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14999 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
15000 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
15001 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
15002 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
15003 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
15004 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
15005 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
15006 IDirectDrawSurface4_Release(surface
);
15008 refcount
= IDirectDraw4_Release(ddraw
);
15009 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
15010 DestroyWindow(window
);
15013 static void test_surface_desc_size(void)
15018 DDSURFACEDESC desc1
;
15019 DDSURFACEDESC2 desc2
;
15022 IDirectDrawSurface4
*surface4
;
15023 IDirectDrawSurface3
*surface3
;
15024 IDirectDrawSurface
*surface
;
15025 DDSURFACEDESC2 surface_desc
;
15026 HRESULT expected_hr
, hr
;
15027 IDirectDraw4
*ddraw
;
15031 static const struct
15038 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
15039 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
15040 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
15042 static const unsigned int desc_sizes
[] =
15044 sizeof(DDSURFACEDESC
),
15045 sizeof(DDSURFACEDESC2
),
15046 sizeof(DDSURFACEDESC
) + 1,
15047 sizeof(DDSURFACEDESC2
) + 1,
15048 2 * sizeof(DDSURFACEDESC
),
15049 2 * sizeof(DDSURFACEDESC2
),
15050 sizeof(DDSURFACEDESC
) - 1,
15051 sizeof(DDSURFACEDESC2
) - 1,
15052 sizeof(DDSURFACEDESC
) / 2,
15053 sizeof(DDSURFACEDESC2
) / 2,
15058 sizeof(desc
) - 100,
15061 if (!(ddraw
= create_ddraw()))
15063 skip("Failed to create ddraw.\n");
15066 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
15067 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
15069 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
15071 memset(&surface_desc
, 0, sizeof(surface_desc
));
15072 surface_desc
.dwSize
= sizeof(surface_desc
);
15073 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
15074 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
15075 surface_desc
.dwHeight
= 128;
15076 surface_desc
.dwWidth
= 128;
15077 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
)))
15079 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
15082 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface
, (void **)&surface
);
15083 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
15084 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
15085 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
15087 /* GetSurfaceDesc() */
15088 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
15090 memset(&desc
, 0, sizeof(desc
));
15091 desc
.dwSize
= desc_sizes
[j
];
15092 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
15093 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
15094 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15095 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15097 memset(&desc
, 0, sizeof(desc
));
15098 desc
.dwSize
= desc_sizes
[j
];
15099 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
15100 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
15101 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15102 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15104 memset(&desc
, 0, sizeof(desc
));
15105 desc
.dwSize
= desc_sizes
[j
];
15106 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
15107 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface4
, &desc
.desc2
);
15108 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15109 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15113 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
15115 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
15116 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
15117 DWORD expected_texture_stage
;
15119 memset(&desc
, 0, sizeof(desc
));
15120 desc
.dwSize
= desc_sizes
[j
];
15121 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
15122 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
15123 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
15124 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
15125 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15126 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15127 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
15128 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
15129 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
15130 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
15133 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
15134 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
15135 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
15136 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
15137 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
15138 todo_wine_if(!expected_texture_stage
)
15139 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
15140 "Got unexpected texture stage %#lx, size %u, type %s.\n",
15141 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
15142 IDirectDrawSurface_Unlock(surface
, NULL
);
15145 memset(&desc
, 0, sizeof(desc
));
15146 desc
.dwSize
= desc_sizes
[j
];
15147 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
15148 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
15149 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
15150 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
15151 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15152 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15153 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
15154 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
15155 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
15156 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
15159 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
15160 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
15161 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
15162 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
15163 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
15164 todo_wine_if(!expected_texture_stage
)
15165 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
15166 "Got unexpected texture stage %#lx, size %u, type %s.\n",
15167 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
15168 IDirectDrawSurface3_Unlock(surface3
, NULL
);
15171 memset(&desc
, 0, sizeof(desc
));
15172 desc
.dwSize
= desc_sizes
[j
];
15173 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
15174 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
15175 hr
= IDirectDrawSurface4_Lock(surface4
, NULL
, &desc
.desc2
, 0, 0);
15176 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
15177 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
15178 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
15179 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
15180 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
15181 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
15182 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
15185 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
15186 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
15187 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
15188 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
15189 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
15190 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
15191 "Got unexpected texture stage %#lx, size %u, type %s.\n",
15192 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
15193 IDirectDrawSurface4_Unlock(surface4
, NULL
);
15197 IDirectDrawSurface4_Release(surface4
);
15198 IDirectDrawSurface3_Release(surface3
);
15199 IDirectDrawSurface_Release(surface
);
15202 /* GetDisplayMode() */
15203 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
15205 memset(&desc
, 0xcc, sizeof(desc
));
15206 desc
.dwSize
= desc_sizes
[j
];
15207 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
15208 ? DD_OK
: DDERR_INVALIDPARAMS
;
15209 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &desc
.desc2
);
15210 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
15213 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %lu for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
15214 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
15215 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
15219 refcount
= IDirectDraw4_Release(ddraw
);
15220 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
15223 static void test_get_surface_from_dc(void)
15225 IDirectDrawSurface
*surface1
, *tmp
;
15226 IDirectDrawSurface4
*surface
;
15227 DDSURFACEDESC2 surface_desc
;
15228 IDirectDraw4
*ddraw
;
15235 window
= create_window();
15236 ddraw
= create_ddraw();
15237 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15238 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15239 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
15241 memset(&surface_desc
, 0, sizeof(surface_desc
));
15242 surface_desc
.dwSize
= sizeof(surface_desc
);
15243 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15244 surface_desc
.dwWidth
= 64;
15245 surface_desc
.dwHeight
= 64;
15246 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
15248 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15249 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
15250 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
15251 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
15253 refcount
= get_refcount((IUnknown
*)surface1
);
15254 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15255 refcount
= get_refcount((IUnknown
*)surface
);
15256 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15258 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
15259 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
15261 tmp
= (void *)0xdeadbeef;
15262 device_dc
= (void *)0xdeadbeef;
15263 hr
= GetSurfaceFromDC(NULL
, &tmp
, &device_dc
);
15264 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
15265 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
15266 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
15268 device_dc
= (void *)0xdeadbeef;
15269 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
15270 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
15271 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
15273 tmp
= (void *)0xdeadbeef;
15274 hr
= GetSurfaceFromDC(dc
, &tmp
, NULL
);
15275 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
15276 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
15278 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
15279 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#lx.\n", hr
);
15280 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
15281 IDirectDrawSurface_Release(tmp
);
15283 ret
= GetObjectType(device_dc
);
15284 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#lx.\n", ret
);
15285 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
15286 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#lx.\n", ret
);
15288 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, NULL
);
15289 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
15291 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
15292 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#lx.\n", hr
);
15293 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
15295 refcount
= get_refcount((IUnknown
*)surface1
);
15296 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
15297 refcount
= get_refcount((IUnknown
*)surface
);
15298 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
15300 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
15301 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#lx.\n", hr
);
15303 IDirectDrawSurface_Release(tmp
);
15305 dc
= CreateCompatibleDC(NULL
);
15306 ok(!!dc
, "CreateCompatibleDC failed.\n");
15308 tmp
= (void *)0xdeadbeef;
15309 device_dc
= (void *)0xdeadbeef;
15310 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
15311 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
15312 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
15313 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
15315 tmp
= (void *)0xdeadbeef;
15316 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
15317 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
15318 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
15320 ok(DeleteDC(dc
), "DeleteDC failed.\n");
15322 tmp
= (void *)0xdeadbeef;
15323 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, NULL
, (IDirectDrawSurface4
**)&tmp
);
15324 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
15325 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
15327 IDirectDrawSurface4_Release(surface
);
15328 IDirectDrawSurface_Release(surface1
);
15329 IDirectDraw4_Release(ddraw
);
15330 DestroyWindow(window
);
15333 static void test_ck_operation(void)
15335 IDirectDrawSurface4
*src
, *dst
;
15336 IDirectDrawSurface
*src1
, *dst1
;
15337 DDSURFACEDESC2 surface_desc
;
15338 unsigned int i
, *color
;
15339 IDirectDraw4
*ddraw
;
15346 window
= create_window();
15347 ddraw
= create_ddraw();
15348 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15349 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15350 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
15352 memset(&surface_desc
, 0, sizeof(surface_desc
));
15353 surface_desc
.dwSize
= sizeof(surface_desc
);
15354 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
15355 surface_desc
.dwWidth
= 4;
15356 surface_desc
.dwHeight
= 1;
15357 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
15358 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
15359 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
15360 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
15361 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
15362 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
15363 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
15364 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
15366 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
15367 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
15368 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
15369 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
15370 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
15372 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15373 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15374 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
15375 color
= surface_desc
.lpSurface
;
15376 color
[0] = 0x77010203;
15377 color
[1] = 0x00010203;
15378 color
[2] = 0x77ff00ff;
15379 color
[3] = 0x00ff00ff;
15380 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
15381 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15383 for (i
= 0; i
< 2; ++i
)
15385 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15386 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15387 color
= surface_desc
.lpSurface
;
15388 color
[0] = 0xcccccccc;
15389 color
[1] = 0xcccccccc;
15390 color
[2] = 0xcccccccc;
15391 color
[3] = 0xcccccccc;
15392 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15393 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15397 hr
= IDirectDrawSurface4_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
15398 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15402 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
15403 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15406 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
15407 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15408 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
15409 color
= surface_desc
.lpSurface
;
15410 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
15411 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
15412 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
15413 * color keying nor copies it. */
15414 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
15415 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
15416 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
15417 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
15418 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
15419 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
15420 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
15421 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
15422 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
15423 color
[0], color
[1], color
[2], color
[3], i
);
15424 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15425 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15428 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15429 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
15430 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
15431 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
15433 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
15434 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15435 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15437 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
15438 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15439 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
15440 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
15441 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
15443 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
15444 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
15445 hr
= IDirectDrawSurface4_GetSurfaceDesc(src
, &surface_desc
);
15446 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
15447 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
15448 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
15449 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
15450 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
15452 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
15453 ckey
.dwColorSpaceLowValue
= 0x000000ff;
15454 ckey
.dwColorSpaceHighValue
= 0x00000000;
15455 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15456 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15458 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
15459 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15460 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
15461 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
15462 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
15464 ckey
.dwColorSpaceLowValue
= 0x000000ff;
15465 ckey
.dwColorSpaceHighValue
= 0x00000001;
15466 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15467 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15469 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
15470 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15471 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
15472 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
15473 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
15475 ckey
.dwColorSpaceLowValue
= 0x000000fe;
15476 ckey
.dwColorSpaceHighValue
= 0x000000fd;
15477 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15478 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15480 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
15481 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15482 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
15483 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
15484 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
15486 IDirectDrawSurface4_Release(src
);
15487 IDirectDrawSurface4_Release(dst
);
15489 /* Test source and destination keys and where they are read from. Use a surface with alpha
15490 * to avoid driver-dependent content in the X channel. */
15491 memset(&surface_desc
, 0, sizeof(surface_desc
));
15492 surface_desc
.dwSize
= sizeof(surface_desc
);
15493 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
15494 surface_desc
.dwWidth
= 6;
15495 surface_desc
.dwHeight
= 1;
15496 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
15497 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
15498 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
15499 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
15500 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
15501 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
15502 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
15503 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
15504 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
15505 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
15506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
15508 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
15509 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
15510 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
15511 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15512 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
15513 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
15514 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
15515 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#lx.\n", hr
);
15518 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
15519 skip("Failed to set destination color key, skipping related tests.\n");
15523 ckey
.dwColorSpaceLowValue
= 0x000000ff;
15524 ckey
.dwColorSpaceHighValue
= 0x000000ff;
15525 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
15526 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15527 ckey
.dwColorSpaceLowValue
= 0x000000aa;
15528 ckey
.dwColorSpaceHighValue
= 0x000000aa;
15529 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
15530 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15532 memset(&fx
, 0, sizeof(fx
));
15533 fx
.dwSize
= sizeof(fx
);
15534 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
15535 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
15536 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
15537 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
15539 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15540 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15541 color
= surface_desc
.lpSurface
;
15542 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
15543 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
15544 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
15545 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
15546 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
15547 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
15548 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
15549 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15551 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15552 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15553 color
= surface_desc
.lpSurface
;
15554 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
15555 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15556 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15558 /* Test a blit without keying. */
15559 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
15560 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15562 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15563 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15564 color
= surface_desc
.lpSurface
;
15565 /* Should have copied src data unmodified to dst. */
15566 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
15567 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
15568 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15569 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15571 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
15572 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15573 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15576 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
15577 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15579 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15580 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15581 color
= surface_desc
.lpSurface
;
15582 /* Src key applied to color[0]. It is unmodified, the others are copied. */
15583 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
15584 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
15585 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15586 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15588 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
15589 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15590 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15592 /* Src override. */
15593 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
15594 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15596 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15597 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15598 color
= surface_desc
.lpSurface
;
15599 /* Override key applied to color[5]. It is unmodified, the others are copied. */
15600 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
15601 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
15602 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15603 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15605 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
15606 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15607 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15609 /* Src override AND src key. That is not supposed to work. */
15610 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
15611 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15613 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15614 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15615 color
= surface_desc
.lpSurface
;
15616 /* Ensure the destination was not changed. */
15617 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
15618 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
15619 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15620 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15622 /* Use different dst colors for the dst key test. */
15623 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15624 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15625 color
[2] = 0x00001100; /* Dest key in override. */
15626 color
[3] = 0x00001100; /* Dest key in override. */
15627 color
[4] = 0x000000aa; /* Dest key in src surface. */
15628 color
[5] = 0x000000aa; /* Dest key in src surface. */
15629 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15630 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15632 /* Dest key blit. The key is taken from the DESTINATION surface in v4! */
15633 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
15634 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15636 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15637 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15638 color
= surface_desc
.lpSurface
;
15639 /* Dst key applied to color[0,1], they are the only changed pixels. */
15640 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
15641 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
15642 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15643 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15645 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15646 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15647 color
[2] = 0x00001100; /* Dest key in override. */
15648 color
[3] = 0x00001100; /* Dest key in override. */
15649 color
[4] = 0x000000aa; /* Dest key in src surface. */
15650 color
[5] = 0x000000aa; /* Dest key in src surface. */
15651 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15652 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15654 /* What happens with a QI'd older version of the interface? It takes the key
15655 * from the source surface. */
15656 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
15657 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
15658 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
15659 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
15661 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
15662 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15664 IDirectDrawSurface_Release(dst1
);
15665 IDirectDrawSurface_Release(src1
);
15667 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15668 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15669 color
= surface_desc
.lpSurface
;
15670 /* Dst key applied to color[4,5], they are the only changed pixels. */
15671 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
15672 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
15673 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15674 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15676 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15677 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15678 color
[2] = 0x00001100; /* Dest key in override. */
15679 color
[3] = 0x00001100; /* Dest key in override. */
15680 color
[4] = 0x000000aa; /* Dest key in src surface. */
15681 color
[5] = 0x000000aa; /* Dest key in src surface. */
15682 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
15683 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15685 /* Dest override key blit. */
15686 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
15687 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15689 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15690 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15691 color
= surface_desc
.lpSurface
;
15692 /* Dst key applied to color[2,3], they are the only changed pixels. */
15693 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
15694 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
15695 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15696 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15698 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15699 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15700 color
[2] = 0x00001100; /* Dest key in override. */
15701 color
[3] = 0x00001100; /* Dest key in override. */
15702 color
[4] = 0x000000aa; /* Dest key in src surface. */
15703 color
[5] = 0x000000aa; /* Dest key in src surface. */
15704 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15705 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15707 /* Dest override together with surface key. Supposed to fail. */
15708 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
15709 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15711 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15712 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15713 color
= surface_desc
.lpSurface
;
15714 /* Destination is unchanged. */
15715 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
15716 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
15717 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15718 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15719 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15720 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15722 /* Source and destination key. This is driver dependent. New HW treats it like
15723 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
15726 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
15727 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15729 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15730 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15731 color
= surface_desc
.lpSurface
;
15732 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
15733 * the driver applies it. */
15734 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
15735 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
15736 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15737 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15739 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
15740 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
15741 color
[2] = 0x00001100; /* Dest key in override. */
15742 color
[3] = 0x00001100; /* Dest key in override. */
15743 color
[4] = 0x000000aa; /* Dest key in src surface. */
15744 color
[5] = 0x000000aa; /* Dest key in src surface. */
15745 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15746 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15749 /* Override keys without ddbltfx parameter fail */
15750 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
15751 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15752 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
15753 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15755 /* Try blitting without keys in the source surface. */
15756 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
15757 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15758 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
15759 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15761 /* That fails now. Do not bother to check that the data is unmodified. */
15762 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
15763 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15765 /* Dest key blit still works, the destination surface key is used in v4. */
15766 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
15767 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
15769 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15770 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
15771 color
= surface_desc
.lpSurface
;
15772 /* Dst key applied to color[0,1], they are the only changed pixels. */
15773 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
15774 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
15775 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
15776 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
15777 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
15778 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
15780 /* Try blitting without keys in the destination surface. */
15781 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
15782 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15783 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
15784 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
15786 /* This fails, as sanity would dictate. */
15787 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
15788 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
15791 IDirectDrawSurface4_Release(src
);
15792 IDirectDrawSurface4_Release(dst
);
15793 refcount
= IDirectDraw4_Release(ddraw
);
15794 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
15795 DestroyWindow(window
);
15798 static void test_vb_refcount(void)
15800 ULONG prev_d3d_refcount
, prev_device_refcount
;
15801 ULONG cur_d3d_refcount
, cur_device_refcount
;
15802 IDirect3DVertexBuffer
*vb
, *vb1
;
15803 IDirect3DVertexBuffer7
*vb7
;
15804 D3DVERTEXBUFFERDESC vb_desc
;
15805 IDirect3DDevice3
*device
;
15812 window
= create_window();
15813 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15815 skip("Failed to create a 3D device, skipping test.\n");
15816 DestroyWindow(window
);
15820 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15821 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
15823 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
15824 prev_device_refcount
= get_refcount((IUnknown
*)device
);
15826 memset(&vb_desc
, 0, sizeof(vb_desc
));
15827 vb_desc
.dwSize
= sizeof(vb_desc
);
15828 vb_desc
.dwFVF
= D3DFVF_XYZ
;
15829 vb_desc
.dwNumVertices
= 4;
15830 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
15831 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
15833 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
15834 cur_device_refcount
= get_refcount((IUnknown
*)device
);
15835 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %lu to %lu.\n",
15836 prev_d3d_refcount
, cur_d3d_refcount
);
15837 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %lu to %lu.\n",
15838 prev_device_refcount
, cur_device_refcount
);
15840 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
15841 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer, hr %#lx.\n", hr
);
15842 IDirect3DVertexBuffer_Release(vb1
);
15844 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
15845 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer7 returned unexpected hr %#lx.\n", hr
);
15847 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
15848 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#lx.\n", hr
);
15849 ok((IUnknown
*)vb
== unk
,
15850 "IDirect3DVertexBuffer and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
15851 IUnknown_Release(unk
);
15853 refcount
= IDirect3DVertexBuffer_Release(vb
);
15854 ok(!refcount
, "Vertex buffer has %lu references left.\n", refcount
);
15855 IDirect3D3_Release(d3d
);
15856 refcount
= IDirect3DDevice3_Release(device
);
15857 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15858 DestroyWindow(window
);
15861 static void test_compute_sphere_visibility(void)
15863 static D3DMATRIX proj_1
=
15865 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
15866 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
15867 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
15868 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
15870 static D3DMATRIX proj_2
=
15872 10.0f
, 0.0f
, 0.0f
, 0.0f
,
15873 0.0f
, 10.0f
, 0.0f
, 0.0f
,
15874 0.0f
, 0.0f
, 10.0f
, 0.0f
,
15875 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15877 static D3DMATRIX view_1
=
15879 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
15880 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
15881 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
15882 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
15884 static D3DMATRIX identity
=
15886 1.0f
, 0.0f
, 0.0f
, 0.0f
,
15887 0.0f
, 1.0f
, 0.0f
, 0.0f
,
15888 0.0f
, 0.0f
, 1.0f
, 0.0f
,
15889 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15893 D3DMATRIX
*view
, *proj
;
15894 unsigned int sphere_count
;
15895 D3DVECTOR center
[3];
15896 D3DVALUE radius
[3];
15897 const DWORD expected
[3];
15902 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, {0x1555}},
15903 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
15904 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
15905 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
15906 {4.354097f
, 12.500704f
, 17.251318f
}, {0x154a, 0x1555, 0x1555}},
15907 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, {0x1555}, TRUE
},
15908 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, {0x1401}},
15909 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, {0x401}},
15910 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, {0x1505}, TRUE
}, /* 5 */
15911 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x154a}},
15912 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x1562}},
15913 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, {0x1616}},
15914 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, {0x1496}},
15915 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, {0x956}}, /* 10 */
15916 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, {0x2156}},
15918 IDirect3DViewport3
*viewport
;
15919 IDirect3DDevice3
*device
;
15926 window
= create_window();
15927 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15929 skip("Failed to create a 3D device, skipping test.\n");
15930 DestroyWindow(window
);
15934 viewport
= create_viewport(device
, 0, 0, 640, 480);
15935 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15936 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
15938 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
15940 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15942 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
15943 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
15945 hr
= IDirect3DDevice3_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
15946 tests
[i
].sphere_count
, 0, result
);
15947 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15949 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
15950 todo_wine_if(tests
[i
].todo
)
15951 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#lx, got %#lx.\n",
15952 i
, j
, tests
[i
].expected
[j
], result
[j
]);
15955 destroy_viewport(device
, viewport
);
15956 refcount
= IDirect3DDevice3_Release(device
);
15957 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15958 DestroyWindow(window
);
15961 static void test_texture_stages_limits(void)
15963 IDirectDrawSurface4
*surface
;
15964 DDSURFACEDESC2 surface_desc
;
15965 IDirect3DTexture2
*texture
;
15966 IDirect3DDevice3
*device
;
15967 IDirectDraw4
*ddraw
;
15974 window
= create_window();
15975 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15977 skip("Failed to create 3D device.\n");
15978 DestroyWindow(window
);
15981 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15982 ok(SUCCEEDED(hr
), "Failed to get Direct3D interface, hr %#lx.\n", hr
);
15983 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
15984 ok(SUCCEEDED(hr
), "Failed to get DirectDraw interface, hr %#lx.\n", hr
);
15985 IDirect3D3_Release(d3d
);
15987 memset(&surface_desc
, 0, sizeof(surface_desc
));
15988 surface_desc
.dwSize
= sizeof(surface_desc
);
15989 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15990 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
15991 surface_desc
.dwWidth
= 16;
15992 surface_desc
.dwHeight
= 16;
15993 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15994 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
15995 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
15996 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
15997 IDirectDrawSurface4_Release(surface
);
15999 for (i
= 0; i
< 8; ++i
)
16001 hr
= IDirect3DDevice3_SetTexture(device
, i
, texture
);
16002 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#lx.\n", i
, hr
);
16003 hr
= IDirect3DDevice3_SetTexture(device
, i
, NULL
);
16004 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#lx.\n", i
, hr
);
16005 hr
= IDirect3DDevice3_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
16006 ok(hr
== D3D_OK
, "Failed to set texture stage state %u, hr %#lx.\n", i
, hr
);
16009 IDirectDraw4_Release(ddraw
);
16010 IDirect3DTexture2_Release(texture
);
16011 refcount
= IDirect3DDevice3_Release(device
);
16012 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16013 DestroyWindow(window
);
16016 static void test_set_render_state(void)
16018 IDirect3DDevice3
*device
;
16024 window
= create_window();
16025 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16027 skip("Failed to create 3D device.\n");
16028 DestroyWindow(window
);
16032 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
16033 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16034 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
16035 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16037 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
16038 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16039 state
= 0xdeadbeef;
16040 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
16041 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16042 ok(!state
, "Got unexpected render state %#lx.\n", state
);
16043 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
16044 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16045 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
16046 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
16047 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#lx.\n", state
);
16049 refcount
= IDirect3DDevice3_Release(device
);
16050 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16051 DestroyWindow(window
);
16054 static void test_map_synchronisation(void)
16056 LARGE_INTEGER frequency
, diff
, ts
[3];
16057 unsigned int i
, j
, tri_count
, colour
;
16058 IDirect3DVertexBuffer
*buffer
;
16059 IDirect3DViewport3
*viewport
;
16060 D3DVERTEXBUFFERDESC vb_desc
;
16061 IDirect3DDevice3
*device
;
16062 BOOL unsynchronised
, ret
;
16063 IDirectDrawSurface4
*rt
;
16069 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
16071 /* DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE were introduced with
16072 * ddraw7 and are ignored in earlier versions. */
16073 static const struct
16075 unsigned int flags
;
16076 BOOL unsynchronised
;
16081 {DDLOCK_NOOVERWRITE
, FALSE
},
16082 {DDLOCK_DISCARDCONTENTS
, FALSE
},
16083 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, FALSE
},
16086 static const struct quad
16090 struct vec3 position
;
16097 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
16098 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
16099 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
16100 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
16106 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
16107 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
16108 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
16109 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
16112 struct quad
*quads
;
16114 window
= create_window();
16115 ok(!!window
, "Failed to create a window.\n");
16117 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16119 skip("Failed to create a D3D device, skipping tests.\n");
16120 DestroyWindow(window
);
16124 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
16125 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
16127 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
16128 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
16129 viewport
= create_viewport(device
, 0, 0, 640, 480);
16130 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16131 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16133 tri_count
= 0x1000;
16135 ret
= QueryPerformanceFrequency(&frequency
);
16136 ok(ret
, "Failed to get performance counter frequency.\n");
16138 vb_desc
.dwSize
= sizeof(vb_desc
);
16139 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
16140 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
16141 vb_desc
.dwNumVertices
= tri_count
+ 2;
16142 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
16143 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
16144 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
16145 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
16146 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
16150 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
16151 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
16153 /* Initial draw to initialise states, compile shaders, etc. */
16154 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16155 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16156 hr
= IDirect3DDevice3_BeginScene(device
);
16157 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
16158 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
16159 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
16160 hr
= IDirect3DDevice3_EndScene(device
);
16161 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
16162 /* Read the result to ensure the GPU has finished drawing. */
16163 colour
= get_surface_color(rt
, 320, 240);
16165 /* Time drawing tri_count triangles. */
16166 ret
= QueryPerformanceCounter(&ts
[0]);
16167 ok(ret
, "Failed to read performance counter.\n");
16168 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16169 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16170 hr
= IDirect3DDevice3_BeginScene(device
);
16171 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
16172 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
16173 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
16174 hr
= IDirect3DDevice3_EndScene(device
);
16175 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
16176 colour
= get_surface_color(rt
, 320, 240);
16177 /* Time drawing a single triangle. */
16178 ret
= QueryPerformanceCounter(&ts
[1]);
16179 ok(ret
, "Failed to read performance counter.\n");
16180 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16181 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16182 hr
= IDirect3DDevice3_BeginScene(device
);
16183 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
16184 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
16185 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
16186 hr
= IDirect3DDevice3_EndScene(device
);
16187 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
16188 colour
= get_surface_color(rt
, 320, 240);
16189 ret
= QueryPerformanceCounter(&ts
[2]);
16190 ok(ret
, "Failed to read performance counter.\n");
16192 IDirect3DVertexBuffer_Release(buffer
);
16194 /* Estimate the number of triangles we can draw in 100ms. */
16195 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
16196 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
16197 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
16198 vb_desc
.dwNumVertices
= tri_count
+ 2;
16200 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16202 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
16203 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
16204 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
16205 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
16206 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
16210 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
16211 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
16213 /* Start a draw operation. */
16214 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16215 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16216 hr
= IDirect3DDevice3_BeginScene(device
);
16217 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
16218 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
16219 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
16220 hr
= IDirect3DDevice3_EndScene(device
);
16221 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
16223 /* Map the last quad while the draw is in progress. */
16224 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
16225 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
16226 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
16227 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
16228 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
16230 colour
= get_surface_color(rt
, 320, 240);
16231 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
16232 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
16233 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
16235 IDirect3DVertexBuffer_Release(buffer
);
16238 destroy_viewport(device
, viewport
);
16239 IDirectDrawSurface4_Release(rt
);
16240 IDirect3D3_Release(d3d
);
16241 refcount
= IDirect3DDevice3_Release(device
);
16242 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16243 DestroyWindow(window
);
16246 static void test_depth_readback(void)
16248 unsigned int depth
, expected_depth
, i
, x
, y
, max_diff
, passed_fmts
= 0;
16249 IDirectDrawSurface4
*rt
, *ds
;
16250 IDirect3DViewport3
*viewport
;
16251 DDSURFACEDESC2 surface_desc
;
16252 IDirect3DDevice3
*device
;
16253 IDirectDraw4
*ddraw
;
16261 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
16264 struct vec3 position
;
16269 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
16270 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
16271 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
16272 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
16275 static const struct
16277 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
16282 {16, 0, 0x0000ffff, 0x00000000},
16283 {24, 0, 0x00ffffff, 0x00000000},
16284 {32, 0, 0x00ffffff, 0x00000000},
16285 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
16286 {32, 0, 0xffffffff, 0x00000000},
16289 window
= create_window();
16290 ok(!!window
, "Failed to create a window.\n");
16292 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16294 skip("Failed to create a D3D device, skipping tests.\n");
16295 DestroyWindow(window
);
16299 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
16300 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
16301 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
16302 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
16304 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
16305 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
16306 viewport
= create_viewport(device
, 0, 0, 640, 480);
16307 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16308 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16310 ds
= get_depth_stencil(device
);
16311 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
16312 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
16313 IDirectDrawSurface4_Release(ds
);
16315 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
16317 memset(&surface_desc
, 0, sizeof(surface_desc
));
16318 surface_desc
.dwSize
= sizeof(surface_desc
);
16319 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
16320 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
16321 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16322 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
16323 if (tests
[i
].s_depth
)
16324 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
16325 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
16326 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
16327 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
16328 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
16329 surface_desc
.dwWidth
= 640;
16330 surface_desc
.dwHeight
= 480;
16331 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
16334 skip("Format %u not supported, skipping test.\n", i
);
16338 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
16339 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
16340 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
16341 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
16343 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
16344 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
16345 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16346 hr
= IDirect3DDevice3_BeginScene(device
);
16347 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
16348 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
16349 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
16350 hr
= IDirect3DDevice3_EndScene(device
);
16351 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
16354 for (y
= 60; y
< 480; y
+= 120)
16356 for (x
= 80; x
< 640; x
+= 160)
16358 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
16359 memset(&surface_desc
, 0, sizeof(surface_desc
));
16360 surface_desc
.dwSize
= sizeof(surface_desc
);
16361 hr
= IDirectDrawSurface4_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
16362 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
16364 depth
= *((DWORD
*)surface_desc
.lpSurface
) & tests
[i
].z_mask
;
16365 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
16366 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
16367 /* The ddraw4 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
16368 * except that Geforce 7 also returns garbage data in D24S8, whereas the ddraw7 version
16369 * returns 0 for that format. Give up on pre-filtering formats, accept Nvidia as generally
16370 * broken here, but still expect at least one format (D16 or D24X8 in practise) to pass.
16372 * Some of the tested places pass on some GPUs on Wine by accident. */
16373 todo_wine_if(tests
[i
].todo
&& !compare_uint(expected_depth
, depth
, max_diff
))
16374 ok(compare_uint(expected_depth
, depth
, max_diff
) || ddraw_is_nvidia(ddraw
)
16375 || (ddraw_is_amd(ddraw
) && !tests
[i
].s_depth
&& tests
[i
].z_mask
== 0x00ffffff),
16376 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
16377 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
16378 if (!compare_uint(expected_depth
, depth
, max_diff
))
16381 hr
= IDirectDrawSurface4_Unlock(ds
, &r
);
16382 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
16389 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
16390 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#lx.\n", hr
);
16391 IDirectDrawSurface4_Release(ds
);
16394 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
16396 destroy_viewport(device
, viewport
);
16397 IDirectDrawSurface4_Release(rt
);
16398 IDirectDraw4_Release(ddraw
);
16399 IDirect3D3_Release(d3d
);
16400 refcount
= IDirect3DDevice3_Release(device
);
16401 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16402 DestroyWindow(window
);
16405 static void test_clear(void)
16407 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
16408 IDirect3DViewport3
*viewport
, *viewport2
, *viewport3
;
16409 IDirect3DDevice3
*device
;
16410 IDirectDrawSurface4
*rt
;
16411 IDirectDraw4
*ddraw
;
16412 unsigned int color
;
16419 window
= create_window();
16420 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16422 skip("Failed to create 3D device.\n");
16423 DestroyWindow(window
);
16427 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
16428 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
16429 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
16430 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
16432 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
16433 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
16435 viewport
= create_viewport(device
, 0, 0, 640, 480);
16436 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16437 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16439 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
16440 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16442 /* Positive x, negative y. */
16443 U1(rect
[0]).x1
= 0;
16444 U2(rect
[0]).y1
= 480;
16445 U3(rect
[0]).x2
= 320;
16446 U4(rect
[0]).y2
= 240;
16448 /* Positive x, positive y. */
16449 U1(rect
[1]).x1
= 0;
16450 U2(rect
[1]).y1
= 0;
16451 U3(rect
[1]).x2
= 320;
16452 U4(rect
[1]).y2
= 240;
16454 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
16455 * refuse negative rectangles, but it will not clear them either. */
16456 hr
= IDirect3DViewport3_Clear2(viewport
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
16457 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16459 color
= get_surface_color(rt
, 160, 360);
16460 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
16461 color
= get_surface_color(rt
, 160, 120);
16462 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
16463 color
= get_surface_color(rt
, 480, 360);
16464 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
16465 color
= get_surface_color(rt
, 480, 120);
16466 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
16468 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
16469 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16470 /* negative x, negative y.
16471 * Also ignored, except on WARP, which clears the entire screen. */
16472 U1(rect_negneg
).x1
= 640;
16473 U2(rect_negneg
).y1
= 240;
16474 U3(rect_negneg
).x2
= 320;
16475 U4(rect_negneg
).y2
= 0;
16476 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
16477 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16479 color
= get_surface_color(rt
, 160, 360);
16480 ok(compare_color(color
, 0x00ffffff, 0)
16481 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
16482 "Got unexpected color 0x%08x.\n", color
);
16483 color
= get_surface_color(rt
, 160, 120);
16484 ok(compare_color(color
, 0x00ffffff, 0)
16485 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
16486 "Got unexpected color 0x%08x.\n", color
);
16487 color
= get_surface_color(rt
, 480, 360);
16488 ok(compare_color(color
, 0x00ffffff, 0)
16489 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
16490 "Got unexpected color 0x%08x.\n", color
);
16491 color
= get_surface_color(rt
, 480, 120);
16492 ok(compare_color(color
, 0x00ffffff, 0)
16493 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
16494 "Got unexpected color 0x%08x.\n", color
);
16496 /* Test how the viewport affects clears. */
16497 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
16498 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16500 viewport2
= create_viewport(device
, 160, 120, 160, 120);
16501 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport2
);
16502 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16504 hr
= IDirect3DViewport3_Clear2(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16505 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16507 viewport3
= create_viewport(device
, 320, 240, 320, 240);
16508 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
16509 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16511 U1(rect
[0]).x1
= 160;
16512 U2(rect
[0]).y1
= 120;
16513 U3(rect
[0]).x2
= 480;
16514 U4(rect
[0]).y2
= 360;
16515 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
16516 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16518 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16519 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#lx.\n", hr
);
16521 color
= get_surface_color(rt
, 158, 118);
16522 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
16523 color
= get_surface_color(rt
, 162, 118);
16524 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
16525 color
= get_surface_color(rt
, 158, 122);
16526 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
16527 color
= get_surface_color(rt
, 162, 122);
16528 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
16530 color
= get_surface_color(rt
, 318, 238);
16531 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
16532 color
= get_surface_color(rt
, 322, 238);
16533 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
16534 color
= get_surface_color(rt
, 318, 242);
16535 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
16536 color
= get_surface_color(rt
, 322, 242);
16537 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
16539 color
= get_surface_color(rt
, 478, 358);
16540 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
16541 color
= get_surface_color(rt
, 482, 358);
16542 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
16543 color
= get_surface_color(rt
, 478, 362);
16544 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
16545 color
= get_surface_color(rt
, 482, 362);
16546 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
16548 /* The clear rectangle is rendertarget absolute, not relative to the
16550 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
16551 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16552 U1(rect
[0]).x1
= 330;
16553 U2(rect
[0]).y1
= 250;
16554 U3(rect
[0]).x2
= 340;
16555 U4(rect
[0]).y2
= 260;
16556 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
16557 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
16559 color
= get_surface_color(rt
, 328, 248);
16560 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
16561 color
= get_surface_color(rt
, 332, 248);
16562 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
16563 color
= get_surface_color(rt
, 328, 252);
16564 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
16565 color
= get_surface_color(rt
, 332, 252);
16566 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
16568 color
= get_surface_color(rt
, 338, 248);
16569 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
16570 color
= get_surface_color(rt
, 342, 248);
16571 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
16572 color
= get_surface_color(rt
, 338, 252);
16573 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
16574 color
= get_surface_color(rt
, 342, 252);
16575 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
16577 color
= get_surface_color(rt
, 328, 258);
16578 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
16579 color
= get_surface_color(rt
, 332, 258);
16580 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
16581 color
= get_surface_color(rt
, 328, 262);
16582 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
16583 color
= get_surface_color(rt
, 332, 262);
16584 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
16586 color
= get_surface_color(rt
, 338, 258);
16587 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
16588 color
= get_surface_color(rt
, 342, 258);
16589 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
16590 color
= get_surface_color(rt
, 338, 262);
16591 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
16592 color
= get_surface_color(rt
, 342, 262);
16593 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
16595 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
16598 IDirect3DViewport3_Release(viewport3
);
16599 IDirect3DViewport3_Release(viewport2
);
16600 IDirect3DViewport3_Release(viewport
);
16601 IDirectDrawSurface4_Release(rt
);
16602 IDirectDraw4_Release(ddraw
);
16603 IDirect3D3_Release(d3d
);
16604 refcount
= IDirect3DDevice3_Release(device
);
16605 ok(!refcount
, "Device has %lu references left.\n", refcount
);
16606 DestroyWindow(window
);
16609 struct enum_surfaces_param
16611 IDirectDraw4
*ddraw
;
16612 DDSURFACEDESC2 modes
[20];
16613 unsigned int mode_count
;
16615 IDirectDrawSurface4
*surfaces
[8];
16616 unsigned int count
;
16619 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC2
*desc
, void *context
)
16621 struct enum_surfaces_param
*param
= context
;
16622 IDirectDrawSurface4
*surface
;
16624 if (SUCCEEDED(IDirectDraw4_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
16626 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
16627 param
->modes
[param
->mode_count
] = *desc
;
16628 ++param
->mode_count
;
16629 IDirectDrawSurface4_Release(surface
);
16632 return DDENUMRET_OK
;
16635 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
16637 struct enum_surfaces_param
*param
= context
;
16638 BOOL found
= FALSE
;
16641 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
16643 if (param
->surfaces
[i
] == surface
)
16650 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
16651 IDirectDrawSurface4_Release(surface
);
16654 return DDENUMRET_OK
;
16657 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
16659 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
16660 struct enum_surfaces_param
*param
= context
;
16662 ok(!surface
, "Unexpected surface %p.\n", surface
);
16663 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#lx.\n", desc
->dwFlags
);
16664 if (param
->count
< ARRAY_SIZE(param
->modes
))
16666 const DDSURFACEDESC2
*expect
= ¶m
->modes
[param
->count
];
16667 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %lu, got %lu.\n", expect
->dwWidth
, desc
->dwWidth
);
16668 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %lu, got %lu.\n", expect
->dwHeight
, desc
->dwHeight
);
16669 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
16670 "Pixel formats didn't match.\n");
16675 return DDENUMRET_OK
;
16678 static void test_enum_surfaces(void)
16680 struct enum_surfaces_param param
= {0};
16681 DDPIXELFORMAT current_format
;
16682 DDSURFACEDESC2 desc
;
16683 IDirectDraw4
*ddraw
;
16686 ddraw
= create_ddraw();
16687 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16688 param
.ddraw
= ddraw
;
16690 memset(&desc
, 0, sizeof(desc
));
16691 desc
.dwSize
= sizeof(desc
);
16692 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &desc
);
16693 ok(hr
== DD_OK
, "Failed to get display mode, hr %#lx.\n", hr
);
16694 current_format
= U4(desc
).ddpfPixelFormat
;
16696 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
16697 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#lx.\n", hr
);
16699 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
16700 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
16702 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
16703 NULL
, NULL
, enum_surfaces_cb
);
16704 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
16706 memset(&desc
, 0, sizeof(desc
));
16707 desc
.dwSize
= sizeof(desc
);
16708 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
16709 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
16710 U2(desc
).dwMipMapCount
= 3;
16712 desc
.dwHeight
= 32;
16713 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
16714 ok(hr
== DD_OK
, "Failed to create a surface, hr %#lx.\n", hr
);
16716 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
16717 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#lx.\n", hr
);
16718 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
16719 ok(hr
== DD_OK
, "Failed to get attached surface, hr %#lx.\n", hr
);
16720 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
16721 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
16722 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
16725 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16726 &desc
, ¶m
, enum_surfaces_cb
);
16727 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16728 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16731 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16732 NULL
, ¶m
, enum_surfaces_cb
);
16733 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16734 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16736 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
16738 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16739 &desc
, ¶m
, enum_surfaces_cb
);
16740 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16741 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16744 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
16745 &desc
, ¶m
, enum_surfaces_cb
);
16746 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16747 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16751 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16752 &desc
, ¶m
, enum_surfaces_cb
);
16753 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16754 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16758 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
16759 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16760 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16762 IDirectDrawSurface4_Release(param
.surfaces
[2]);
16763 IDirectDrawSurface4_Release(param
.surfaces
[1]);
16764 IDirectDrawSurface4_Release(param
.surfaces
[0]);
16767 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
16768 NULL
, ¶m
, enum_surfaces_cb
);
16769 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16770 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16772 memset(&desc
, 0, sizeof(desc
));
16773 desc
.dwSize
= sizeof(desc
);
16774 desc
.dwFlags
= DDSD_CAPS
;
16775 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
16777 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
16778 &desc
, ¶m
, enum_surfaces_create_cb
);
16779 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16781 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
16782 &desc
, ¶m
, enum_surfaces_create_cb
);
16783 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16785 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
16786 &desc
, ¶m
, enum_surfaces_create_cb
);
16787 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16789 /* When not passed width and height, the callback is called with every
16790 * available display resolution. */
16792 param
.mode_count
= 0;
16793 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
16794 U4(desc
).ddpfPixelFormat
= current_format
;
16795 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
16796 ok(hr
== DD_OK
, "Failed to build mode list, hr %#lx.\n", hr
);
16799 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
16800 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16801 &desc
, ¶m
, enum_surfaces_create_cb
);
16802 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16803 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
16805 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
16806 desc
.dwWidth
= desc
.dwHeight
= 32;
16808 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
16811 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16812 &desc
, ¶m
, enum_surfaces_create_cb
);
16813 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16814 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16816 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
16817 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
16819 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
16820 &desc
, ¶m
, enum_surfaces_create_cb
);
16821 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16822 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16823 IDirectDrawSurface4_Release(param
.surfaces
[0]);
16825 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
16826 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
16827 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
16828 U4(desc
).ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
16831 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
16832 &desc
, ¶m
, enum_surfaces_create_cb
);
16833 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
16834 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
16836 IDirectDraw4_Release(ddraw
);
16839 static void test_viewport(void)
16844 RECT expected_rect
;
16845 const char *message
;
16849 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
16850 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
16851 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
16852 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
16853 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
16854 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
16856 static const struct
16862 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
16864 static D3DMATRIX mat
=
16866 1.0f
, 0.0f
, 0.0f
, 0.0f
,
16867 0.0f
, 1.0f
, 0.0f
, 0.0f
,
16868 0.0f
, 0.0f
, 1.0f
, 0.0f
,
16869 0.0f
, 0.0f
, 0.0f
, 1.0f
,
16871 static struct vec3 quad
[] =
16873 {-1.5f
, -0.5f
, 0.1f
},
16874 {-1.5f
, 0.5f
, 0.1f
},
16875 { 0.5f
, -0.5f
, 0.1f
},
16876 { 0.5f
, 0.5f
, 0.1f
},
16878 IDirect3DViewport3
*viewport
, *full_viewport
;
16879 IDirectDrawSurface4
*rt
, *ds
;
16880 DDSURFACEDESC2 surface_desc
;
16881 IDirect3DDevice3
*device
;
16882 BOOL expected_failure
;
16883 IDirectDraw4
*ddraw
;
16884 DDPIXELFORMAT z_fmt
;
16885 D3DRECT clear_rect
;
16893 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
16894 0, 0, 640, 480, 0, 0, 0, 0);
16895 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16897 skip("Failed to create a 3D device, skipping test.\n");
16898 DestroyWindow(window
);
16902 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
16903 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
16904 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
16905 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#lx.\n", hr
);
16907 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
16908 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#lx.\n", hr
);
16909 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
16910 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#lx.\n", hr
);
16912 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
16913 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#lx.\n", hr
);
16914 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
16915 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#lx.\n", hr
);
16916 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
16917 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#lx.\n", hr
);
16919 ds
= get_depth_stencil(device
);
16920 memset(&surface_desc
, 0, sizeof(surface_desc
));
16921 surface_desc
.dwSize
= sizeof(surface_desc
);
16922 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds
, &surface_desc
);
16923 z_fmt
= U4(surface_desc
).ddpfPixelFormat
;
16925 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
16927 winetest_push_context("Size %ux%u", rt_sizes
[i
].x
, rt_sizes
[i
].y
);
16931 memset(&surface_desc
, 0, sizeof(surface_desc
));
16932 surface_desc
.dwSize
= sizeof(surface_desc
);
16933 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
16934 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
16935 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
16936 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
16937 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
16938 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16940 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
16941 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16942 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
16943 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
16944 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16945 hr
= IDirectDrawSurface4_AddAttachedSurface(rt
, ds
);
16946 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16948 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
16949 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16953 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
16954 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16957 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
16959 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
16960 U3(clear_rect
).x2
= rt_sizes
[i
].x
;
16961 U4(clear_rect
).y2
= rt_sizes
[i
].y
;
16963 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
16965 winetest_push_context(tests
[j
].message
);
16967 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
16968 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
16970 hr
= IDirect3DViewport3_Clear2(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff000000, 0.0f
, 0);
16971 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16973 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
16974 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16975 hr
= IDirect3DViewport3_SetViewport2(viewport
, NULL
);
16976 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
16977 memset(&vp
, 0, sizeof(vp
));
16978 vp
.dwSize
= sizeof(vp
);
16979 vp
.dwX
= tests
[j
].vp
.dwX
;
16980 vp
.dwY
= tests
[j
].vp
.dwY
;
16981 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
16982 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
16983 vp
.dvClipX
= -1.0f
;
16985 vp
.dvClipWidth
= 2.0f
;
16986 vp
.dvClipHeight
= 2.0f
;
16989 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
16990 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
16991 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
16992 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16993 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
16994 ok(hr
== (expected_failure
? E_INVALIDARG
: DD_OK
), "Got unexpected hr %#lx.\n", hr
);
16996 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16997 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
16998 if (expected_failure
)
17000 destroy_viewport(device
, viewport
);
17001 winetest_pop_context();
17005 hr
= IDirect3DDevice3_BeginScene(device
);
17006 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17007 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
17008 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17009 hr
= IDirect3DDevice3_EndScene(device
);
17010 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17012 check_rect(rt
, tests
[j
].expected_rect
);
17014 destroy_viewport(device
, viewport
);
17015 winetest_pop_context();
17018 destroy_viewport(device
, full_viewport
);
17020 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
17021 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx (i %u).\n", hr
, i
);
17022 IDirectDrawSurface4_Release(ds
);
17024 IDirectDrawSurface4_Release(rt
);
17026 winetest_pop_context();
17029 refcount
= IDirect3DDevice3_Release(device
);
17030 ok(!refcount
, "Device has %lu references left.\n", refcount
);
17031 IDirect3D3_Release(d3d
);
17032 IDirectDraw4_Release(ddraw
);
17033 DestroyWindow(window
);
17036 static void test_find_device(void)
17038 D3DFINDDEVICESEARCH search
= {0};
17039 D3DFINDDEVICERESULT result
= {0};
17040 IDirect3DDevice3
*device
;
17041 IDirectDraw4
*ddraw
;
17051 D3DDEVICEDESC_V1 hw_desc
;
17052 D3DDEVICEDESC_V1 sw_desc
;
17059 D3DDEVICEDESC_V2 hw_desc
;
17060 D3DDEVICEDESC_V2 sw_desc
;
17063 static const struct
17070 {&IID_IDirect3D
, DDERR_NOTFOUND
},
17071 {&IID_IDirect3DRampDevice
, DDERR_NOTFOUND
},
17072 {&IID_IDirect3DRGBDevice
, D3D_OK
},
17073 {&IID_IDirect3DMMXDevice
, DDERR_NOTFOUND
},
17074 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
17075 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
17076 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
17079 ddraw
= create_ddraw();
17080 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17082 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
17084 skip("D3D interface is not available, skipping test.\n");
17085 IDirectDraw4_Release(ddraw
);
17089 result
.dwSize
= sizeof(result
);
17090 search
.dwSize
= sizeof(search
);
17091 hr
= IDirect3D3_FindDevice(d3d
, NULL
, NULL
);
17092 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17093 hr
= IDirect3D3_FindDevice(d3d
, NULL
, &result
);
17094 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17095 hr
= IDirect3D3_FindDevice(d3d
, &search
, NULL
);
17096 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17097 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17098 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17099 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %lu.\n", result
.dwSize
);
17100 ok(result
.ddHwDesc
.dwSize
== sizeof(result
.ddHwDesc
),
17101 "Got unexpected HW desc size %lu.\n", result
.ddHwDesc
.dwSize
);
17102 ok(result
.ddSwDesc
.dwSize
== sizeof(result
.ddSwDesc
),
17103 "Got unexpected SW desc size %lu.\n", result
.ddSwDesc
.dwSize
);
17105 memset(&search
, 0, sizeof(search
));
17106 memset(&result
, 0, sizeof(result
));
17107 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17108 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17110 search
.dwSize
= sizeof(search
) + 1;
17111 result
.dwSize
= sizeof(result
) + 1;
17112 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17113 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17115 search
.dwSize
= sizeof(search
);
17117 memset(&result_v1
, 0, sizeof(result_v1
));
17118 result_v1
.size
= sizeof(result_v1
);
17119 hr
= IDirect3D3_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
17120 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17121 ok(result_v1
.hw_desc
.dwSize
== sizeof(result
.ddHwDesc
),
17122 "Got unexpected HW desc size %lu.\n", result_v1
.hw_desc
.dwSize
);
17123 ok(result_v1
.sw_desc
.dwSize
== sizeof(result
.ddSwDesc
),
17124 "Got unexpected SW desc size %lu.\n", result_v1
.sw_desc
.dwSize
);
17126 memset(&result_v2
, 0, sizeof(result_v2
));
17127 result_v2
.size
= sizeof(result_v2
);
17128 hr
= IDirect3D3_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
17129 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17130 ok(result_v2
.hw_desc
.dwSize
== sizeof(result
.ddHwDesc
),
17131 "Got unexpected HW desc size %lu.\n", result_v2
.hw_desc
.dwSize
);
17132 ok(result_v2
.sw_desc
.dwSize
== sizeof(result
.ddSwDesc
),
17133 "Got unexpected SW desc size %lu.\n", result_v2
.sw_desc
.dwSize
);
17135 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
17137 memset(&search
, 0, sizeof(search
));
17138 search
.dwSize
= sizeof(search
);
17139 search
.dwFlags
= D3DFDS_GUID
;
17140 search
.guid
= *tests
[i
].guid
;
17142 memset(&result
, 0, sizeof(result
));
17143 result
.dwSize
= sizeof(result
);
17145 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17146 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
17147 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %lu.\n", i
, result
.dwSize
);
17150 ok(result
.ddHwDesc
.dwSize
== sizeof(result
.ddHwDesc
),
17151 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
17152 ok(result
.ddSwDesc
.dwSize
== sizeof(result
.ddSwDesc
),
17153 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
17157 ok(!result
.ddHwDesc
.dwSize
,
17158 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
17159 ok(!result
.ddSwDesc
.dwSize
,
17160 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
17164 /* The HAL device can only be enumerated if hardware acceleration is present. */
17165 search
.dwSize
= sizeof(search
);
17166 search
.dwFlags
= D3DFDS_GUID
;
17167 search
.guid
= IID_IDirect3DHALDevice
;
17168 result
.dwSize
= sizeof(result
);
17169 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17171 window
= create_window();
17172 device
= create_device(window
, DDSCL_NORMAL
);
17174 ok(!!device
, "Failed to create a 3D device.\n");
17176 ok(!device
, "Succeeded to create a 3D device.\n");
17178 IDirect3DDevice3_Release(device
);
17179 DestroyWindow(window
);
17181 /* Curiously the colour model criteria seem to be ignored. */
17182 search
.dwSize
= sizeof(search
);
17183 search
.dwFlags
= D3DFDS_COLORMODEL
;
17184 search
.dcmColorModel
= 0xdeadbeef;
17185 result
.dwSize
= sizeof(result
);
17186 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
17187 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17189 IDirect3D3_Release(d3d
);
17190 IDirectDraw4_Release(ddraw
);
17193 static IDirectDraw4
*killfocus_ddraw
;
17194 static IDirectDrawSurface4
*killfocus_surface
;
17196 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
17200 if (message
== WM_KILLFOCUS
)
17202 ref
= IDirectDrawSurface4_Release(killfocus_surface
);
17203 ok(!ref
, "Unexpected surface refcount %lu.\n", ref
);
17204 ref
= IDirectDraw4_Release(killfocus_ddraw
);
17205 ok(!ref
, "Unexpected ddraw refcount %lu.\n", ref
);
17206 killfocus_ddraw
= NULL
;
17209 return DefWindowProcA(window
, message
, wparam
, lparam
);
17212 static void test_killfocus(void)
17214 DDSURFACEDESC2 surface_desc
;
17217 WNDCLASSA wc
= {0};
17219 wc
.lpfnWndProc
= killfocus_proc
;
17220 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
17221 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
17223 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
17224 0, 0, 640, 480, 0, 0, 0, 0);
17226 killfocus_ddraw
= create_ddraw();
17227 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
17229 hr
= IDirectDraw4_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
17230 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
17232 memset(&surface_desc
, 0, sizeof(surface_desc
));
17233 surface_desc
.dwSize
= sizeof(surface_desc
);
17234 surface_desc
.dwFlags
= DDSD_CAPS
;
17235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17236 hr
= IDirectDraw4_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
17237 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
17239 SetForegroundWindow(GetDesktopWindow());
17240 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
17242 DestroyWindow(window
);
17243 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
17246 static void test_sysmem_draw(void)
17248 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
17249 IDirectDrawSurface4
*rt
, *surface
;
17250 IDirect3DViewport3
*viewport
;
17251 DDSURFACEDESC2 surface_desc
;
17252 D3DVERTEXBUFFERDESC vb_desc
;
17253 IDirect3DTexture2
*texture
;
17254 IDirect3DVertexBuffer
*vb
;
17255 IDirect3DDevice3
*device
;
17256 IDirectDraw4
*ddraw
;
17257 unsigned int color
;
17264 static const struct
17266 struct vec3 position
;
17271 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
17272 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
17273 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
17274 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
17275 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
17276 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
17277 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
17278 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
17280 static WORD indices
[] = {4, 5, 6, 7};
17282 window
= create_window();
17283 ok(!!window
, "Failed to create a window.\n");
17285 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17287 skip("Failed to create a 3D device, skipping test.\n");
17288 DestroyWindow(window
);
17292 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
17293 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17294 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
17295 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17296 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
17297 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17299 viewport
= create_viewport(device
, 0, 0, 640, 480);
17300 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
17301 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17303 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17304 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17306 vb_desc
.dwSize
= sizeof(vb_desc
);
17307 vb_desc
.dwCaps
= D3DVBCAPS_SYSTEMMEMORY
;
17308 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
17309 vb_desc
.dwNumVertices
= ARRAY_SIZE(quad
);
17310 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
17311 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17313 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, (void **)&data
, NULL
);
17314 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17315 memcpy(data
, quad
, sizeof(quad
));
17316 hr
= IDirect3DVertexBuffer_Unlock(vb
);
17317 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17319 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
17320 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17322 hr
= IDirect3DDevice3_BeginScene(device
);
17323 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17324 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 4, 4, 0);
17325 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17326 hr
= IDirect3DDevice3_EndScene(device
);
17327 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17329 color
= get_surface_color(rt
, 320, 240);
17330 ok(compare_color(color
, 0x00007f7f, 1), "Got unexpected color 0x%08x.\n", color
);
17332 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
17333 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17335 hr
= IDirect3DDevice3_BeginScene(device
);
17336 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17337 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
17338 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17339 hr
= IDirect3DDevice3_EndScene(device
);
17340 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17342 color
= get_surface_color(rt
, 320, 240);
17343 ok(compare_color(color
, 0x00007f7f, 1), "Got unexpected color 0x%08x.\n", color
);
17345 memset(&surface_desc
, 0, sizeof(surface_desc
));
17346 surface_desc
.dwSize
= sizeof(surface_desc
);
17347 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
17348 surface_desc
.dwHeight
= 2;
17349 surface_desc
.dwWidth
= 2;
17350 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
17351 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
17352 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
17353 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
17354 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
17355 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
17356 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
17357 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
17358 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17359 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17360 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
17361 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17362 IDirectDrawSurface4_Release(surface
);
17363 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
17364 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17366 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
17367 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17369 hr
= IDirect3DDevice3_BeginScene(device
);
17370 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17371 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
17372 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17373 hr
= IDirect3DDevice3_EndScene(device
);
17374 ok(hr
== D3D_OK
|| hr
== D3DERR_SCENE_END_FAILED
, "Got unexpected hr %#lx.\n", hr
);
17376 IDirect3DTexture2_Release(texture
);
17377 IDirect3DVertexBuffer_Release(vb
);
17378 IDirect3DViewport3_Release(viewport
);
17379 IDirectDrawSurface4_Release(rt
);
17380 IDirectDraw4_Release(ddraw
);
17381 IDirect3D3_Release(d3d
);
17382 refcount
= IDirect3DDevice3_Release(device
);
17383 ok(!refcount
, "Device has %lu references left.\n", refcount
);
17384 DestroyWindow(window
);
17387 static void test_gdi_surface(void)
17389 IDirectDrawSurface4
*primary
, *backbuffer
, *gdi_surface
;
17390 DDSCAPS2 caps
= {DDSCAPS_BACKBUFFER
, 0, 0, {0}};
17391 DDSURFACEDESC2 surface_desc
;
17392 IDirectDraw4
*ddraw
;
17397 window
= create_window();
17398 ddraw
= create_ddraw();
17399 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17400 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17401 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17403 /* Retrieving the GDI surface requires a primary surface to exist. */
17404 gdi_surface
= (void *)0xc0dec0de;
17405 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
17406 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
17407 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
17409 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
17410 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
17412 memset(&surface_desc
, 0, sizeof(surface_desc
));
17413 surface_desc
.dwSize
= sizeof(surface_desc
);
17414 surface_desc
.dwFlags
= DDSD_CAPS
;
17415 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17416 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17417 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17419 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
17420 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17421 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17422 IDirectDrawSurface4_Release(gdi_surface
);
17424 /* Flipping to the GDI surface requires the primary surface to be
17426 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
17427 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#lx.\n", hr
);
17429 IDirectDrawSurface4_Release(primary
);
17431 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
17432 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17434 memset(&surface_desc
, 0, sizeof(surface_desc
));
17435 surface_desc
.dwSize
= sizeof(surface_desc
);
17436 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
17437 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
17438 U5(surface_desc
).dwBackBufferCount
= 1;
17439 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
17440 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17441 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &caps
, &backbuffer
);
17442 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17443 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
17445 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
17446 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17447 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17448 IDirectDrawSurface4_Release(gdi_surface
);
17450 hr
= IDirectDrawSurface4_Flip(primary
, NULL
, DDFLIP_WAIT
);
17451 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17452 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
17453 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17454 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
17455 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
17456 IDirectDrawSurface4_Release(gdi_surface
);
17458 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
17459 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17461 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
17462 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17463 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
17464 IDirectDrawSurface4_Release(gdi_surface
);
17466 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
17467 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17469 IDirectDrawSurface4_Release(backbuffer
);
17470 IDirectDrawSurface4_Release(primary
);
17472 refcount
= IDirectDraw4_Release(ddraw
);
17473 ok(!refcount
, "%lu references left.\n", refcount
);
17474 DestroyWindow(window
);
17477 static void test_alphatest(void)
17479 #define ALPHATEST_PASSED 0x0000ff00
17480 #define ALPHATEST_FAILED 0x00ff0000
17481 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
17482 IDirect3DViewport3
*viewport
;
17483 IDirect3DDevice3
*device
;
17484 IDirectDrawSurface4
*rt
;
17485 unsigned int color
, i
;
17491 static const struct
17494 unsigned int color_less
, color_equal
, color_greater
;
17498 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17499 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
17500 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17501 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
17502 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17503 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
17504 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17505 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
17509 struct vec3 position
;
17514 {{-1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17515 {{-1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17516 {{ 1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17517 {{ 1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
17520 window
= create_window();
17521 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
17523 skip("Failed to create a 3D device.\n");
17524 DestroyWindow(window
);
17527 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
17528 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17530 viewport
= create_viewport(device
, 0, 0, 640, 480);
17531 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
17532 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17534 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
17535 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17536 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
17537 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17538 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
17539 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17540 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
17541 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17543 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
17545 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
17546 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17548 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17549 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17550 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
17551 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17552 hr
= IDirect3DDevice3_BeginScene(device
);
17553 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17554 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17555 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17556 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17557 hr
= IDirect3DDevice3_EndScene(device
);
17558 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17559 color
= get_surface_color(rt
, 320, 240);
17560 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17561 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17562 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17564 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
17565 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17566 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
17567 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17568 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
17569 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17570 ok(value
== 0xff70, "Got unexpected value %#lx.\n", value
);
17571 hr
= IDirect3DDevice3_BeginScene(device
);
17572 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17573 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
17574 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
17575 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17576 hr
= IDirect3DDevice3_EndScene(device
);
17577 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
17578 color
= get_surface_color(rt
, 320, 240);
17579 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
17580 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
17581 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
17584 destroy_viewport(device
, viewport
);
17585 IDirectDrawSurface4_Release(rt
);
17586 refcount
= IDirect3DDevice3_Release(device
);
17587 ok(!refcount
, "Device has %lu references left.\n", refcount
);
17588 DestroyWindow(window
);
17591 static void test_clipper_refcount(void)
17593 IDirectDrawSurface4
*surface
;
17594 IDirectDrawClipper
*clipper
, *clipper2
;
17595 DDSURFACEDESC2 surface_desc
;
17596 IDirectDraw4
*ddraw
;
17597 IDirectDraw
*ddraw1
;
17602 const IDirectDrawClipperVtbl
*orig_vtbl
;
17604 window
= create_window();
17605 ddraw
= create_ddraw();
17606 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17607 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17608 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17610 memset(&surface_desc
, 0, sizeof(surface_desc
));
17611 surface_desc
.dwSize
= sizeof(surface_desc
);
17612 surface_desc
.dwFlags
= DDSD_CAPS
;
17613 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
17614 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17615 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17617 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17618 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
17619 refcount
= get_refcount((IUnknown
*)clipper
);
17620 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
17622 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
17624 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
17625 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
17626 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
17627 clipper
->lpVtbl
, clipper2
->lpVtbl
);
17628 orig_vtbl
= clipper
->lpVtbl
;
17629 IDirectDrawClipper_Release(clipper2
);
17631 /* Surfaces hold a reference to clippers. No surprises there. */
17632 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
17633 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
17634 refcount
= get_refcount((IUnknown
*)clipper
);
17635 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
17637 hr
= IDirectDrawSurface4_GetClipper(surface
, &clipper2
);
17638 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
17639 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17640 refcount
= IDirectDrawClipper_Release(clipper2
);
17641 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
17643 hr
= IDirectDrawSurface4_SetClipper(surface
, NULL
);
17644 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
17645 refcount
= get_refcount((IUnknown
*)clipper
);
17646 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
17648 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
17649 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
17650 refcount
= get_refcount((IUnknown
*)clipper
);
17651 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
17653 refcount
= IDirectDrawSurface4_Release(surface
);
17654 ok(!refcount
, "%lu references left.\n", refcount
);
17655 refcount
= get_refcount((IUnknown
*)clipper
);
17656 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
17658 /* SetClipper with an invalid pointer crashes. */
17660 /* Clipper methods work with a broken vtable, with the exception of Release. */
17661 clipper
->lpVtbl
= (void *)0xdeadbeef;
17662 refcount
= orig_vtbl
->AddRef(clipper
);
17663 todo_wine
ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
17664 refcount
= orig_vtbl
->Release(clipper
);
17665 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
17667 clipper
->lpVtbl
= orig_vtbl
;
17668 refcount
= orig_vtbl
->Release(clipper
);
17669 todo_wine
ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
17671 /* Fix the refcount difference because Wine did not increase the ref in the
17672 * AddRef call above. */
17675 refcount
= IDirectDrawClipper_Release(clipper
);
17676 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
17679 /* Steal the reference and see what happens - releasing the surface works fine.
17680 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
17681 * release it after the GetClipper call is likely to crash, and certain to crash
17682 * if we allocate and zero as much heap memory as we can get. */
17683 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17684 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17685 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
17686 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
17687 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
17688 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
17690 IDirectDrawClipper_Release(clipper
);
17691 IDirectDrawClipper_Release(clipper
);
17695 /* Disabled because it causes heap corruption (HeapValidate fails and random
17696 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
17697 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
17698 * is affected too. Some testbot machines have crashes directly in GetClipper
17699 * or proceed with a corrupted heap too.
17701 * The same Windows and driver versions run the test without heap corruption on
17702 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
17703 hr
= IDirectDrawSurface4_GetClipper(surface
, &clipper2
);
17704 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
17705 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
17708 /* Show that invoking the Release method does not crash, but don't get the
17709 * vtable through the clipper pointer because it is no longer pointing to
17711 refcount
= orig_vtbl
->Release(clipper
);
17712 ok(!refcount
, "%lu references left.\n", refcount
);
17714 refcount
= IDirectDrawSurface4_Release(surface
);
17715 ok(!refcount
, "%lu references left.\n", refcount
);
17717 /* It looks like the protection against invalid thispointers is part of
17718 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
17719 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
17720 ok(!!clipper
, "failed to allocate memory\n");
17722 /* Assigning the vtable to our fake clipper does NOT make a difference on
17723 * native - there is a different member of the clipper implementation struct
17724 * that is used to determine if a clipper is valid. */
17725 clipper
->lpVtbl
= orig_vtbl
;
17727 refcount
= orig_vtbl
->AddRef(clipper
);
17728 todo_wine
ok(!refcount
, "Got refcount %lu.\n", refcount
);
17729 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
17730 ok(!refcount
, "Got refcount %lu.\n", refcount
);
17733 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
17734 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17735 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17738 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
17739 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17740 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
17742 /* Nope, we can't initialize our fake clipper. */
17743 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
17744 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#lx.\n", hr
);
17746 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
17747 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
17749 IDirectDraw_Release(ddraw1
);
17751 HeapFree(GetProcessHeap(), 0, clipper
);
17753 refcount
= IDirectDraw4_Release(ddraw
);
17754 ok(!refcount
, "%lu references left.\n", refcount
);
17755 DestroyWindow(window
);
17758 static void test_caps(void)
17760 DWORD caps_never
, caps_always
, caps_hal
;
17761 DDCAPS hal_caps
, hel_caps
;
17762 IDirectDraw4
*ddraw
;
17763 IDirectDraw
*ddraw1
;
17767 caps_never
= DDSCAPS_RESERVED1
17769 | DDSCAPS_PRIMARYSURFACELEFT
17770 | DDSCAPS_SYSTEMMEMORY
17772 | DDSCAPS_WRITEONLY
17773 | DDSCAPS_LIVEVIDEO
17776 | DDSCAPS_RESERVED2
17779 | DDSCAPS_ALLOCONLOAD
17780 | DDSCAPS_VIDEOPORT
17781 | DDSCAPS_STANDARDVGAMODE
17782 | DDSCAPS_OPTIMIZED
;
17784 caps_always
= DDSCAPS_FLIP
17785 | DDSCAPS_OFFSCREENPLAIN
17786 | DDSCAPS_PRIMARYSURFACE
17791 caps_hal
= DDSCAPS_BACKBUFFER
17793 | DDSCAPS_FRONTBUFFER
17795 | DDSCAPS_VIDEOMEMORY
17796 | DDSCAPS_LOCALVIDMEM
17797 | DDSCAPS_NONLOCALVIDMEM
;
17799 ddraw
= create_ddraw();
17800 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17802 memset(&hal_caps
, 0, sizeof(hal_caps
));
17803 memset(&hel_caps
, 0, sizeof(hel_caps
));
17804 hal_caps
.dwSize
= sizeof(hal_caps
);
17805 hel_caps
.dwSize
= sizeof(hel_caps
);
17806 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17807 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17808 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17809 "Got unexpected caps %#lx, expected %#lx.\n",
17810 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17811 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17812 "Got unexpected caps %#lx, expected %#lx.\n",
17813 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17815 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
17816 if (hal_caps
.ddsCaps
.dwCaps
)
17818 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17819 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17820 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17821 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17823 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17824 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17825 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17826 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17828 IDirectDraw4_Release(ddraw
);
17830 if (hal_caps
.ddsCaps
.dwCaps
)
17832 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw1
, NULL
);
17833 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17834 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw
);
17835 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17836 IDirectDraw_Release(ddraw1
);
17838 memset(&hal_caps
, 0, sizeof(hal_caps
));
17839 memset(&hel_caps
, 0, sizeof(hel_caps
));
17840 hal_caps
.dwSize
= sizeof(hal_caps
);
17841 hel_caps
.dwSize
= sizeof(hel_caps
);
17842 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17843 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17844 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17845 "Got unexpected caps %#lx, expected %#lx.\n",
17846 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17847 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17848 "Got unexpected caps %#lx, expected %#lx.\n",
17849 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17851 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17852 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17853 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
17854 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17855 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17857 IDirectDraw4_Release(ddraw
);
17860 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw1
, NULL
);
17861 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17862 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw
);
17863 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17864 IDirectDraw_Release(ddraw1
);
17866 memset(&hal_caps
, 0, sizeof(hal_caps
));
17867 memset(&hel_caps
, 0, sizeof(hel_caps
));
17868 hal_caps
.dwSize
= sizeof(hal_caps
);
17869 hel_caps
.dwSize
= sizeof(hel_caps
);
17870 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
17871 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17872 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
17873 "Got unexpected caps %#lx, expected %#lx.\n",
17874 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
17875 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
17876 "Got unexpected caps %#lx, expected %#lx.\n",
17877 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
17879 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
17880 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17881 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17882 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
17883 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
17885 IDirectDraw4_Release(ddraw
);
17888 static void test_d32_support(void)
17890 IDirectDrawSurface4
*surface
;
17891 DDSURFACEDESC2 surface_desc
;
17892 IDirectDraw4
*ddraw
;
17897 window
= create_window();
17898 ddraw
= create_ddraw();
17899 ok(!!ddraw
, "Failed to create a ddraw object.\n");
17900 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
17901 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17903 memset(&surface_desc
, 0, sizeof(surface_desc
));
17904 surface_desc
.dwSize
= sizeof(surface_desc
);
17905 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
17906 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
17907 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
17908 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
17909 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 32;
17910 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0xffffffff;
17911 surface_desc
.dwWidth
= 64;
17912 surface_desc
.dwHeight
= 64;
17913 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
17914 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17916 memset(&surface_desc
, 0, sizeof(surface_desc
));
17917 surface_desc
.dwSize
= sizeof(surface_desc
);
17918 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
17919 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
17920 ok((surface_desc
.dwFlags
& DDSD_PIXELFORMAT
), "Got unexpected flags %#lx.\n", surface_desc
.dwFlags
);
17921 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
& DDPF_ZBUFFER
,
17922 "Got unexpected format flags %#lx.\n", U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
17923 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
== 32,
17924 "Got unexpected dwZBufferBitDepth %lu.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
);
17925 ok(U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
== 0xffffffff,
17926 "Got unexpected Z mask 0x%08lx.\n", U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
);
17927 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
17928 "Got unexpected surface caps %#lx.\n", surface_desc
.ddsCaps
.dwCaps
);
17929 IDirectDrawSurface4_Release(surface
);
17931 refcount
= IDirectDraw4_Release(ddraw
);
17932 ok(!refcount
, "%lu references left.\n", refcount
);
17933 DestroyWindow(window
);
17936 static void test_surface_format_conversion_alpha(void)
17938 static const unsigned int rgba_data
[4 * 4] =
17940 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff0000ff,
17941 0xff0000ff, 0xff00ff00, 0xff0000ff, 0xff0000ff,
17942 0xff00ff00, 0xff0000ff, 0xff00ff00, 0xff0000ff,
17943 0xff00ff00, 0xff0000ff, 0xff0000ff, 0xff00ff00,
17945 static const unsigned int rgbx_data
[4 * 4] =
17947 0x0000ff00, 0x000000ff, 0x000000ff, 0x000000ff,
17948 0x000000ff, 0x0000ff00, 0x000000ff, 0x000000ff,
17949 0x0000ff00, 0x000000ff, 0x0000ff00, 0x000000ff,
17950 0x0000ff00, 0x000000ff, 0x000000ff, 0x0000ff00,
17952 static const unsigned short int r5g6b5_data
[4 * 4] =
17954 0x07e0, 0x001f, 0x001f, 0x001f,
17955 0x001f, 0x07e0, 0x001f, 0x001f,
17956 0x07e0, 0x001f, 0x07e0, 0x001f,
17957 0x07e0, 0x001f, 0x001f, 0x07e0,
17959 static const unsigned short int r5g5b5x1_data
[4 * 4] =
17961 0x03e0, 0x001f, 0x001f, 0x001f,
17962 0x001f, 0x03e0, 0x001f, 0x001f,
17963 0x03e0, 0x001f, 0x03e0, 0x001f,
17964 0x03e0, 0x001f, 0x001f, 0x03e0,
17966 static const unsigned short int r5g5b5a1_data
[4 * 4] =
17968 0x83e0, 0x801f, 0x801f, 0x801f,
17969 0x801f, 0x83e0, 0x801f, 0x801f,
17970 0x83e0, 0x801f, 0x83e0, 0x801f,
17971 0x83e0, 0x801f, 0x801f, 0x83e0,
17973 static const unsigned int dxt1_data
[8] =
17975 0x001f07e0, 0x14445154,
17977 static const unsigned int dxt2_data
[16] =
17979 0xffffffff, 0xffffffff, 0x001f07e0, 0x14445154,
17982 enum test_format_id
17994 static const struct test_format
17998 unsigned int block_size
, x_blocks
, y_blocks
;
17999 DWORD support_flag
;
18000 BOOL broken_software_blit
, broken_hardware_blit
;
18006 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18007 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
18013 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
18014 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
18020 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
18021 {16}, {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}
18023 "R5G6B5", 2, 4, 4, 0, TRUE
,
18024 /* Looks broken for sysmem texture conversions on Windows (at
18025 * least with hardware device), the result is either error from
18026 * _Blt() or a copy of the source data without any conversion. */
18030 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
18031 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}
18033 "R5G5B5X1", 2, 4, 4,
18037 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18038 {16}, {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}
18040 "R5G5B5A1", 2, 4, 4, 0, FALSE
, TRUE
,
18044 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
18045 {0}, {0}, {0}, {0}, {0}
18047 "DXT1", 8, 1, 1, SUPPORT_DXT1
,
18051 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '2'),
18052 {0}, {0}, {0}, {0}, {0}
18054 "DXT2", 16, 1, 1, SUPPORT_DXT2
,
18058 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '3'),
18059 {0}, {0}, {0}, {0}, {0}
18061 "DXT3", 16, 1, 1, SUPPORT_DXT3
,
18065 static const struct
18067 DWORD src_caps
, dst_caps
;
18071 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18072 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18073 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
},
18074 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
},
18077 static const struct
18079 enum test_format_id src_format
;
18080 const void *src_data
;
18081 enum test_format_id dst_format
;
18082 const void *expected_data
;
18088 /* The following 3 tests give different results on AMD and NVIDIA on Windows, disabling. */
18089 {FMT_RGBX
, rgbx_data
, FMT_RGBA
, rgba_data
},
18090 {FMT_RGBA
, rgba_data
, FMT_RGBX
, rgbx_data
},
18091 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_RGBA
, rgba_data
},
18093 {FMT_R5G6B5
, r5g6b5_data
, FMT_RGBA
, rgba_data
},
18094 {FMT_R5G6B5
, r5g6b5_data
, FMT_R5G5B5A1
, r5g5b5a1_data
},
18095 {FMT_R5G5B5X1
, r5g5b5x1_data
, FMT_R5G5B5A1
, r5g5b5x1_data
, TRUE
},
18096 {FMT_R5G5B5A1
, r5g5b5a1_data
, FMT_R5G6B5
, r5g6b5_data
},
18097 {FMT_RGBA
, rgba_data
, FMT_DXT1
, dxt1_data
},
18098 {FMT_RGBX
, rgbx_data
, FMT_DXT1
, dxt1_data
},
18099 {FMT_RGBA
, rgba_data
, FMT_DXT2
, dxt2_data
},
18100 {FMT_RGBX
, rgbx_data
, FMT_DXT2
, dxt2_data
},
18101 {FMT_RGBA
, rgba_data
, FMT_DXT3
, dxt2_data
},
18102 {FMT_RGBX
, rgbx_data
, FMT_DXT3
, dxt2_data
},
18103 {FMT_DXT1
, dxt1_data
, FMT_DXT2
, dxt2_data
},
18104 {FMT_DXT1
, dxt1_data
, FMT_RGBA
, rgba_data
},
18105 {FMT_DXT1
, dxt1_data
, FMT_RGBX
, rgba_data
},
18106 {FMT_DXT3
, dxt2_data
, FMT_RGBA
, rgba_data
},
18107 {FMT_DXT3
, dxt2_data
, FMT_RGBX
, rgba_data
},
18110 const struct test_format
*src_format
, *dst_format
;
18111 IDirectDrawSurface4
*src_surf
, *dst_surf
;
18112 DDSURFACEDESC2 surface_desc
, lock
;
18113 unsigned int i
, j
, x
, y
, pitch
;
18114 IDirect3DDevice3
*device
;
18115 DWORD supported_fmts
;
18116 IDirectDraw4
*ddraw
;
18123 window
= create_window();
18124 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
18126 skip("Failed to create a 3D device, skipping test.\n");
18127 DestroyWindow(window
);
18131 ddraw
= create_ddraw();
18132 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18133 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18134 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18136 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
,
18138 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18140 is_wine
= !strcmp(winetest_platform
, "wine");
18142 memset(&surface_desc
, 0, sizeof(surface_desc
));
18143 surface_desc
.dwSize
= sizeof(surface_desc
);
18144 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
18145 surface_desc
.dwWidth
= 4;
18146 surface_desc
.dwHeight
= 4;
18148 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
18150 src_format
= &formats
[tests
[i
].src_format
];
18151 dst_format
= &formats
[tests
[i
].dst_format
];
18153 if (~supported_fmts
& dst_format
->support_flag
)
18155 skip("%s format is not supported, skipping test %u.\n", dst_format
->name
, i
);
18158 if (~supported_fmts
& src_format
->support_flag
)
18160 skip("%s format is not supported, skipping test %u.\n", src_format
->name
, i
);
18164 for (j
= 0; j
< ARRAY_SIZE(test_caps
); ++j
)
18166 if (!is_wine
&& ((test_caps
[j
].src_caps
| test_caps
[j
].dst_caps
) & DDSCAPS_SYSTEMMEMORY
)
18167 && (src_format
->broken_software_blit
|| dst_format
->broken_software_blit
))
18169 if (!is_wine
&& (test_caps
[j
].dst_caps
& DDSCAPS_VIDEOMEMORY
)
18170 && dst_format
->broken_hardware_blit
)
18173 U4(surface_desc
).ddpfPixelFormat
= src_format
->fmt
;
18174 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].src_caps
;
18175 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surf
, NULL
);
18176 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#lx.\n", j
, i
, hr
);
18178 U4(surface_desc
).ddpfPixelFormat
= dst_format
->fmt
;
18179 surface_desc
.ddsCaps
.dwCaps
= test_caps
[j
].dst_caps
;
18180 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surf
, NULL
);
18181 ok(hr
== DD_OK
, "Test (%u, %u), got unexpected hr %#lx.\n", j
, i
, hr
);
18183 memset(&lock
, 0, sizeof(lock
));
18184 lock
.dwSize
= sizeof(lock
);
18185 hr
= IDirectDrawSurface4_Lock(src_surf
, NULL
, &lock
, 0, NULL
);
18186 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18187 pitch
= U1(lock
).lPitch
;
18188 for (y
= 0; y
< src_format
->y_blocks
; ++y
)
18190 memcpy((BYTE
*)lock
.lpSurface
+ y
* pitch
,
18191 (BYTE
*)tests
[i
].src_data
+ y
* src_format
->x_blocks
* src_format
->block_size
,
18192 src_format
->block_size
* src_format
->x_blocks
);
18194 hr
= IDirectDrawSurface4_Unlock(src_surf
, NULL
);
18195 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18197 hr
= IDirectDrawSurface4_Blt(dst_surf
, NULL
, src_surf
, NULL
, DDBLT_WAIT
, NULL
);
18198 if (!is_wine
&& FAILED(hr
))
18200 /* Some software blits are rejected on Windows. */
18201 IDirectDrawSurface4_Release(dst_surf
);
18202 IDirectDrawSurface4_Release(src_surf
);
18203 skip("Skipping test (%u, %u), cannot blit %s -> %s, hr %#lx.\n", j
, i
,
18204 src_format
->name
, dst_format
->name
, hr
);
18207 ok(hr
== DD_OK
, "Test (%u, %s -> %s), got unexpected hr %#lx.\n", j
,
18208 src_format
->name
, dst_format
->name
, hr
);
18210 memset(&lock
, 0, sizeof(lock
));
18211 lock
.dwSize
= sizeof(lock
);
18212 hr
= IDirectDrawSurface4_Lock(dst_surf
, NULL
, &lock
, 0, NULL
);
18213 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18214 pitch
= U1(lock
).lPitch
;
18216 for (y
= 0; y
< dst_format
->y_blocks
; ++y
)
18218 const void *expected_data
= tests
[i
].expected_data
;
18220 passed
= !memcmp((BYTE
*)lock
.lpSurface
+ y
* pitch
,
18221 (BYTE
*)expected_data
+ y
* dst_format
->x_blocks
* dst_format
->block_size
,
18222 dst_format
->block_size
* dst_format
->x_blocks
);
18223 todo_wine_if(tests
[i
].todo
)
18224 ok(passed
, "Test (%u, %s -> %s), row %u, unexpected surface data.\n", j
,
18225 src_format
->name
, dst_format
->name
, y
);
18227 if (!passed
&& !(is_wine
&& tests
[i
].todo
))
18229 for (x
= 0; x
< dst_format
->x_blocks
* dst_format
->block_size
/ 4; ++x
)
18231 trace("Test (%u, %u), x %u, y %u, got 0x%08x, expected 0x%08x.\n", j
, i
, x
, y
,
18232 *(unsigned int *)((BYTE
*)lock
.lpSurface
+ y
* pitch
+ x
* 4),
18233 *(unsigned int *)((BYTE
*)expected_data
+ y
* dst_format
->x_blocks
18234 * dst_format
->block_size
+ x
* 4));
18240 hr
= IDirectDrawSurface4_Unlock(dst_surf
, NULL
);
18241 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18243 IDirectDrawSurface4_Release(dst_surf
);
18244 IDirectDrawSurface4_Release(src_surf
);
18248 IDirect3DDevice3_Release(device
);
18249 refcount
= IDirectDraw4_Release(ddraw
);
18250 ok(!refcount
, "%lu references left.\n", refcount
);
18251 DestroyWindow(window
);
18254 struct find_different_mode_param
18256 unsigned int old_width
;
18257 unsigned int old_height
;
18258 unsigned int old_frequency
;
18259 unsigned int new_width
;
18260 unsigned int new_height
;
18261 unsigned int new_frequency
;
18262 unsigned int new_bpp
;
18265 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC2
*surface_desc
, void *context
)
18267 struct find_different_mode_param
*param
= context
;
18269 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
18270 return DDENUMRET_OK
;
18272 /* See comment in ddraw7 about the frequency. */
18273 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
&&
18274 (!compare_uint(surface_desc
->dwRefreshRate
, param
->old_frequency
, 1) || !param
->old_frequency
))
18276 /* See test_coop_level_mode_set_enum_cb() for why enumeration might accidentally continue. */
18277 if (!param
->new_width
|| (param
->new_width
< registry_mode
.dmPelsWidth
18278 && param
->new_height
< registry_mode
.dmPelsHeight
))
18280 param
->new_width
= surface_desc
->dwWidth
;
18281 param
->new_height
= surface_desc
->dwHeight
;
18282 param
->new_frequency
= surface_desc
->dwRefreshRate
;
18283 param
->new_bpp
= surface_desc
->ddpfPixelFormat
.dwRGBBitCount
;
18285 return DDENUMRET_CANCEL
;
18288 return DDENUMRET_OK
;
18291 static void test_cursor_clipping(void)
18293 struct find_different_mode_param param
;
18294 DDSURFACEDESC2 surface_desc
;
18295 RECT rect
, clip_rect
;
18296 IDirectDraw4
*ddraw
;
18301 window
= create_window();
18302 ok(!!window
, "Failed to create a window.\n");
18303 ddraw
= create_ddraw();
18304 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18306 memset(&surface_desc
, 0, sizeof(surface_desc
));
18307 surface_desc
.dwSize
= sizeof(surface_desc
);
18308 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
18309 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
18311 memset(¶m
, 0, sizeof(param
));
18312 param
.old_width
= surface_desc
.dwWidth
;
18313 param
.old_height
= surface_desc
.dwHeight
;
18314 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
18315 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
18316 if (!(param
.new_width
&& param
.new_height
))
18318 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
18322 ret
= ClipCursor(NULL
);
18323 ok(ret
, "ClipCursor failed, error %lu.\n", GetLastError());
18324 get_virtual_rect(&rect
);
18325 ret
= GetClipCursor(&clip_rect
);
18326 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18327 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18328 wine_dbgstr_rect(&clip_rect
));
18330 /* Set cooperative level to normal */
18331 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18332 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18334 get_virtual_rect(&rect
);
18335 ret
= GetClipCursor(&clip_rect
);
18336 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18337 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18338 wine_dbgstr_rect(&clip_rect
));
18340 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18341 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
18344 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
18348 get_virtual_rect(&rect
);
18349 ret
= GetClipCursor(&clip_rect
);
18350 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18351 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18352 wine_dbgstr_rect(&clip_rect
));
18354 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
18355 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
18357 get_virtual_rect(&rect
);
18358 ret
= GetClipCursor(&clip_rect
);
18359 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18360 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18361 wine_dbgstr_rect(&clip_rect
));
18363 /* Switch to full screen cooperative level */
18364 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18365 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18367 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18368 ret
= GetClipCursor(&clip_rect
);
18369 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18370 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18371 wine_dbgstr_rect(&clip_rect
));
18373 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
18374 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
18377 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
18381 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
18382 ret
= GetClipCursor(&clip_rect
);
18383 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18384 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18385 wine_dbgstr_rect(&clip_rect
));
18387 /* Restore display mode */
18388 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
18389 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
18391 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
18392 ret
= GetClipCursor(&clip_rect
);
18393 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18394 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18395 wine_dbgstr_rect(&clip_rect
));
18397 /* Switch to normal cooperative level */
18398 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18399 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18401 get_virtual_rect(&rect
);
18402 ret
= GetClipCursor(&clip_rect
);
18403 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
18404 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
18405 wine_dbgstr_rect(&clip_rect
));
18408 IDirectDraw4_Release(ddraw
);
18409 DestroyWindow(window
);
18412 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18415 RECT primary_rect
, window_rect
, new_rect
;
18416 IDirectDraw4
*ddraw
;
18421 ddraw
= create_ddraw();
18422 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18423 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
18424 monitor_rect
->top
, 100, 100, NULL
, NULL
, NULL
, NULL
);
18425 ok(!!window
, "Failed to create a window.\n");
18428 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18429 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18431 ret
= GetWindowRect(window
, &window_rect
);
18432 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
18433 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
18434 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18435 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18437 new_rect
= window_rect
;
18441 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
18442 new_rect
.bottom
- new_rect
.top
, TRUE
);
18443 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18444 ret
= GetWindowRect(window
, &window_rect
);
18445 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18446 ok(EqualRect(&window_rect
, &new_rect
),
18447 "Expected window rect %s, got %s.\n",
18448 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18449 /* After processing window events window rectangle gets restored. But only once, the size set
18450 * on the second resize remains. */
18452 ret
= GetWindowRect(window
, &window_rect
);
18453 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18454 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
18455 * it may get adjusted depending on window manager. */
18456 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
18457 "Expected window rect %s, got %s.\n",
18458 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18460 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
18461 new_rect
.bottom
- new_rect
.top
, TRUE
);
18462 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18463 ret
= GetWindowRect(window
, &window_rect
);
18464 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18465 ok(EqualRect(&window_rect
, &new_rect
),
18466 "Expected window rect %s, got %s.\n",
18467 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18469 ret
= GetWindowRect(window
, &window_rect
);
18470 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
18471 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
18472 "Expected window rect %s, got %s.\n",
18473 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
18475 /* Window activation should restore the window to fit the whole primary monitor */
18476 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18477 SWP_NOZORDER
| SWP_NOSIZE
);
18478 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
18479 ret
= SetForegroundWindow(GetDesktopWindow());
18480 ok(ret
, "Failed to set foreground window.\n");
18482 ret
= ShowWindow(window
, SW_RESTORE
);
18483 ok(ret
, "Failed to restore window, error %lu.\n", GetLastError());
18485 ret
= SetForegroundWindow(window
);
18486 ok(ret
, "SetForegroundWindow failed, error %lu.\n", GetLastError());
18488 ret
= GetWindowRect(window
, &window_rect
);
18489 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
18490 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18491 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18493 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
18494 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18495 ret
= GetWindowRect(window
, &window_rect
);
18496 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
18497 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
18498 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
18500 DestroyWindow(window
);
18501 IDirectDraw4_Release(ddraw
);
18505 static void test_window_position(void)
18507 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
18510 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
18513 DDSURFACEDESC2 surface_desc
;
18514 IDirectDraw4
*ddraw
;
18519 ddraw
= create_ddraw();
18520 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18521 window
= create_window();
18522 ok(!!window
, "Failed to create a window.\n");
18524 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
18525 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
18526 SWP_NOZORDER
| SWP_NOSIZE
);
18527 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
18529 surface_desc
.dwSize
= sizeof(surface_desc
);
18530 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
18531 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
18532 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %lu.\n",
18533 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
18534 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %lu.\n",
18535 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
18537 DestroyWindow(window
);
18538 IDirectDraw4_Release(ddraw
);
18542 static void test_get_display_mode(void)
18544 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
18545 struct find_different_mode_param param
;
18546 DDSURFACEDESC2 surface_desc
;
18547 IDirectDraw4
*ddraw
;
18553 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
18555 ddraw
= create_ddraw();
18556 ok(!!ddraw
, "Failed to create a ddraw object.\n");
18557 window
= create_window();
18558 ok(!!window
, "Failed to create a window.\n");
18560 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
18561 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
18563 memset(&devmode
, 0, sizeof(devmode
));
18564 devmode
.dmSize
= sizeof(devmode
);
18565 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
18566 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
18568 surface_desc
.dwSize
= sizeof(surface_desc
);
18569 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
18570 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
18571 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Got dwSize %lu.\n", surface_desc
.dwSize
);
18572 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#lx, got %#lx.\n", flags
,
18573 surface_desc
.dwFlags
);
18574 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %lu, got %lu.\n",
18575 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
18576 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %lu, got %lu.\n",
18577 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
18578 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %lu, got %lu.\n",
18579 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
18580 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
18581 "Got ddpfPixelFormat.dwSize %lu.\n", surface_desc
.ddpfPixelFormat
.dwSize
);
18582 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
18583 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
18584 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18585 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18586 "Expected pitch %lu, got %lu.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
18587 surface_desc
.lPitch
);
18589 memset(¶m
, 0, sizeof(param
));
18590 param
.old_frequency
= surface_desc
.dwRefreshRate
;
18591 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, DDEDM_REFRESHRATES
, NULL
, ¶m
,
18592 find_different_mode_callback
);
18593 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
18594 if (!param
.new_frequency
)
18596 skip("Failed to find a display mode with a different frequency.\n");
18600 hr
= IDirectDraw4_SetDisplayMode(ddraw
, param
.new_width
, param
.new_height
, param
.new_bpp
,
18601 param
.new_frequency
, 0);
18602 ok(hr
== DD_OK
, "SetDisplayMode failed, hr %#lx.\n", hr
);
18603 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
18604 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
18605 ok(surface_desc
.dwWidth
== param
.new_width
, "Expected width %u, got %lu.\n", param
.new_width
,
18606 surface_desc
.dwWidth
);
18607 ok(surface_desc
.dwHeight
== param
.new_height
, "Expected height %u, got %lu.\n", param
.new_height
,
18608 surface_desc
.dwHeight
);
18609 ok(surface_desc
.dwRefreshRate
== param
.new_frequency
, "Expected frequency %u, got %lu.\n",
18610 param
.new_frequency
, surface_desc
.dwRefreshRate
);
18611 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== param
.new_bpp
,
18612 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
18613 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
18616 DestroyWindow(window
);
18617 IDirectDraw4_Release(ddraw
);
18620 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
18622 test_func(&IID_IDirect3DHALDevice
);
18623 test_func(&IID_IDirect3DRGBDevice
);
18626 static void test_texture_wrong_caps(const GUID
*device_guid
)
18630 struct vec3 position
;
18631 struct vec2 texcoord
;
18635 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
18636 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
18637 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
18638 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
18640 static DDPIXELFORMAT fmt
=
18642 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
18643 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
18645 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
18646 unsigned int color
, expected_color
;
18647 IDirectDrawSurface4
*surface
, *rt
;
18648 IDirect3DViewport3
*viewport
;
18649 IDirect3DTexture2
*texture
;
18650 IDirect3DDevice3
*device
;
18651 IDirectDraw4
*ddraw
;
18652 DDSURFACEDESC2 ddsd
;
18658 window
= create_window();
18659 if (!(device
= create_device_ex(window
, DDSCL_NORMAL
, device_guid
)))
18661 skip("Failed to create a 3D device, skipping test.\n");
18662 DestroyWindow(window
);
18665 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
18666 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18667 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
18668 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18669 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
18670 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18672 viewport
= create_viewport(device
, 0, 0, 640, 480);
18673 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
18674 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18676 memset(&ddsd
, 0, sizeof(ddsd
));
18677 ddsd
.dwSize
= sizeof(ddsd
);
18678 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
18679 ddsd
.dwHeight
= 16;
18681 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
18682 U4(ddsd
).ddpfPixelFormat
= fmt
;
18683 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
18684 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18685 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
18686 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
18688 fill_surface(surface
, 0xff00ff00);
18690 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
18691 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18693 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
18694 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18695 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
18696 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18697 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
18698 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18699 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_TEXTURE
);
18701 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18702 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
18703 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18704 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
18705 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18706 hr
= IDirect3DDevice3_BeginScene(device
);
18707 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18708 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
18709 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
18710 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18711 hr
= IDirect3DDevice3_EndScene(device
);
18712 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
18714 expected_color
= is_software_device_type(device_guid
) ? 0x0000ff00 : 0x00ffffff;
18715 color
= get_surface_color(rt
, 320, 240);
18716 ok(color
== expected_color
, "Got color 0x%08x, expected 0x%08x.\n", color
, expected_color
);
18718 IDirect3DTexture2_Release(texture
);
18719 IDirectDrawSurface4_Release(surface
);
18720 IDirectDrawSurface4_Release(rt
);
18721 destroy_viewport(device
, viewport
);
18722 IDirectDraw4_Release(ddraw
);
18723 IDirect3D3_Release(d3d
);
18724 refcount
= IDirect3DDevice3_Release(device
);
18725 ok(!refcount
, "Device has %lu references left.\n", refcount
);
18726 DestroyWindow(window
);
18729 static void test_filling_convention(void)
18731 IDirectDrawSurface4
*rt
, *backbuffer
, *cur
, *ds
;
18732 static const DWORD colour_bottom
= 0x00ffff00;
18733 static const DWORD colour_clear
= 0x000000ff;
18734 static const DWORD colour_right
= 0x00000000;
18735 static const DWORD colour_left
= 0x00ff0000;
18736 static const DWORD colour_top
= 0x0000ff00;
18737 unsigned int colour
, expected
, i
, j
, x
, y
;
18738 IDirect3DViewport3
*viewport
;
18739 IDirect3DDevice3
*device
;
18740 IDirectDraw4
*ddraw
;
18741 DDSURFACEDESC2 desc
;
18748 static const unsigned int vp_size
= 8;
18749 D3DRECT clear_rect
= {{0}, {0}, {vp_size
}, {vp_size
}};
18751 /* This test data follows the examples in MSDN's
18752 * "Rasterization Rules (Direct3D 9)" article.
18754 * See the d3d9 test for a comment about the eps value. */
18755 static const float eps
= 1.0f
/ 64.0f
;
18758 struct vec3 position
;
18764 {{-2.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_left
},
18765 {{-2.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_left
},
18766 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_left
},
18769 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_top
},
18770 {{-2.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_top
},
18771 {{-0.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_top
},
18774 {{-0.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_right
},
18775 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_right
},
18776 {{-0.5f
/ 4.0f
, 2.5f
/ 4.0f
, 0.0f
}, colour_right
},
18779 {{-2.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18780 {{-1.5f
/ 4.0f
, 0.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18781 {{-0.5f
/ 4.0f
, -1.5f
/ 4.0f
, 0.0f
}, colour_bottom
},
18787 {{-2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18788 {{-2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18789 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18792 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18793 {{-2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18794 {{ 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18797 {{ 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18798 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18799 {{ 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18802 {{-2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18803 {{-1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18804 {{ 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18806 nudge_right_tris
[] =
18809 {{eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18810 {{eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18811 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18814 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18815 {{eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18816 {{eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18819 {{eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18820 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18821 {{eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18824 {{eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18825 {{eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18826 {{eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18828 nudge_left_tris
[] =
18830 {{-eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18831 {{-eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18832 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18835 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18836 {{-eps
- 2.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18837 {{-eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18840 {{-eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18841 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18842 {{-eps
- 0.0f
/ 4.0f
, 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18845 {{-eps
- 2.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18846 {{-eps
- 1.0f
/ 4.0f
, 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18847 {{-eps
- 0.0f
/ 4.0f
, -1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18852 {{-2.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18853 {{-2.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18854 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18857 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18858 {{-2.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18859 {{ 0.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18862 {{ 0.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18863 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18864 {{ 0.0f
/ 4.0f
, eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18867 {{-2.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18868 {{-1.0f
/ 4.0f
, eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18869 {{ 0.0f
/ 4.0f
, eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18871 nudge_bottom_tris
[] =
18874 {{-2.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18875 {{-2.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_left
},
18876 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_left
},
18879 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_top
},
18880 {{-2.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18881 {{ 0.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_top
},
18884 {{ 0.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18885 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_right
},
18886 {{ 0.0f
/ 4.0f
, -eps
+ 3.0f
/ 4.0f
, 0.0f
}, colour_right
},
18889 {{-2.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18890 {{-1.0f
/ 4.0f
, -eps
+ 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18891 {{ 0.0f
/ 4.0f
, -eps
- 1.0f
/ 4.0f
, 0.0f
}, colour_bottom
},
18896 struct vec4 position
;
18902 {{ 1.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_left
},
18903 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_left
},
18904 {{ 1.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_left
},
18907 {{ 1.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_top
},
18908 {{ 3.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_top
},
18909 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_top
},
18912 {{ 3.5f
, 1.5f
, 0.0f
, 1.0f
}, colour_right
},
18913 {{ 3.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_right
},
18914 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_right
},
18917 {{ 2.5f
, 3.5f
, 0.0f
, 1.0f
}, colour_bottom
},
18918 {{ 3.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_bottom
},
18919 {{ 1.5f
, 5.5f
, 0.0f
, 1.0f
}, colour_bottom
},
18924 {{ 2.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_left
},
18925 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_left
},
18926 {{ 2.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_left
},
18929 {{ 2.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_top
},
18930 {{ 4.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_top
},
18931 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_top
},
18934 {{ 4.0f
, 1.0f
, 0.0f
, 1.0f
}, colour_right
},
18935 {{ 4.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_right
},
18936 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_right
},
18939 {{ 3.0f
, 3.0f
, 0.0f
, 1.0f
}, colour_bottom
},
18940 {{ 4.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_bottom
},
18941 {{ 2.0f
, 5.0f
, 0.0f
, 1.0f
}, colour_bottom
},
18948 const char *expected
[8];
18954 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
18968 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
18982 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
18996 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19010 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19024 D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
19038 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
,
19052 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
,
19066 window
= create_window();
19067 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
19069 skip("Failed to create 3D device.\n");
19070 DestroyWindow(window
);
19074 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
19075 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
19076 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
19077 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
19078 hr
= IDirect3DDevice3_GetRenderTarget(device
, &backbuffer
);
19079 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
19080 viewport
= create_viewport(device
, 0, 0, vp_size
, vp_size
);
19081 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
19082 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19084 memset(&desc
, 0, sizeof(desc
));
19085 desc
.dwSize
= sizeof(desc
);
19086 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
19087 desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
19088 desc
.dwWidth
= vp_size
;
19089 desc
.dwHeight
= vp_size
;
19090 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
19091 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
19092 desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
19093 desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
19094 desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
19095 desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
19096 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, &rt
, NULL
);
19097 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19099 /* Nvidia on Windows 10 refuses to set the offscreen RT
19100 * if it does not have an attached depth stencil. */
19101 ds
= get_depth_stencil(device
);
19102 memset(&desc
, 0, sizeof(desc
));
19103 desc
.dwSize
= sizeof(desc
);
19104 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
19105 hr
= IDirectDrawSurface4_GetPixelFormat(ds
, &desc
.ddpfPixelFormat
);
19106 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19107 IDirectDrawSurface4_Release(ds
);
19109 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
19110 desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
19111 desc
.dwWidth
= vp_size
;
19112 desc
.dwHeight
= vp_size
;
19113 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, &ds
, NULL
);
19114 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19115 hr
= IDirectDrawSurface4_AddAttachedSurface(rt
, ds
);
19116 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
19118 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
19119 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19120 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
19121 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19123 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
19125 for (j
= 0; j
< 2; ++j
)
19127 cur
= j
? rt
: backbuffer
;
19129 hr
= IDirect3DDevice3_SetRenderTarget(device
, cur
, 0);
19130 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19131 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, colour_clear
, 0.0f
, 0);
19132 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19134 hr
= IDirect3DDevice3_BeginScene(device
);
19135 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19136 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLELIST
,
19137 tests
[i
].fvf
, tests
[i
].geometry
, 12, 0);
19138 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19139 hr
= IDirect3DDevice3_EndScene(device
);
19140 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
19142 for (y
= 0; y
< 8; y
++)
19144 for (x
= 0; x
< 8; x
++)
19147 switch (tests
[i
].expected
[y
][x
])
19149 case 'l': todo
= TRUE
;
19151 expected
= colour_left
;
19153 case 't': todo
= TRUE
;
19155 expected
= colour_top
;
19157 case 'r': todo
= TRUE
;
19159 expected
= colour_right
;
19161 case 'b': todo
= TRUE
;
19163 expected
= colour_bottom
;
19166 expected
= colour_clear
;
19169 ok(0, "Unexpected entry in expected test char\n");
19170 expected
= 0xdeadbeef;
19172 colour
= get_surface_color(cur
, x
, y
);
19173 /* The nudge-to-bottom test fails on cards that give us a bottom-left
19174 * filling convention. The cause isn't the bottom part of the filling
19175 * convention, but because wined3d will nudge geometry to the left to
19176 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
19177 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
19178 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
19179 colour
, x
, y
, i
, j
);
19185 destroy_viewport(device
, viewport
);
19186 IDirectDrawSurface4_Release(backbuffer
);
19187 IDirectDrawSurface4_Release(rt
);
19188 IDirectDrawSurface4_Release(ds
);
19189 IDirectDraw4_Release(ddraw
);
19190 IDirect3D3_Release(d3d
);
19191 refcount
= IDirect3DDevice3_Release(device
);
19192 ok(!refcount
, "Device has %lu references left.\n", refcount
);
19193 DestroyWindow(window
);
19196 static HRESULT WINAPI
test_enum_devices_caps_callback(GUID
*guid
, char *device_desc
,
19197 char *device_name
, D3DDEVICEDESC
*hal
, D3DDEVICEDESC
*hel
, void *ctx
)
19199 if(IsEqualGUID(&IID_IDirect3DRGBDevice
, guid
))
19201 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19202 "RGB Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
19203 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19204 "RGB Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
19205 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19206 "RGB Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19207 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19208 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19210 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19211 "RGB Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19212 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19213 "RGB Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19214 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19215 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19216 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19217 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19219 ok(hal
->dcmColorModel
== 0, "RGB Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
19220 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "RGB Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
19222 ok(hal
->dwFlags
== 0, "RGB Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
19223 ok(hel
->dwFlags
!= 0, "RGB Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
19225 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19226 "RGB Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19227 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19228 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19229 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19230 "RGB Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19231 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19232 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19234 else if(IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
19236 ok(hal
->dcmColorModel
== D3DCOLOR_RGB
, "HAL Device hal caps has colormodel %lu\n", hel
->dcmColorModel
);
19237 ok(hel
->dcmColorModel
== 0, "HAL Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
19239 ok(hal
->dwFlags
!= 0, "HAL Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
19240 ok(hel
->dwFlags
!= 0, "HAL Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
19242 ok(hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
,
19243 "HAL Device hal device caps does not have D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19244 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19245 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19246 ok(hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
,
19247 "HAL Device hal device caps does not have D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19248 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19249 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19251 else if(IsEqualGUID(&IID_IDirect3DRefDevice
, guid
))
19253 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19254 "REF Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
19255 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19256 "REF Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
19257 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19258 "REF Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19259 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19260 "REF Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19262 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19263 "REF Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19264 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19265 "REF Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19266 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19267 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19268 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19269 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19271 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19272 "REF Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19273 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19274 "REF Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19275 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19276 "REF Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19277 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19278 "REF Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19280 else if(IsEqualGUID(&IID_IDirect3DRampDevice
, guid
))
19282 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19283 "Ramp Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
19284 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19285 "Ramp Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
19286 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19287 "Ramp Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19288 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19289 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19291 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19292 "Ramp Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19293 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19294 "Ramp Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19295 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19296 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19297 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19298 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19300 ok(hal
->dcmColorModel
== 0, "Ramp Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
19301 ok(hel
->dcmColorModel
== D3DCOLOR_MONO
, "Ramp Device hel caps has colormodel %lu\n",
19302 hel
->dcmColorModel
);
19304 ok(hal
->dwFlags
== 0, "Ramp Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
19305 ok(hel
->dwFlags
!= 0, "Ramp Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
19307 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19308 "Ramp Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19309 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19310 "Ramp Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19311 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19312 "Ramp Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19313 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19314 "Ramp Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19316 else if(IsEqualGUID(&IID_IDirect3DMMXDevice
, guid
))
19318 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19319 "MMX Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
19320 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
19321 "MMX Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
19322 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19323 "MMX Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19324 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
19325 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
19327 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19328 "MMX Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19329 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
19330 "MMX Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
19331 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19332 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19333 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
19334 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
19336 ok(hal
->dcmColorModel
== 0, "MMX Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
19337 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "MMX Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
19339 ok(hal
->dwFlags
== 0, "MMX Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
19340 ok(hel
->dwFlags
!= 0, "MMX Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
19342 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19343 "MMX Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19344 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
19345 "MMX Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
19346 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19347 "MMX Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19348 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
19349 "MMX Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
19353 ok(FALSE
, "Unexpected device enumerated: \"%s\" \"%s\"\n", device_desc
, device_name
);
19354 if (hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
19355 trace("hal line has pow2 set\n");
19357 trace("hal line does NOT have pow2 set\n");
19358 if (hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
19359 trace("hal tri has pow2 set\n");
19361 trace("hal tri does NOT have pow2 set\n");
19362 if (hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
19363 trace("hel line has pow2 set\n");
19365 trace("hel line does NOT have pow2 set\n");
19366 if (hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
19367 trace("hel tri has pow2 set\n");
19369 trace("hel tri does NOT have pow2 set\n");
19372 return DDENUMRET_OK
;
19375 static void test_enum_devices(void)
19377 IDirectDraw4
*ddraw
;
19382 ddraw
= create_ddraw();
19383 ok(!!ddraw
, "Failed to create a ddraw object.\n");
19385 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
);
19388 skip("D3D interface is not available, skipping test.\n");
19389 IDirectDraw4_Release(ddraw
);
19393 hr
= IDirect3D3_EnumDevices(d3d
, NULL
, NULL
);
19394 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
19396 hr
= IDirect3D3_EnumDevices(d3d
, test_enum_devices_caps_callback
, NULL
);
19397 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
19399 IDirect3D3_Release(d3d
);
19400 refcount
= IDirectDraw4_Release(ddraw
);
19401 ok(!refcount
, "Device has %lu references left.\n", refcount
);
19406 DDDEVICEIDENTIFIER identifier
;
19407 DEVMODEW current_mode
;
19408 IDirectDraw4
*ddraw
;
19411 if (!(ddraw
= create_ddraw()))
19413 skip("Failed to create a ddraw object, skipping tests.\n");
19417 if (ddraw_get_identifier(ddraw
, &identifier
))
19419 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
19420 trace("Description string: \"%s\"\n", identifier
.szDescription
);
19421 trace("Driver version %d.%d.%d.%d\n",
19422 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
19423 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
19425 IDirectDraw4_Release(ddraw
);
19427 memset(¤t_mode
, 0, sizeof(current_mode
));
19428 current_mode
.dmSize
= sizeof(current_mode
);
19429 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
19430 registry_mode
.dmSize
= sizeof(registry_mode
);
19431 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
19432 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
19433 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
19435 skip("Current mode does not match registry mode, skipping test.\n");
19439 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
19440 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
19442 test_process_vertices();
19443 test_coop_level_create_device_window();
19444 test_clipper_blt();
19445 test_coop_level_d3d_state();
19446 test_surface_interface_mismatch();
19447 test_coop_level_threaded();
19448 run_for_each_device_type(test_depth_blit
);
19449 test_texture_load_ckey();
19450 test_viewport_object();
19451 run_for_each_device_type(test_zenable
);
19452 run_for_each_device_type(test_ck_rgba
);
19458 test_window_style();
19459 test_redundant_mode_set();
19460 test_coop_level_mode_set();
19461 test_coop_level_mode_set_multi();
19463 test_coop_level_surf_create();
19465 test_coop_level_multi_window();
19466 test_draw_strided();
19468 test_specular_lighting();
19469 test_clear_rect_count();
19470 test_coop_level_versions();
19471 test_lighting_interface_versions();
19472 test_coop_level_activateapp();
19473 test_texturemanage();
19474 test_block_formats_creation();
19475 test_unsupported_formats();
19476 run_for_each_device_type(test_rt_caps
);
19477 test_primary_caps();
19478 test_surface_lock();
19479 test_surface_discard();
19481 test_set_surface_desc();
19482 test_user_memory_getdc();
19483 test_sysmem_overlay();
19484 test_primary_palette();
19485 test_surface_attachment();
19486 test_private_data();
19487 test_pixel_format();
19488 test_create_surface_pitch();
19490 test_palette_complex();
19493 test_palette_gdi();
19494 test_palette_alpha();
19495 test_vb_writeonly();
19496 test_lost_device();
19497 test_surface_desc_lock();
19498 test_texturemapblend();
19499 test_signed_formats();
19501 test_texcoordindex();
19502 test_colorkey_precision();
19503 test_range_colorkey();
19505 test_lockrect_invalid();
19506 test_yv12_overlay();
19507 test_offscreen_overlay();
19508 test_overlay_rect();
19510 test_blt_z_alpha();
19511 test_cross_device_blt();
19512 test_color_clamping();
19514 test_draw_primitive();
19515 test_edge_antialiasing_blending();
19516 test_transform_vertices();
19517 test_display_mode_surface_pixel_format();
19518 test_surface_desc_size();
19519 test_get_surface_from_dc();
19520 test_ck_operation();
19521 test_vb_refcount();
19522 test_compute_sphere_visibility();
19523 test_texture_stages_limits();
19524 test_set_render_state();
19525 test_map_synchronisation();
19526 test_depth_readback();
19528 test_enum_surfaces();
19530 test_find_device();
19532 test_sysmem_draw();
19533 test_gdi_surface();
19535 test_clipper_refcount();
19537 test_d32_support();
19538 test_surface_format_conversion_alpha();
19539 test_cursor_clipping();
19540 test_window_position();
19541 test_get_display_mode();
19542 run_for_each_device_type(test_texture_wrong_caps
);
19543 test_filling_convention();
19544 test_enum_devices();