2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2013 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 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
31 static DEVMODEW registry_mode
;
33 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
45 struct create_window_thread_param
48 HANDLE window_created
;
49 HANDLE destroy_window
;
53 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
63 if (abs(x
- y
) > ulps
)
69 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
71 return compare_float(vec
->x
, x
, ulps
)
72 && compare_float(vec
->y
, y
, ulps
)
73 && compare_float(vec
->z
, z
, ulps
)
74 && compare_float(vec
->w
, w
, ulps
);
77 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
79 unsigned int diff
= x
> y
? x
- y
: y
- x
;
81 return diff
<= max_diff
;
84 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
86 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
87 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
88 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
89 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
92 static void get_virtual_rect(RECT
*rect
)
94 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
95 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
96 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
97 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
100 /* Try to make sure pending X events have been processed before continuing */
101 static void flush_events(void)
107 time
= GetTickCount() + diff
;
110 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
112 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
113 DispatchMessageA(&msg
);
114 diff
= time
- GetTickCount();
118 static BOOL
ddraw_get_identifier(IDirectDraw
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
120 IDirectDraw4
*ddraw4
;
123 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
124 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#lx.\n", hr
);
125 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
126 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#lx.\n", hr
);
127 IDirectDraw4_Release(ddraw4
);
129 return SUCCEEDED(hr
);
132 static BOOL
ddraw_is_warp(IDirectDraw
*ddraw
)
134 DDDEVICEIDENTIFIER identifier
;
136 return strcmp(winetest_platform
, "wine")
137 && ddraw_get_identifier(ddraw
, &identifier
)
138 && strstr(identifier
.szDriver
, "warp");
141 static BOOL
ddraw_is_vendor(IDirectDraw
*ddraw
, DWORD vendor
)
143 DDDEVICEIDENTIFIER identifier
;
145 return strcmp(winetest_platform
, "wine")
146 && ddraw_get_identifier(ddraw
, &identifier
)
147 && identifier
.dwVendorId
== vendor
;
150 static BOOL
ddraw_is_amd(IDirectDraw
*ddraw
)
152 return ddraw_is_vendor(ddraw
, 0x1002);
155 static BOOL
ddraw_is_intel(IDirectDraw
*ddraw
)
157 return ddraw_is_vendor(ddraw
, 0x8086);
160 static BOOL
ddraw_is_nvidia(IDirectDraw
*ddraw
)
162 return ddraw_is_vendor(ddraw
, 0x10de);
165 static BOOL
ddraw_is_vmware(IDirectDraw
*ddraw
)
167 return ddraw_is_vendor(ddraw
, 0x15ad);
170 static BOOL
is_software_device_type(const GUID
*device_guid
)
172 return device_guid
!= &IID_IDirect3DHALDevice
;
175 static IDirectDrawSurface
*create_overlay(IDirectDraw
*ddraw
,
176 unsigned int width
, unsigned int height
, DWORD format
)
178 IDirectDrawSurface
*surface
;
181 memset(&desc
, 0, sizeof(desc
));
182 desc
.dwSize
= sizeof(desc
);
183 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
184 desc
.dwWidth
= width
;
185 desc
.dwHeight
= height
;
186 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
187 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
188 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
189 desc
.ddpfPixelFormat
.dwFourCC
= format
;
191 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
196 static HWND
create_window(void)
198 RECT r
= {0, 0, 640, 480};
200 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
202 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
203 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
206 static DWORD WINAPI
create_window_thread_proc(void *param
)
208 struct create_window_thread_param
*p
= param
;
212 p
->window
= create_window();
213 ret
= SetEvent(p
->window_created
);
214 ok(ret
, "SetEvent failed, last error %lu.\n", GetLastError());
220 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
221 DispatchMessageA(&msg
);
222 res
= WaitForSingleObject(p
->destroy_window
, 100);
223 if (res
== WAIT_OBJECT_0
)
225 if (res
!= WAIT_TIMEOUT
)
227 ok(0, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
232 DestroyWindow(p
->window
);
237 static void create_window_thread(struct create_window_thread_param
*p
)
241 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
242 ok(!!p
->window_created
, "CreateEvent failed, last error %lu.\n", GetLastError());
243 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
244 ok(!!p
->destroy_window
, "CreateEvent failed, last error %lu.\n", GetLastError());
245 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
246 ok(!!p
->thread
, "Failed to create thread, last error %lu.\n", GetLastError());
247 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
248 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
251 static void destroy_window_thread(struct create_window_thread_param
*p
)
253 SetEvent(p
->destroy_window
);
254 WaitForSingleObject(p
->thread
, INFINITE
);
255 CloseHandle(p
->destroy_window
);
256 CloseHandle(p
->window_created
);
257 CloseHandle(p
->thread
);
260 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice
*device
)
262 IDirectDrawSurface
*rt
, *ret
;
263 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
266 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
267 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
268 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
269 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#lx.\n", hr
);
270 IDirectDrawSurface_Release(rt
);
274 /* Free original_modes after finished using it */
275 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
277 unsigned int number
, size
= 2, count
= 0, index
= 0;
278 DISPLAY_DEVICEW display_device
;
279 DEVMODEW
*modes
, *tmp
;
281 if (!(modes
= heap_alloc(size
* sizeof(*modes
))))
284 display_device
.cb
= sizeof(display_device
);
285 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
287 /* Skip software devices */
288 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
291 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
297 if (!(tmp
= heap_realloc(modes
, size
* sizeof(*modes
))))
305 memset(&modes
[count
], 0, sizeof(modes
[count
]));
306 modes
[count
].dmSize
= sizeof(modes
[count
]);
307 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
313 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
316 *original_modes
= modes
;
317 *display_count
= count
;
321 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
326 for (index
= 0; index
< count
; ++index
)
328 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
329 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
330 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
333 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
334 return ret
== DISP_CHANGE_SUCCESSFUL
;
337 static HRESULT
set_display_mode(IDirectDraw
*ddraw
, DWORD width
, DWORD height
)
339 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
341 return IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24);
344 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
346 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
347 DDSURFACEDESC surface_desc
;
351 memset(&surface_desc
, 0, sizeof(surface_desc
));
352 surface_desc
.dwSize
= sizeof(surface_desc
);
354 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
355 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
359 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
361 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
362 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
367 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
369 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
374 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
375 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
377 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
379 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
380 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
386 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
387 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
390 static void check_rect(IDirectDrawSurface
*surface
, RECT r
)
392 LONG x_coords
[2][2] =
394 {r
.left
- 1, r
.left
+ 1},
395 {r
.right
+ 1, r
.right
- 1},
397 LONG y_coords
[2][2] =
399 {r
.top
- 1, r
.top
+ 1},
400 {r
.bottom
+ 1, r
.bottom
- 1}
402 unsigned int i
, j
, x_side
, y_side
, color
;
405 for (i
= 0; i
< 2; ++i
)
407 for (j
= 0; j
< 2; ++j
)
409 for (x_side
= 0; x_side
< 2; ++x_side
)
411 for (y_side
= 0; y_side
< 2; ++y_side
)
413 unsigned int expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
415 x
= x_coords
[i
][x_side
];
416 y
= y_coords
[j
][y_side
];
417 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
419 color
= get_surface_color(surface
, x
, y
);
420 ok(color
== expected
, "Pixel (%ld, %ld) has color %08x, expected %08x.\n", x
, y
, color
, expected
);
427 static void emit_process_vertices(void **ptr
, DWORD flags
, WORD base_idx
, DWORD vertex_count
)
429 D3DINSTRUCTION
*inst
= *ptr
;
430 D3DPROCESSVERTICES
*pv
= (D3DPROCESSVERTICES
*)(inst
+ 1);
432 inst
->bOpcode
= D3DOP_PROCESSVERTICES
;
433 inst
->bSize
= sizeof(*pv
);
437 pv
->wStart
= base_idx
;
439 pv
->dwCount
= vertex_count
;
445 static void emit_set_ts(void **ptr
, D3DTRANSFORMSTATETYPE state
, DWORD value
)
447 D3DINSTRUCTION
*inst
= *ptr
;
448 D3DSTATE
*ts
= (D3DSTATE
*)(inst
+ 1);
450 inst
->bOpcode
= D3DOP_STATETRANSFORM
;
451 inst
->bSize
= sizeof(*ts
);
454 U1(*ts
).dtstTransformStateType
= state
;
455 U2(*ts
).dwArg
[0] = value
;
460 static void emit_set_ls(void **ptr
, D3DLIGHTSTATETYPE state
, DWORD value
)
462 D3DINSTRUCTION
*inst
= *ptr
;
463 D3DSTATE
*ls
= (D3DSTATE
*)(inst
+ 1);
465 inst
->bOpcode
= D3DOP_STATELIGHT
;
466 inst
->bSize
= sizeof(*ls
);
469 U1(*ls
).dlstLightStateType
= state
;
470 U2(*ls
).dwArg
[0] = value
;
475 static void emit_set_rs(void **ptr
, D3DRENDERSTATETYPE state
, DWORD value
)
477 D3DINSTRUCTION
*inst
= *ptr
;
478 D3DSTATE
*rs
= (D3DSTATE
*)(inst
+ 1);
480 inst
->bOpcode
= D3DOP_STATERENDER
;
481 inst
->bSize
= sizeof(*rs
);
484 U1(*rs
).drstRenderStateType
= state
;
485 U2(*rs
).dwArg
[0] = value
;
490 static void emit_tquad(void **ptr
, WORD base_idx
)
492 D3DINSTRUCTION
*inst
= *ptr
;
493 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
495 inst
->bOpcode
= D3DOP_TRIANGLE
;
496 inst
->bSize
= sizeof(*tri
);
499 U1(*tri
).v1
= base_idx
;
500 U2(*tri
).v2
= base_idx
+ 1;
501 U3(*tri
).v3
= base_idx
+ 2;
502 tri
->wFlags
= D3DTRIFLAG_START
;
505 U1(*tri
).v1
= base_idx
+ 2;
506 U2(*tri
).v2
= base_idx
+ 1;
507 U3(*tri
).v3
= base_idx
+ 3;
508 tri
->wFlags
= D3DTRIFLAG_ODD
;
514 static void emit_tquad_tlist(void **ptr
, WORD base_idx
)
516 D3DINSTRUCTION
*inst
= *ptr
;
517 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
519 inst
->bOpcode
= D3DOP_TRIANGLE
;
520 inst
->bSize
= sizeof(*tri
);
523 U1(*tri
).v1
= base_idx
;
524 U2(*tri
).v2
= base_idx
+ 1;
525 U3(*tri
).v3
= base_idx
+ 2;
526 tri
->wFlags
= D3DTRIFLAG_START
;
529 U1(*tri
).v1
= base_idx
+ 2;
530 U2(*tri
).v2
= base_idx
+ 3;
531 U3(*tri
).v3
= base_idx
;
532 tri
->wFlags
= D3DTRIFLAG_START
;
538 static void emit_tri_indices(void **ptr
, WORD
*indices
, unsigned int primitive_count
)
540 D3DINSTRUCTION
*inst
= *ptr
;
541 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
544 inst
->bOpcode
= D3DOP_TRIANGLE
;
545 inst
->bSize
= sizeof(*tri
);
546 inst
->wCount
= primitive_count
;
548 for (i
= 0; i
< primitive_count
; ++i
)
550 U1(*tri
).v1
= indices
[i
* 3];
551 U2(*tri
).v2
= indices
[i
* 3 + 1];
552 U3(*tri
).v3
= indices
[i
* 3 + 2];
553 tri
->wFlags
= D3DTRIFLAG_START
;
559 static void emit_texture_load(void **ptr
, D3DTEXTUREHANDLE dst_texture
,
560 D3DTEXTUREHANDLE src_texture
)
562 D3DINSTRUCTION
*instruction
= *ptr
;
563 D3DTEXTURELOAD
*texture_load
= (D3DTEXTURELOAD
*)(instruction
+ 1);
565 instruction
->bOpcode
= D3DOP_TEXTURELOAD
;
566 instruction
->bSize
= sizeof(*texture_load
);
567 instruction
->wCount
= 1;
569 texture_load
->hDestTexture
= dst_texture
;
570 texture_load
->hSrcTexture
= src_texture
;
576 static void emit_end(void **ptr
)
578 D3DINSTRUCTION
*inst
= *ptr
;
580 inst
->bOpcode
= D3DOP_EXIT
;
587 static void set_execute_data(IDirect3DExecuteBuffer
*execute_buffer
, UINT vertex_count
, UINT offset
, UINT len
)
589 D3DEXECUTEDATA exec_data
;
592 memset(&exec_data
, 0, sizeof(exec_data
));
593 exec_data
.dwSize
= sizeof(exec_data
);
594 exec_data
.dwVertexCount
= vertex_count
;
595 exec_data
.dwInstructionOffset
= offset
;
596 exec_data
.dwInstructionLength
= len
;
597 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
598 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
601 static DWORD
get_device_z_depth(IDirect3DDevice
*device
)
603 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
604 IDirectDrawSurface
*ds
, *rt
;
608 if (FAILED(IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
)))
611 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
612 IDirectDrawSurface_Release(rt
);
616 desc
.dwSize
= sizeof(desc
);
617 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
618 IDirectDrawSurface_Release(ds
);
622 return U2(desc
).dwZBufferBitDepth
;
625 static IDirectDraw
*create_ddraw(void)
629 if (FAILED(DirectDrawCreate(NULL
, &ddraw
, NULL
)))
635 static IDirect3DDevice
*create_device_ex(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
, const GUID
*device_guid
)
637 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
638 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
639 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
641 static const DWORD z_depths
[] = {16, 32, 24};
642 IDirectDrawSurface
*surface
, *ds
;
643 IDirect3DDevice
*device
= NULL
;
644 DDSURFACEDESC surface_desc
;
648 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, coop_level
);
649 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
651 memset(&surface_desc
, 0, sizeof(surface_desc
));
652 surface_desc
.dwSize
= sizeof(surface_desc
);
653 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
654 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
655 if (is_software_device_type(device_guid
))
656 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
657 surface_desc
.dwWidth
= 640;
658 surface_desc
.dwHeight
= 480;
660 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
661 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
663 if (coop_level
& DDSCL_NORMAL
)
665 IDirectDrawClipper
*clipper
;
667 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
668 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
669 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
670 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
671 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
672 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#lx.\n", hr
);
673 IDirectDrawClipper_Release(clipper
);
676 /* We used to use EnumDevices() for this, but it seems
677 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
678 * relationship with reality. */
679 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
681 memset(&surface_desc
, 0, sizeof(surface_desc
));
682 surface_desc
.dwSize
= sizeof(surface_desc
);
683 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
684 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
685 if (is_software_device_type(device_guid
))
686 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
687 U2(surface_desc
).dwZBufferBitDepth
= z_depths
[i
];
688 surface_desc
.dwWidth
= 640;
689 surface_desc
.dwHeight
= 480;
690 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
693 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
694 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
695 IDirectDrawSurface_Release(ds
);
699 if (SUCCEEDED(IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
)))
702 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
705 IDirectDrawSurface_Release(surface
);
709 static IDirect3DDevice
*create_device(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
)
711 return create_device_ex(ddraw
, window
, coop_level
, &IID_IDirect3DHALDevice
);
714 static IDirect3DViewport
*create_viewport(IDirect3DDevice
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
716 IDirect3DViewport
*viewport
;
721 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
722 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
723 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
724 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
725 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
726 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
727 memset(&vp
, 0, sizeof(vp
));
728 vp
.dwSize
= sizeof(vp
);
733 vp
.dvScaleX
= (float)w
/ 2.0f
;
734 vp
.dvScaleY
= (float)h
/ 2.0f
;
739 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
740 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
741 IDirect3D_Release(d3d
);
746 static void viewport_set_background(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
,
747 IDirect3DMaterial
*material
)
749 D3DMATERIALHANDLE material_handle
;
752 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
753 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
754 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
755 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
758 static void destroy_viewport(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
)
762 hr
= IDirect3DDevice_DeleteViewport(device
, viewport
);
763 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
764 IDirect3DViewport_Release(viewport
);
767 static IDirect3DMaterial
*create_material(IDirect3DDevice
*device
, D3DMATERIAL
*mat
)
769 IDirect3DMaterial
*material
;
773 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
774 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
775 hr
= IDirect3D_CreateMaterial(d3d
, &material
, NULL
);
776 ok(SUCCEEDED(hr
), "Failed to create material, hr %#lx.\n", hr
);
777 hr
= IDirect3DMaterial_SetMaterial(material
, mat
);
778 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
779 IDirect3D_Release(d3d
);
784 static IDirect3DMaterial
*create_diffuse_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
788 memset(&mat
, 0, sizeof(mat
));
789 mat
.dwSize
= sizeof(mat
);
790 U1(U(mat
).diffuse
).r
= r
;
791 U2(U(mat
).diffuse
).g
= g
;
792 U3(U(mat
).diffuse
).b
= b
;
793 U4(U(mat
).diffuse
).a
= a
;
795 return create_material(device
, &mat
);
798 static IDirect3DMaterial
*create_diffuse_and_ambient_material(IDirect3DDevice
*device
,
799 float r
, float g
, float b
, float a
)
803 memset(&mat
, 0, sizeof(mat
));
804 mat
.dwSize
= sizeof(mat
);
805 U1(U(mat
).diffuse
).r
= r
;
806 U2(U(mat
).diffuse
).g
= g
;
807 U3(U(mat
).diffuse
).b
= b
;
808 U4(U(mat
).diffuse
).a
= a
;
810 U1(U(mat
).ambient
).r
= r
;
811 U2(U(mat
).ambient
).g
= g
;
812 U3(U(mat
).ambient
).b
= b
;
813 U4(U(mat
).ambient
).a
= a
;
815 return create_material(device
, &mat
);
818 static IDirect3DMaterial
*create_emissive_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
822 memset(&mat
, 0, sizeof(mat
));
823 mat
.dwSize
= sizeof(mat
);
824 U1(U3(mat
).emissive
).r
= r
;
825 U2(U3(mat
).emissive
).g
= g
;
826 U3(U3(mat
).emissive
).b
= b
;
827 U4(U3(mat
).emissive
).a
= a
;
829 return create_material(device
, &mat
);
832 static IDirect3DMaterial
*create_specular_material(IDirect3DDevice
*device
,
833 float r
, float g
, float b
, float a
, float power
)
837 memset(&mat
, 0, sizeof(mat
));
838 mat
.dwSize
= sizeof(mat
);
839 U1(U2(mat
).specular
).r
= r
;
840 U2(U2(mat
).specular
).g
= g
;
841 U3(U2(mat
).specular
).b
= b
;
842 U4(U2(mat
).specular
).a
= a
;
843 U4(mat
).power
= power
;
845 return create_material(device
, &mat
);
848 static void destroy_material(IDirect3DMaterial
*material
)
850 IDirect3DMaterial_Release(material
);
857 WPARAM expect_wparam
;
860 static const struct message
*expect_messages
;
862 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
864 if (expect_messages
&& message
== expect_messages
->message
)
866 if (expect_messages
->check_wparam
)
867 ok (wparam
== expect_messages
->expect_wparam
,
868 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
869 wparam
, message
, expect_messages
->expect_wparam
);
874 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
877 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
878 * interface. This prevents subsequent SetCooperativeLevel() calls on a
879 * different window from failing with DDERR_HWNDALREADYSET. */
880 static void fix_wndproc(HWND window
, LONG_PTR proc
)
885 if (!(ddraw
= create_ddraw()))
888 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
889 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
890 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
891 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
892 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
894 IDirectDraw_Release(ddraw
);
897 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
899 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
900 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#lx.\n", hr
);
901 IDirectDrawSurface_Release(surface
);
906 static HRESULT
restore_surfaces(IDirectDraw
*ddraw
)
908 return IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
909 NULL
, NULL
, restore_callback
);
912 static void test_coop_level_create_device_window(void)
914 HWND focus_window
, device_window
;
918 focus_window
= create_window();
919 ddraw
= create_ddraw();
920 ok(!!ddraw
, "Failed to create a ddraw object.\n");
922 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
923 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
924 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
925 ok(!device_window
, "Unexpected device window found.\n");
926 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
927 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
928 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
929 ok(!device_window
, "Unexpected device window found.\n");
930 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
931 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
932 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
933 ok(!device_window
, "Unexpected device window found.\n");
934 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
935 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
936 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
937 ok(!device_window
, "Unexpected device window found.\n");
938 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
939 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#lx.\n", hr
);
940 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
941 ok(!device_window
, "Unexpected device window found.\n");
943 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
944 if (broken(hr
== DDERR_INVALIDPARAMS
))
946 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
947 IDirectDraw_Release(ddraw
);
948 DestroyWindow(focus_window
);
952 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
953 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
954 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
955 ok(!device_window
, "Unexpected device window found.\n");
956 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
957 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
958 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
959 ok(!device_window
, "Unexpected device window found.\n");
961 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
962 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
963 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
964 ok(!device_window
, "Unexpected device window found.\n");
965 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
966 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
967 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#lx.\n", hr
);
968 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
969 ok(!!device_window
, "Device window not found.\n");
971 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
972 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
973 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
974 ok(!device_window
, "Unexpected device window found.\n");
975 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
976 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
977 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
978 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
979 ok(!!device_window
, "Device window not found.\n");
981 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
982 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
983 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
984 ok(!device_window
, "Unexpected device window found.\n");
985 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
986 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#lx.\n", hr
);
987 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
988 ok(!device_window
, "Unexpected device window found.\n");
989 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
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");
993 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
994 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
995 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
996 ok(!!device_window
, "Device window not found.\n");
998 IDirectDraw_Release(ddraw
);
999 DestroyWindow(focus_window
);
1002 static void test_clipper_blt(void)
1004 IDirectDrawSurface
*src_surface
, *dst_surface
;
1005 unsigned int color
, i
, j
, x
, y
;
1006 RECT client_rect
, src_rect
;
1007 IDirectDrawClipper
*clipper
;
1008 DDSURFACEDESC surface_desc
;
1019 static const DWORD src_data
[] =
1021 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1022 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1023 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1025 static const unsigned int expected1
[] =
1027 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1028 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1029 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1030 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1032 /* Nvidia on Windows seems to have an off-by-one error
1033 * when processing source rectangles. Our left = 1 and
1034 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
1035 * read as well, but only for the edge pixels on the
1036 * output image. The bug happens on the y axis as well,
1037 * but we only read one row there, and all source rows
1038 * contain the same data. This bug is not dependent on
1039 * the presence of a clipper. */
1040 static const D3DCOLOR expected1_broken
[] =
1042 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1043 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1044 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
1045 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
1047 static const unsigned int expected2
[] =
1049 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1050 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1051 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1052 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1055 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1056 10, 10, 640, 480, 0, 0, 0, 0);
1057 ShowWindow(window
, SW_SHOW
);
1058 ddraw
= create_ddraw();
1059 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1061 ret
= GetClientRect(window
, &client_rect
);
1062 ok(ret
, "Failed to get client rect.\n");
1063 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
1064 ok(ret
, "Failed to map client rect.\n");
1066 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1067 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1069 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
1070 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
1071 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1072 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1073 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1074 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1075 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1076 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1077 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1078 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
1079 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#lx.\n", hr
);
1080 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#lx.\n", rgn_data
->rdh
.dwSize
);
1081 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#lx.\n", rgn_data
->rdh
.iType
);
1082 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %lu.\n", rgn_data
->rdh
.nCount
);
1083 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
1084 "Got unexpected bounding rect %s, expected %s.\n",
1085 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
1086 HeapFree(GetProcessHeap(), 0, rgn_data
);
1088 r1
= CreateRectRgn(0, 0, 320, 240);
1089 ok(!!r1
, "Failed to create region.\n");
1090 r2
= CreateRectRgn(320, 240, 640, 480);
1091 ok(!!r2
, "Failed to create region.\n");
1092 CombineRgn(r1
, r1
, r2
, RGN_OR
);
1093 ret
= GetRegionData(r1
, 0, NULL
);
1094 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
1095 ret
= GetRegionData(r1
, ret
, rgn_data
);
1096 ok(!!ret
, "Failed to get region data.\n");
1101 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1102 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#lx.\n", hr
);
1103 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1104 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1105 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1106 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1108 HeapFree(GetProcessHeap(), 0, rgn_data
);
1110 memset(&surface_desc
, 0, sizeof(surface_desc
));
1111 surface_desc
.dwSize
= sizeof(surface_desc
);
1112 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1113 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1114 surface_desc
.dwWidth
= 640;
1115 surface_desc
.dwHeight
= 480;
1116 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1117 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1118 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1119 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1120 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1121 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1123 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
1124 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
1125 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
1126 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
1128 memset(&fx
, 0, sizeof(fx
));
1129 fx
.dwSize
= sizeof(fx
);
1130 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1131 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
1132 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1133 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1135 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
1136 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
1137 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %lu.\n", U1(surface_desc
).lPitch
);
1138 ptr
= surface_desc
.lpSurface
;
1139 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
1140 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
1141 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
1142 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
1143 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
1145 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
1146 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
1148 SetRect(&src_rect
, 1, 1, 5, 2);
1149 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
1150 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
1151 for (i
= 0; i
< 4; ++i
)
1153 for (j
= 0; j
< 4; ++j
)
1155 x
= 80 * ((2 * j
) + 1);
1156 y
= 60 * ((2 * i
) + 1);
1157 color
= get_surface_color(dst_surface
, x
, y
);
1158 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1159 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1160 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1164 U5(fx
).dwFillColor
= 0xff0000ff;
1165 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1166 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1167 for (i
= 0; i
< 4; ++i
)
1169 for (j
= 0; j
< 4; ++j
)
1171 x
= 80 * ((2 * j
) + 1);
1172 y
= 60 * ((2 * i
) + 1);
1173 color
= get_surface_color(dst_surface
, x
, y
);
1174 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1175 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1179 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1180 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#lx.\n", hr
);
1182 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1183 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1184 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1185 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1186 DestroyWindow(window
);
1187 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1188 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
1189 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1190 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1191 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1192 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1193 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1194 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1195 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1196 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1197 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1198 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1200 IDirectDrawSurface_Release(dst_surface
);
1201 IDirectDrawSurface_Release(src_surface
);
1202 refcount
= IDirectDrawClipper_Release(clipper
);
1203 ok(!refcount
, "Clipper has %lu references left.\n", refcount
);
1204 IDirectDraw_Release(ddraw
);
1207 static void test_coop_level_d3d_state(void)
1209 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1210 IDirectDrawSurface
*rt
, *surface
;
1211 IDirect3DMaterial
*background
;
1212 IDirect3DViewport
*viewport
;
1213 IDirect3DDevice
*device
;
1214 D3DMATERIAL material
;
1221 window
= create_window();
1222 ddraw
= create_ddraw();
1223 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1224 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1226 skip("Failed to create a 3D device, skipping test.\n");
1227 IDirectDraw_Release(ddraw
);
1228 DestroyWindow(window
);
1232 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1233 viewport
= create_viewport(device
, 0, 0, 640, 480);
1234 viewport_set_background(device
, viewport
, background
);
1236 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1237 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1238 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1239 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1240 color
= get_surface_color(rt
, 320, 240);
1241 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1243 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1244 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1245 hr
= IDirectDrawSurface_IsLost(rt
);
1246 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1248 memset(&lock
, 0, sizeof(lock
));
1249 lock
.dwSize
= sizeof(lock
);
1250 lock
.lpSurface
= (void *)0xdeadbeef;
1251 hr
= IDirectDrawSurface_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1252 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1253 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1255 hr
= restore_surfaces(ddraw
);
1256 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1258 hr
= IDirectDrawSurface_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1259 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1260 hr
= IDirectDrawSurface2_Unlock(rt
, NULL
);
1261 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1263 memset(&material
, 0, sizeof(material
));
1264 material
.dwSize
= sizeof(material
);
1265 U1(U(material
).diffuse
).r
= 0.0f
;
1266 U2(U(material
).diffuse
).g
= 1.0f
;
1267 U3(U(material
).diffuse
).b
= 0.0f
;
1268 U4(U(material
).diffuse
).a
= 1.0f
;
1269 hr
= IDirect3DMaterial_SetMaterial(background
, &material
);
1270 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1272 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&surface
);
1273 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1274 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1275 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1276 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1277 color
= get_surface_color(rt
, 320, 240);
1278 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1279 "Got unexpected color 0x%08x.\n", color
);
1281 destroy_viewport(device
, viewport
);
1282 destroy_material(background
);
1283 IDirectDrawSurface_Release(surface
);
1284 IDirectDrawSurface_Release(rt
);
1285 IDirect3DDevice_Release(device
);
1286 IDirectDraw_Release(ddraw
);
1287 DestroyWindow(window
);
1290 static void test_surface_interface_mismatch(void)
1292 IDirectDraw
*ddraw
= NULL
;
1293 IDirectDrawSurface
*surface
= NULL
, *ds
;
1294 IDirectDrawSurface3
*surface3
= NULL
;
1295 IDirect3DDevice
*device
= NULL
;
1296 IDirect3DViewport
*viewport
= NULL
;
1297 IDirect3DMaterial
*background
= NULL
;
1298 DDSURFACEDESC surface_desc
;
1304 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1306 window
= create_window();
1307 ddraw
= create_ddraw();
1308 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1309 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1311 skip("Failed to create a 3D device, skipping test.\n");
1312 IDirectDraw_Release(ddraw
);
1313 DestroyWindow(window
);
1316 z_depth
= get_device_z_depth(device
);
1317 ok(!!z_depth
, "Failed to get device z depth.\n");
1318 IDirect3DDevice_Release(device
);
1321 memset(&surface_desc
, 0, sizeof(surface_desc
));
1322 surface_desc
.dwSize
= sizeof(surface_desc
);
1323 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1324 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1325 surface_desc
.dwWidth
= 640;
1326 surface_desc
.dwHeight
= 480;
1328 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1329 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
1331 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1334 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1338 memset(&surface_desc
, 0, sizeof(surface_desc
));
1339 surface_desc
.dwSize
= sizeof(surface_desc
);
1340 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1341 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1342 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
1343 surface_desc
.dwWidth
= 640;
1344 surface_desc
.dwHeight
= 480;
1345 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1346 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
1350 /* Using a different surface interface version still works */
1351 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1352 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
1353 refcount
= IDirectDrawSurface_Release(ds
);
1354 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
1359 hr
= IDirectDrawSurface3_QueryInterface(surface3
, &IID_IDirect3DHALDevice
, (void **)&device
);
1360 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1364 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1365 viewport
= create_viewport(device
, 0, 0, 640, 480);
1366 viewport_set_background(device
, viewport
, background
);
1368 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1369 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
1370 color
= get_surface_color(surface
, 320, 240);
1371 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1375 destroy_viewport(device
, viewport
);
1377 destroy_material(background
);
1378 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1379 if (surface
) IDirectDrawSurface_Release(surface
);
1380 if (device
) IDirect3DDevice_Release(device
);
1381 if (ddraw
) IDirectDraw_Release(ddraw
);
1382 DestroyWindow(window
);
1385 static void test_coop_level_threaded(void)
1387 struct create_window_thread_param p
;
1391 ddraw
= create_ddraw();
1392 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1393 create_window_thread(&p
);
1395 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1396 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1398 destroy_window_thread(&p
);
1399 IDirectDraw_Release(ddraw
);
1402 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1404 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1405 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1406 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1407 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1410 static ULONG
get_refcount(IUnknown
*test_iface
)
1412 IUnknown_AddRef(test_iface
);
1413 return IUnknown_Release(test_iface
);
1416 static void test_viewport_object(void)
1418 IDirect3DViewport
*viewport
, *another_vp
;
1419 IDirectDrawGammaControl
*gamma
;
1420 IDirect3DViewport2
*viewport2
;
1421 IDirect3DViewport3
*viewport3
;
1422 IDirect3DDevice
*device
;
1437 window
= create_window();
1438 ddraw
= create_ddraw();
1439 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1440 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1442 skip("Failed to create a 3D device, skipping test.\n");
1443 IDirectDraw_Release(ddraw
);
1444 DestroyWindow(window
);
1448 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
1449 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1450 ref
= get_refcount((IUnknown
*) d3d
);
1451 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1453 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
1454 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1455 ref
= get_refcount((IUnknown
*)viewport
);
1456 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1457 ref
= get_refcount((IUnknown
*)d3d
);
1458 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1460 memset(&desc
, 0, sizeof(desc
));
1461 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1462 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1463 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1464 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1465 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1466 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1467 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1468 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1469 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1470 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1471 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1472 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %lu.\n", desc
.vp1
.dwSize
);
1474 /* E_FAIL return values are returned by Winetestbot Windows NT machines. While not supporting
1475 * newer interfaces is legitimate for old ddraw versions, E_FAIL violates Microsoft's rules
1476 * for QueryInterface, hence the broken() */
1477 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1478 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1479 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
1480 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1482 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport2
, (void **)&viewport2
);
1483 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1485 ref
= get_refcount((IUnknown
*)viewport
);
1486 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1487 ref
= get_refcount((IUnknown
*)viewport2
);
1488 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1490 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1491 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1493 ref
= get_refcount((IUnknown
*)viewport
);
1494 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1495 ref
= get_refcount((IUnknown
*)viewport3
);
1496 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1497 IDirect3DViewport3_Release(viewport3
);
1499 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IUnknown
, (void **)&unknown
);
1500 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1501 ref
= get_refcount((IUnknown
*)viewport
);
1502 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1503 ref
= get_refcount(unknown
);
1504 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1505 IUnknown_Release(unknown
);
1507 hr
= IDirect3DDevice_DeleteViewport(device
, NULL
);
1508 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1510 hr
= IDirect3D_CreateViewport(d3d
, &another_vp
, NULL
);
1511 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1513 /* AddViewport(NULL): Segfault */
1514 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
1515 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1516 ref
= get_refcount((IUnknown
*) viewport
);
1517 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1518 hr
= IDirect3DDevice_AddViewport(device
, another_vp
);
1519 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1520 ref
= get_refcount((IUnknown
*) another_vp
);
1521 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1523 memset(&vp
, 0, sizeof(vp
));
1530 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1531 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1534 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1535 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1537 vp
.dwSize
= sizeof(vp
);
1538 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1539 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1541 vp2
.dwSize
= sizeof(vp2
);
1544 vp2
.dwWidth
= 640 - vp2
.dwX
;
1545 vp2
.dwHeight
= 480 - vp2
.dwY
;
1547 vp2
.dvClipY
= -1.75f
;
1548 vp2
.dvClipWidth
= 2.5f
;
1549 vp2
.dvClipHeight
= -1.5f
;
1552 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1553 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1555 memset(&vp
, 0xff, sizeof(vp
));
1556 vp
.dwSize
= sizeof(vp
);
1557 hr
= IDirect3DViewport2_GetViewport(viewport2
, &vp
);
1558 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1559 ok(vp
.dvMaxX
== 4.5f
&& vp
.dvMaxY
== -1.75f
&& vp
.dvScaleX
== 192.0f
1560 && vp
.dvScaleY
== -240.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
1561 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1562 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
1564 vp2
.dvClipX
= -1.5f
;
1565 vp2
.dvClipY
= 1.75f
;
1566 vp2
.dvClipWidth
= -1.5f
;
1567 vp2
.dvClipHeight
= 2.0f
;
1571 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1572 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1574 memset(&vp
, 0xff, sizeof(vp
));
1575 vp
.dwSize
= sizeof(vp
);
1576 hr
= IDirect3DViewport2_GetViewport(viewport2
, &vp
);
1577 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1578 ok(vp
.dvMaxX
== -3.0f
&& vp
.dvMaxY
== 1.75f
&& vp
.dvScaleX
== -320.0f
1579 && vp
.dvScaleY
== 180.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
1580 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1581 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
1583 vp
.dwSize
= sizeof(vp
);
1586 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1587 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1589 memset(&vp2
, 0xff, sizeof(vp2
));
1590 vp2
.dwSize
= sizeof(vp2
);
1591 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &vp2
);
1592 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1593 ok(vp2
.dvClipX
== 0.75f
&& vp2
.dvClipY
== 1.0f
&& vp2
.dvClipWidth
== -1.5f
1594 && vp2
.dvClipHeight
== 2.0f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
1595 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1596 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
1600 vp
.dvScaleX
= 192.0f
;
1601 vp
.dvScaleY
= -240.0f
;
1605 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1606 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1608 memset(&vp2
, 0xff, sizeof(vp2
));
1609 vp2
.dwSize
= sizeof(vp2
);
1610 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &vp2
);
1611 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1612 ok(vp2
.dvClipX
== -1.25f
&& vp2
.dvClipY
== -0.75f
&& vp2
.dvClipWidth
== 2.5f
1613 && vp2
.dvClipHeight
== -1.5f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
1614 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1615 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
1617 IDirect3DViewport2_Release(viewport2
);
1619 hr
= IDirect3DDevice_DeleteViewport(device
, another_vp
);
1620 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1621 ref
= get_refcount((IUnknown
*) another_vp
);
1622 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1624 IDirect3DDevice_Release(device
);
1625 ref
= get_refcount((IUnknown
*) viewport
);
1626 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1628 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1629 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1631 IDirect3DViewport_Release(another_vp
);
1632 IDirect3D_Release(d3d
);
1633 IDirect3DViewport_Release(viewport
);
1634 DestroyWindow(window
);
1635 IDirectDraw_Release(ddraw
);
1638 static void test_zenable(const GUID
*device_guid
)
1640 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1641 static D3DTLVERTEX tquad
[] =
1643 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1644 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1645 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1646 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1648 unsigned int inst_length
, color
, x
, y
, i
, j
;
1649 IDirect3DExecuteBuffer
*execute_buffer
;
1650 D3DEXECUTEBUFFERDESC exec_desc
;
1651 IDirect3DMaterial
*background
;
1652 IDirect3DViewport
*viewport
;
1653 IDirect3DDevice
*device
;
1654 IDirectDrawSurface
*rt
;
1660 window
= create_window();
1661 ddraw
= create_ddraw();
1662 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1663 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1665 skip("Failed to create a 3D device, skipping test.\n");
1666 IDirectDraw_Release(ddraw
);
1667 DestroyWindow(window
);
1671 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1672 viewport
= create_viewport(device
, 0, 0, 640, 480);
1673 viewport_set_background(device
, viewport
, background
);
1675 memset(&exec_desc
, 0, sizeof(exec_desc
));
1676 exec_desc
.dwSize
= sizeof(exec_desc
);
1677 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1678 exec_desc
.dwBufferSize
= 1024;
1679 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1681 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1682 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
1683 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1684 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
1685 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1686 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1687 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1688 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1689 emit_tquad(&ptr
, 0);
1691 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
1692 inst_length
-= sizeof(tquad
);
1693 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1694 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1696 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1697 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1698 hr
= IDirect3DDevice_BeginScene(device
);
1699 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1700 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
1701 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1702 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1703 hr
= IDirect3DDevice_EndScene(device
);
1704 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1706 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1707 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1708 for (i
= 0; i
< 4; ++i
)
1710 for (j
= 0; j
< 4; ++j
)
1712 x
= 80 * ((2 * j
) + 1);
1713 y
= 60 * ((2 * i
) + 1);
1714 color
= get_surface_color(rt
, x
, y
);
1715 ok(compare_color(color
, 0x0000ff00, 1),
1716 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1719 IDirectDrawSurface_Release(rt
);
1721 destroy_viewport(device
, viewport
);
1722 IDirect3DExecuteBuffer_Release(execute_buffer
);
1723 destroy_material(background
);
1724 IDirect3DDevice_Release(device
);
1725 IDirectDraw_Release(ddraw
);
1726 DestroyWindow(window
);
1729 static void test_ck_rgba(const GUID
*device_guid
)
1731 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1732 static D3DTLVERTEX tquad
[] =
1734 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1735 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1736 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1737 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1738 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1739 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1740 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1741 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1743 /* Supposedly there was no D3DRENDERSTATE_COLORKEYENABLE in D3D < 5.
1744 * Maybe the WARP driver on Windows 8 ignores setting it via the older
1745 * device interface but it's buggy in that the internal state is not
1746 * initialized, or possibly toggling D3DRENDERSTATE_COLORKEYENABLE /
1747 * D3DRENDERSTATE_ALPHABLENDENABLE has unintended side effects.
1748 * Checking the W8 test results it seems like test 1 fails most of the time
1749 * and test 0 fails very rarely. */
1752 D3DCOLOR fill_color
;
1755 unsigned int result1
, result1_r200
, result1_warp
;
1756 unsigned int result2
, result2_r200
, result2_warp
;
1760 /* r200 on Windows doesn't check the alpha component when applying the color
1761 * key, so the key matches on every texel. */
1762 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1763 0x000000ff, 0x000000ff, 0x0000ff00},
1764 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1765 0x000000ff, 0x000000ff, 0x0000ff00},
1766 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1767 0x0000ff00, 0x0000ff00, 0x0000ff00},
1768 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1769 0x0000ff00, 0x0000ff00, 0x0000ff00},
1770 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00,
1771 0x00807f00, 0x000000ff, 0x00807f00},
1772 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00,
1773 0x0000ff00, 0x000000ff, 0x0000ff00},
1774 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00,
1775 0x00807f00, 0x00807f00, 0x00807f00},
1776 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1777 0x0000ff00, 0x0000ff00, 0x0000ff00},
1780 IDirect3DExecuteBuffer
*execute_buffer
;
1781 D3DTEXTUREHANDLE texture_handle
;
1782 D3DEXECUTEBUFFERDESC exec_desc
;
1783 IDirect3DMaterial
*background
;
1784 IDirectDrawSurface
*surface
;
1785 IDirect3DViewport
*viewport
;
1786 DDSURFACEDESC surface_desc
;
1787 IDirect3DTexture
*texture
;
1788 IDirect3DDevice
*device
;
1789 IDirectDrawSurface
*rt
;
1790 unsigned int color
, i
;
1796 window
= create_window();
1797 ddraw
= create_ddraw();
1798 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1799 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1801 skip("Failed to create a 3D device, skipping test.\n");
1802 IDirectDraw_Release(ddraw
);
1803 DestroyWindow(window
);
1807 background
= create_diffuse_material(device
, 1.0, 0.0f
, 0.0f
, 1.0f
);
1808 viewport
= create_viewport(device
, 0, 0, 640, 480);
1809 viewport_set_background(device
, viewport
, background
);
1811 memset(&surface_desc
, 0, sizeof(surface_desc
));
1812 surface_desc
.dwSize
= sizeof(surface_desc
);
1813 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1814 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1815 if (is_software_device_type(device_guid
))
1816 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1817 surface_desc
.dwWidth
= 256;
1818 surface_desc
.dwHeight
= 256;
1819 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1820 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1821 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1822 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1823 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1824 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1825 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1826 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1827 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1828 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1829 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1830 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1831 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1832 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1833 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1834 IDirect3DTexture_Release(texture
);
1836 memset(&exec_desc
, 0, sizeof(exec_desc
));
1837 exec_desc
.dwSize
= sizeof(exec_desc
);
1838 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1839 exec_desc
.dwBufferSize
= 1024;
1840 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1841 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1842 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1844 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1845 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1847 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1849 UINT draw1_len
, draw2_len
;
1852 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1853 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1854 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1855 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1856 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1857 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1858 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1859 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1860 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1862 if (is_software_device_type(device_guid
))
1864 /* It looks like D3DRENDERSTATE_COLORKEYENABLE is ignored with software device
1865 * on Windows and the colour key is always enabled if set on surface. */
1866 IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, tests
[i
].color_key
1867 ? &surface_desc
.ddckCKSrcBlt
: NULL
);
1870 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1871 emit_tquad(&ptr
, 0);
1873 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
1874 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 4, 4);
1875 emit_tquad(&ptr
, 0);
1876 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1878 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_len
;
1879 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1880 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1882 memset(&fx
, 0, sizeof(fx
));
1883 fx
.dwSize
= sizeof(fx
);
1884 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1885 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1886 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1888 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1889 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1890 /* RT clears are broken on Windows for software render target. */
1891 if (is_software_device_type(device_guid
))
1892 fill_surface(rt
, 0xffff0000);
1894 hr
= IDirect3DDevice_BeginScene(device
);
1895 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1896 set_execute_data(execute_buffer
, 8, sizeof(tquad
), draw1_len
);
1897 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1898 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1899 hr
= IDirect3DDevice_EndScene(device
);
1900 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1902 color
= get_surface_color(rt
, 320, 240);
1903 ok(compare_color(color
, tests
[i
].result1
, 2)
1904 || broken(compare_color(color
, tests
[i
].result1_r200
, 1))
1905 || broken(compare_color(color
, tests
[i
].result1_warp
, 1)),
1906 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1908 U5(fx
).dwFillColor
= 0xff0000ff;
1909 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1910 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1912 hr
= IDirect3DDevice_BeginScene(device
);
1913 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1914 set_execute_data(execute_buffer
, 8, sizeof(tquad
) + draw1_len
, draw2_len
);
1915 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1916 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1917 hr
= IDirect3DDevice_EndScene(device
);
1918 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1920 /* This tests that fragments that are masked out by the color key are
1921 * discarded, instead of just fully transparent. */
1922 color
= get_surface_color(rt
, 320, 240);
1923 ok(compare_color(color
, tests
[i
].result2
, 2)
1924 || broken(compare_color(color
, tests
[i
].result2_r200
, 1))
1925 || broken(compare_color(color
, tests
[i
].result2_warp
, 1)),
1926 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1929 IDirectDrawSurface_Release(rt
);
1930 IDirect3DExecuteBuffer_Release(execute_buffer
);
1931 IDirectDrawSurface_Release(surface
);
1932 destroy_viewport(device
, viewport
);
1933 destroy_material(background
);
1934 IDirect3DDevice_Release(device
);
1935 IDirectDraw_Release(ddraw
);
1936 DestroyWindow(window
);
1939 static void test_ck_default(void)
1941 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1942 static D3DTLVERTEX tquad
[] =
1944 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1945 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1946 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1947 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1949 IDirect3DExecuteBuffer
*execute_buffer
;
1950 IDirectDrawSurface
*surface
, *rt
;
1951 D3DTEXTUREHANDLE texture_handle
;
1952 D3DEXECUTEBUFFERDESC exec_desc
;
1953 IDirect3DMaterial
*background
;
1954 UINT draw1_offset
, draw1_len
;
1955 UINT draw2_offset
, draw2_len
;
1956 UINT draw3_offset
, draw3_len
;
1957 UINT draw4_offset
, draw4_len
;
1958 IDirect3DViewport
*viewport
;
1959 DDSURFACEDESC surface_desc
;
1960 IDirect3DTexture
*texture
;
1961 IDirect3DDevice
*device
;
1969 window
= create_window();
1970 ddraw
= create_ddraw();
1971 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1972 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1974 skip("Failed to create a 3D device, skipping test.\n");
1975 IDirectDraw_Release(ddraw
);
1976 DestroyWindow(window
);
1980 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1981 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
1983 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1984 viewport
= create_viewport(device
, 0, 0, 640, 480);
1985 viewport_set_background(device
, viewport
, background
);
1987 memset(&surface_desc
, 0, sizeof(surface_desc
));
1988 surface_desc
.dwSize
= sizeof(surface_desc
);
1989 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1990 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1991 surface_desc
.dwWidth
= 256;
1992 surface_desc
.dwHeight
= 256;
1993 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1994 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1995 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1996 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1997 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1998 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1999 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2000 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2001 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2002 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2003 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
2004 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
2005 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
2006 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
2007 IDirect3DTexture_Release(texture
);
2009 memset(&fx
, 0, sizeof(fx
));
2010 fx
.dwSize
= sizeof(fx
);
2011 U5(fx
).dwFillColor
= 0x000000ff;
2012 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2013 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
2015 memset(&exec_desc
, 0, sizeof(exec_desc
));
2016 exec_desc
.dwSize
= sizeof(exec_desc
);
2017 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
2018 exec_desc
.dwBufferSize
= 1024;
2019 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
2020 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
2021 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
2023 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
2024 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
2025 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
2026 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
2027 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2028 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2029 emit_tquad(&ptr
, 0);
2031 draw1_offset
= sizeof(tquad
);
2032 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_offset
;
2033 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2034 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
2035 emit_tquad(&ptr
, 0);
2037 draw2_offset
= draw1_offset
+ draw1_len
;
2038 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw2_offset
;
2039 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2040 emit_tquad(&ptr
, 0);
2042 draw3_offset
= draw2_offset
+ draw2_len
;
2043 draw3_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw3_offset
;
2044 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2045 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2046 emit_tquad(&ptr
, 0);
2047 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2049 draw4_offset
= draw3_offset
+ draw3_len
;
2050 draw4_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw4_offset
;
2051 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
2052 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
2054 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2055 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2056 hr
= IDirect3DDevice_BeginScene(device
);
2057 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2058 set_execute_data(execute_buffer
, 4, draw1_offset
, draw1_len
);
2059 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2060 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2061 hr
= IDirect3DDevice_EndScene(device
);
2062 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2063 color
= get_surface_color(rt
, 320, 240);
2064 /* Color keying is supposed to be on by default in ddraw1, but used only if a ckey is set.
2065 * WARP begs to differ. The default of D3DRENDERSTATE_COLORKEYENABLE is random, and it
2066 * doesn't mind the absence of a color key (the latter part affects other tests, not this one). */
2067 ok(compare_color(color
, 0x0000ff00, 1) || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x000000ff, 1)),
2068 "Got unexpected color 0x%08x.\n", color
);
2070 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2071 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2072 hr
= IDirect3DDevice_BeginScene(device
);
2073 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2074 set_execute_data(execute_buffer
, 4, draw2_offset
, draw2_len
);
2075 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2076 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2077 hr
= IDirect3DDevice_EndScene(device
);
2078 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2079 color
= get_surface_color(rt
, 320, 240);
2080 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2082 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2083 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2084 hr
= IDirect3DDevice_BeginScene(device
);
2085 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2086 set_execute_data(execute_buffer
, 4, draw3_offset
, draw3_len
);
2087 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2088 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2089 hr
= IDirect3DDevice_EndScene(device
);
2090 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2091 color
= get_surface_color(rt
, 320, 240);
2092 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2094 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2095 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2096 hr
= IDirect3DDevice_BeginScene(device
);
2097 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2098 set_execute_data(execute_buffer
, 4, draw4_offset
, draw4_len
);
2099 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2100 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2101 hr
= IDirect3DDevice_EndScene(device
);
2102 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2103 color
= get_surface_color(rt
, 320, 240);
2104 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2106 IDirect3DExecuteBuffer_Release(execute_buffer
);
2107 IDirectDrawSurface_Release(surface
);
2108 destroy_viewport(device
, viewport
);
2109 destroy_material(background
);
2110 IDirectDrawSurface_Release(rt
);
2111 IDirect3DDevice_Release(device
);
2112 IDirectDraw_Release(ddraw
);
2113 DestroyWindow(window
);
2116 static void test_ck_complex(void)
2118 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
2119 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
2120 DDSURFACEDESC surface_desc
;
2121 IDirect3DDevice
*device
;
2122 DDCOLORKEY color_key
;
2129 window
= create_window();
2130 ddraw
= create_ddraw();
2131 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2132 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2134 skip("Failed to create a 3D device, skipping test.\n");
2135 DestroyWindow(window
);
2136 IDirectDraw_Release(ddraw
);
2139 IDirect3DDevice_Release(device
);
2141 memset(&surface_desc
, 0, sizeof(surface_desc
));
2142 surface_desc
.dwSize
= sizeof(surface_desc
);
2143 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2144 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2145 surface_desc
.dwWidth
= 128;
2146 surface_desc
.dwHeight
= 128;
2147 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2148 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2150 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2151 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2152 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2153 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2154 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2155 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2156 memset(&color_key
, 0, sizeof(color_key
));
2157 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2158 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2159 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2160 color_key
.dwColorSpaceLowValue
);
2161 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2162 color_key
.dwColorSpaceHighValue
);
2165 IDirectDrawSurface_AddRef(mipmap
);
2166 for (i
= 0; i
< 7; ++i
)
2168 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2169 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
2171 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2172 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2173 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2174 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2175 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2176 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx, i %u.\n", hr
, i
);
2177 memset(&color_key
, 0, sizeof(color_key
));
2178 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2179 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx, i %u.\n", hr
, i
);
2180 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2181 color_key
.dwColorSpaceLowValue
, i
);
2182 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2183 color_key
.dwColorSpaceHighValue
, i
);
2185 IDirectDrawSurface_Release(mipmap
);
2189 memset(&color_key
, 0, sizeof(color_key
));
2190 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2191 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2192 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2193 color_key
.dwColorSpaceLowValue
);
2194 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2195 color_key
.dwColorSpaceHighValue
);
2197 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2198 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
2199 IDirectDrawSurface_Release(mipmap
);
2200 refcount
= IDirectDrawSurface_Release(surface
);
2201 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2203 memset(&surface_desc
, 0, sizeof(surface_desc
));
2204 surface_desc
.dwSize
= sizeof(surface_desc
);
2205 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2206 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2207 surface_desc
.dwBackBufferCount
= 1;
2208 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2209 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2211 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2212 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2213 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2214 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2215 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2216 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2217 memset(&color_key
, 0, sizeof(color_key
));
2218 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2219 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2220 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2221 color_key
.dwColorSpaceLowValue
);
2222 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2223 color_key
.dwColorSpaceHighValue
);
2225 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2226 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
2228 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2229 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2230 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2231 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2232 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2233 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2234 memset(&color_key
, 0, sizeof(color_key
));
2235 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2236 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2237 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2238 color_key
.dwColorSpaceLowValue
);
2239 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2240 color_key
.dwColorSpaceHighValue
);
2242 IDirectDrawSurface_Release(tmp
);
2244 refcount
= IDirectDrawSurface_Release(surface
);
2245 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2246 refcount
= IDirectDraw_Release(ddraw
);
2247 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2248 DestroyWindow(window
);
2254 REFIID refcount_iid
;
2258 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2259 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2261 ULONG refcount
, expected_refcount
;
2262 IUnknown
*iface1
, *iface2
;
2266 for (i
= 0; i
< entry_count
; ++i
)
2268 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2269 ok(hr
== tests
[i
].hr
, "Got hr %#lx for test \"%s\" %u.\n", hr
, test_name
, i
);
2272 for (j
= 0; j
< entry_count
; ++j
)
2274 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2275 ok(hr
== tests
[j
].hr
, "Got hr %#lx for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2278 expected_refcount
= 0;
2279 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2280 ++expected_refcount
;
2281 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2282 ++expected_refcount
;
2283 refcount
= IUnknown_Release(iface2
);
2284 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
2285 refcount
, test_name
, i
, j
, expected_refcount
);
2289 expected_refcount
= 0;
2290 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2291 ++expected_refcount
;
2292 refcount
= IUnknown_Release(iface1
);
2293 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
2294 refcount
, test_name
, i
, expected_refcount
);
2299 static void test_surface_qi(void)
2301 static const struct qi_test tests
[] =
2303 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2304 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2305 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2306 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2307 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2308 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2309 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2310 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2311 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2312 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2313 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2314 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2315 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2316 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2317 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2318 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2319 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2320 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2321 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2322 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2323 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2324 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2325 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2326 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2327 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2328 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2329 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2330 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2331 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2332 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2333 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2334 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2335 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2336 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2337 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2338 {NULL
, NULL
, E_INVALIDARG
},
2341 IDirectDrawSurface
*surface
;
2342 DDSURFACEDESC surface_desc
;
2343 IDirect3DDevice
*device
;
2348 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2350 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2354 window
= create_window();
2355 ddraw
= create_ddraw();
2356 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2357 /* Try to create a D3D device to see if the ddraw implementation supports
2358 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2359 * doesn't support e.g. the IDirect3DTexture interfaces. */
2360 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2362 skip("Failed to create a 3D device, skipping test.\n");
2363 IDirectDraw_Release(ddraw
);
2364 DestroyWindow(window
);
2367 IDirect3DDevice_Release(device
);
2369 memset(&surface_desc
, 0, sizeof(surface_desc
));
2370 surface_desc
.dwSize
= sizeof(surface_desc
);
2371 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2372 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2373 surface_desc
.dwWidth
= 512;
2374 surface_desc
.dwHeight
= 512;
2375 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2376 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
2377 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2378 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2380 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2382 IDirectDrawSurface_Release(surface
);
2383 IDirectDraw_Release(ddraw
);
2384 DestroyWindow(window
);
2387 static void test_device_qi(void)
2389 static const struct qi_test tests
[] =
2391 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2392 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2393 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2394 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2395 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2396 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2397 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2398 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2399 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2400 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2401 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2402 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2403 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2404 {&IID_IDirect3DHALDevice
, &IID_IDirectDrawSurface
, S_OK
},
2405 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2406 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2407 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2408 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2409 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2410 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2411 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2412 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2413 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2414 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2415 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2416 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2417 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2418 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2419 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2420 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2421 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2422 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2423 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2424 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2425 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2426 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2430 IDirect3DDevice
*device
;
2434 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2436 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2440 window
= create_window();
2441 ddraw
= create_ddraw();
2442 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2443 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2445 skip("Failed to create a 3D device, skipping test.\n");
2446 IDirectDraw_Release(ddraw
);
2447 DestroyWindow(window
);
2451 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2453 IDirect3DDevice_Release(device
);
2454 IDirectDraw_Release(ddraw
);
2455 DestroyWindow(window
);
2458 static void test_wndproc(void)
2460 LONG_PTR proc
, ddraw_proc
;
2467 static struct message messages
[] =
2469 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2470 {WM_MOVE
, FALSE
, 0},
2471 {WM_SIZE
, FALSE
, 0},
2472 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2473 {WM_ACTIVATE
, FALSE
, 0},
2474 {WM_SETFOCUS
, FALSE
, 0},
2478 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2479 ddraw
= create_ddraw();
2480 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2482 wc
.lpfnWndProc
= test_proc
;
2483 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2484 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2486 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2487 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2489 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2490 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2491 (LONG_PTR
)test_proc
, proc
);
2492 expect_messages
= messages
;
2493 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2494 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2495 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2496 expect_messages
= NULL
;
2497 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2498 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2499 (LONG_PTR
)test_proc
, proc
);
2500 ref
= IDirectDraw_Release(ddraw
);
2501 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2502 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2503 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2504 (LONG_PTR
)test_proc
, proc
);
2506 /* DDSCL_NORMAL doesn't. */
2507 ddraw
= create_ddraw();
2508 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2509 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2510 (LONG_PTR
)test_proc
, proc
);
2511 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2512 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2513 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2514 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2515 (LONG_PTR
)test_proc
, proc
);
2516 ref
= IDirectDraw_Release(ddraw
);
2517 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2518 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2519 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2520 (LONG_PTR
)test_proc
, proc
);
2522 /* The original window proc is only restored by ddraw if the current
2523 * window proc matches the one ddraw set. This also affects switching
2524 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2525 ddraw
= create_ddraw();
2526 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2527 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2528 (LONG_PTR
)test_proc
, proc
);
2529 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2530 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2531 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2532 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2533 (LONG_PTR
)test_proc
, proc
);
2535 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2536 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2537 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2538 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2539 (LONG_PTR
)test_proc
, proc
);
2540 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2541 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2542 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2543 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2544 (LONG_PTR
)test_proc
, proc
);
2545 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2546 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2547 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2548 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2549 (LONG_PTR
)DefWindowProcA
, proc
);
2550 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2551 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2552 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2553 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2554 (LONG_PTR
)DefWindowProcA
, proc
);
2555 ref
= IDirectDraw_Release(ddraw
);
2556 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2557 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2558 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2559 (LONG_PTR
)test_proc
, proc
);
2561 ddraw
= create_ddraw();
2562 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2563 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2564 (LONG_PTR
)test_proc
, proc
);
2565 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2566 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2567 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2568 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2569 (LONG_PTR
)test_proc
, proc
);
2570 ref
= IDirectDraw_Release(ddraw
);
2571 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2572 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2573 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2574 (LONG_PTR
)DefWindowProcA
, proc
);
2576 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2577 expect_messages
= NULL
;
2578 DestroyWindow(window
);
2579 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2582 static void test_window_style(void)
2584 LONG style
, exstyle
, tmp
, expected_style
;
2585 RECT fullscreen_rect
, r
;
2586 HWND window
, window2
;
2592 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2593 0, 0, 100, 100, 0, 0, 0, 0);
2594 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2595 0, 0, 50, 50, 0, 0, 0, 0);
2596 ddraw
= create_ddraw();
2597 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2599 style
= GetWindowLongA(window
, GWL_STYLE
);
2600 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2601 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2603 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2604 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2606 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2607 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2608 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2609 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2611 GetWindowRect(window
, &r
);
2612 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2613 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2614 GetClientRect(window
, &r
);
2615 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2617 ret
= SetForegroundWindow(GetDesktopWindow());
2618 ok(ret
, "Failed to set foreground window.\n");
2620 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2621 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2622 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2623 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2625 ret
= SetForegroundWindow(window
);
2626 ok(ret
, "Failed to set foreground window.\n");
2627 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2628 * the next tests expect this. */
2629 ShowWindow(window
, SW_HIDE
);
2631 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2632 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2634 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2635 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2636 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2637 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2639 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2640 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2642 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2643 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2644 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2645 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2647 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2648 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2650 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2651 expected_style
= style
| WS_VISIBLE
;
2652 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2653 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2654 expected_style
= exstyle
| WS_EX_TOPMOST
;
2655 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2657 ShowWindow(window
, SW_HIDE
);
2658 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2659 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2660 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2661 expected_style
= exstyle
| WS_EX_TOPMOST
;
2662 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2664 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2665 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2667 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2668 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2669 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2670 expected_style
= exstyle
| WS_EX_TOPMOST
;
2671 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2673 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2674 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2676 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2677 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2678 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2679 expected_style
= exstyle
| WS_EX_TOPMOST
;
2680 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2682 ret
= SetForegroundWindow(window
);
2683 ok(ret
, "Failed to set foreground window.\n");
2685 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2686 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2688 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2689 expected_style
= style
| WS_VISIBLE
;
2690 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2691 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2692 expected_style
= exstyle
| WS_EX_TOPMOST
;
2693 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2695 ShowWindow(window
, SW_HIDE
);
2696 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2697 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2699 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2700 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2701 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2702 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2704 ShowWindow(window
, SW_SHOW
);
2705 ret
= SetForegroundWindow(GetDesktopWindow());
2706 ok(ret
, "Failed to set foreground window.\n");
2707 SetActiveWindow(window
);
2708 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
2709 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2710 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2712 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2713 expected_style
= style
| WS_VISIBLE
;
2714 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2715 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2716 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2718 GetWindowRect(window
, &r
);
2719 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2720 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2722 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2723 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2725 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
2726 GetWindowRect(window
, &r
);
2727 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
2728 wine_dbgstr_rect(&r
));
2730 ret
= SetForegroundWindow(window2
);
2731 ok(ret
, "Failed to set foreground window.\n");
2732 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2733 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2735 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2736 expected_style
= style
| WS_VISIBLE
;
2737 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2738 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2739 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2741 GetWindowRect(window
, &r
);
2742 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2743 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2745 ret
= SetForegroundWindow(window
);
2746 ok(ret
, "Failed to set foreground window.\n");
2747 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2748 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2750 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2751 expected_style
= style
| WS_VISIBLE
;
2752 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2753 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2754 expected_style
= exstyle
| WS_EX_TOPMOST
;
2755 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2757 ShowWindow(window
, SW_HIDE
);
2758 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2759 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2761 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2762 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2763 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2764 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2766 ShowWindow(window
, SW_SHOW
);
2767 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2768 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2770 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2771 expected_style
= style
| WS_VISIBLE
;
2772 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2773 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2774 expected_style
= exstyle
| WS_EX_TOPMOST
;
2775 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2777 ret
= SetForegroundWindow(GetDesktopWindow());
2778 ok(ret
, "Failed to set foreground window.\n");
2779 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2780 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2781 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2782 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2783 expected_style
= exstyle
| WS_EX_TOPMOST
;
2784 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2786 ref
= IDirectDraw_Release(ddraw
);
2787 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2789 DestroyWindow(window2
);
2790 DestroyWindow(window
);
2793 static void test_redundant_mode_set(void)
2795 DDSURFACEDESC surface_desc
= {0};
2802 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2803 0, 0, 100, 100, 0, 0, 0, 0);
2804 ddraw
= create_ddraw();
2805 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2807 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2808 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2810 surface_desc
.dwSize
= sizeof(surface_desc
);
2811 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
2812 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
2814 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2815 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2816 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2818 GetWindowRect(window
, &q
);
2822 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2823 GetWindowRect(window
, &s
);
2824 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2826 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2827 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
2828 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2830 GetWindowRect(window
, &s
);
2831 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2832 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2834 ref
= IDirectDraw_Release(ddraw
);
2835 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2837 DestroyWindow(window
);
2840 static SIZE screen_size
;
2842 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2844 if (message
== WM_SIZE
)
2846 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2847 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2850 return test_proc(hwnd
, message
, wparam
, lparam
);
2853 struct test_coop_level_mode_set_enum_param
2855 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2858 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2860 struct test_coop_level_mode_set_enum_param
*param
= context
;
2862 if (U1(surface_desc
->ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2863 return DDENUMRET_OK
;
2864 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2865 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2866 return DDENUMRET_OK
;
2868 if (!param
->ddraw_width
)
2870 param
->ddraw_width
= surface_desc
->dwWidth
;
2871 param
->ddraw_height
= surface_desc
->dwHeight
;
2872 return DDENUMRET_OK
;
2874 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2875 return DDENUMRET_OK
;
2877 /* The docs say the DDENUMRET_CANCEL below cancels the enumeration, so the check should be
2878 * redundant. However, since Windows 10 this no longer works and the enumeration continues
2879 * until all supported modes are enumerated. Win8 and earlier do cancel.
2881 * Unrelatedly, some testbot machines report high res modes like 1920x1080, but suffer from
2882 * some problems when we actually try to set them (w10pro64 and its localization siblings).
2883 * Try to stay below the registry mode if possible. */
2884 if (!param
->user32_width
|| (surface_desc
->dwWidth
< registry_mode
.dmPelsWidth
2885 && surface_desc
->dwHeight
< registry_mode
.dmPelsHeight
))
2887 param
->user32_width
= surface_desc
->dwWidth
;
2888 param
->user32_height
= surface_desc
->dwHeight
;
2890 return DDENUMRET_CANCEL
;
2893 static void test_coop_level_mode_set(void)
2895 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2896 unsigned int display_count
= 0;
2897 IDirectDrawSurface
*primary
;
2898 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2906 struct test_coop_level_mode_set_enum_param param
;
2910 static const struct message exclusive_messages
[] =
2912 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2913 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2914 {WM_SIZE
, FALSE
, 0},
2915 {WM_DISPLAYCHANGE
, FALSE
, 0},
2918 static const struct message exclusive_focus_loss_messages
[] =
2920 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2921 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
2922 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2923 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
2924 {WM_DISPLAYCHANGE
, FALSE
, 0},
2925 {WM_KILLFOCUS
, FALSE
, 0},
2926 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
2927 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2928 * SW_MINIMIZED, causing a recursive window activation that does not
2929 * produce the same result in Wine yet. Ignore the difference for now.
2930 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2931 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2932 {WM_MOVE
, FALSE
, 0},
2933 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2934 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2937 static const struct message exclusive_focus_restore_messages
[] =
2939 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2940 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2941 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2942 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2943 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2944 /* Native redundantly sets the window size here. */
2945 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2946 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2947 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2948 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2951 static const struct message sc_restore_messages
[] =
2953 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2954 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2955 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2956 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2959 static const struct message sc_minimize_messages
[] =
2961 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2962 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2963 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2964 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2967 static const struct message sc_maximize_messages
[] =
2969 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2970 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2971 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2972 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2976 static const struct message normal_messages
[] =
2978 {WM_DISPLAYCHANGE
, FALSE
, 0},
2982 memset(&devmode
, 0, sizeof(devmode
));
2983 devmode
.dmSize
= sizeof(devmode
);
2984 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2985 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
2986 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2987 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
2988 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
2989 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
2991 ret
= save_display_modes(&original_modes
, &display_count
);
2992 ok(ret
, "Failed to save original display modes.\n");
2994 ddraw
= create_ddraw();
2995 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2997 memset(¶m
, 0, sizeof(param
));
2998 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2999 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3000 ref
= IDirectDraw_Release(ddraw
);
3001 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3003 if (!param
.user32_height
)
3005 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
3006 heap_free(original_modes
);
3010 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3011 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
3012 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
3014 memset(&devmode
, 0, sizeof(devmode
));
3015 devmode
.dmSize
= sizeof(devmode
);
3016 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3017 devmode
.dmPelsWidth
= param
.user32_width
;
3018 devmode
.dmPelsHeight
= param
.user32_height
;
3019 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3020 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3022 ddraw
= create_ddraw();
3023 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3025 wc
.lpfnWndProc
= mode_set_proc
;
3026 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3027 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3029 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3030 0, 0, 100, 100, 0, 0, 0, 0);
3032 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3033 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3035 GetWindowRect(window
, &r
);
3036 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3037 wine_dbgstr_rect(&r
));
3039 memset(&ddsd
, 0, sizeof(ddsd
));
3040 ddsd
.dwSize
= sizeof(ddsd
);
3041 ddsd
.dwFlags
= DDSD_CAPS
;
3042 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3044 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3045 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3046 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3047 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3048 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3049 param
.user32_width
, ddsd
.dwWidth
);
3050 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3051 param
.user32_height
, ddsd
.dwHeight
);
3053 GetWindowRect(window
, &r
);
3054 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3055 wine_dbgstr_rect(&r
));
3057 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3058 expect_messages
= exclusive_messages
;
3062 hr
= IDirectDrawSurface_IsLost(primary
);
3063 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3064 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3065 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3066 hr
= IDirectDrawSurface_IsLost(primary
);
3067 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3069 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3070 expect_messages
= NULL
;
3071 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3072 "Expected screen size %lux%lu, got %lux%lu.\n",
3073 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3075 GetWindowRect(window
, &r
);
3076 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3077 wine_dbgstr_rect(&r
));
3079 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3080 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3081 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3082 param
.user32_width
, ddsd
.dwWidth
);
3083 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3084 param
.user32_height
, ddsd
.dwHeight
);
3085 IDirectDrawSurface_Release(primary
);
3087 memset(&ddsd
, 0, sizeof(ddsd
));
3088 ddsd
.dwSize
= sizeof(ddsd
);
3089 ddsd
.dwFlags
= DDSD_CAPS
;
3090 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3092 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3093 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3094 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3095 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3096 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3097 param
.ddraw_width
, ddsd
.dwWidth
);
3098 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3099 param
.ddraw_height
, ddsd
.dwHeight
);
3101 GetWindowRect(window
, &r
);
3102 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3103 wine_dbgstr_rect(&r
));
3105 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3106 expect_messages
= exclusive_messages
;
3110 hr
= IDirectDrawSurface_IsLost(primary
);
3111 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3112 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3113 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3114 hr
= IDirectDrawSurface_IsLost(primary
);
3115 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3117 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3118 expect_messages
= NULL
;
3119 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3120 "Expected screen size %lux%lu, got %lux%lu.\n",
3121 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3123 GetWindowRect(window
, &r
);
3124 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3125 wine_dbgstr_rect(&r
));
3127 expect_messages
= exclusive_focus_loss_messages
;
3128 ret
= SetForegroundWindow(GetDesktopWindow());
3129 ok(ret
, "Failed to set foreground window.\n");
3130 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3131 memset(&devmode
, 0, sizeof(devmode
));
3132 devmode
.dmSize
= sizeof(devmode
);
3133 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3134 ok(ret
, "Failed to get display mode.\n");
3135 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3136 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3137 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3139 expect_messages
= exclusive_focus_restore_messages
;
3140 ShowWindow(window
, SW_RESTORE
);
3141 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3143 GetWindowRect(window
, &r
);
3144 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3145 wine_dbgstr_rect(&r
));
3146 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3147 ok(ret
, "Failed to get display mode.\n");
3148 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3149 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %lux%lu.\n",
3150 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3152 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3153 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3154 /* Normally the primary should be restored here. Unfortunately this causes the
3155 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3156 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3157 * the point of the GetSurfaceDesc call. */
3159 expect_messages
= sc_minimize_messages
;
3160 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3161 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3162 expect_messages
= NULL
;
3164 expect_messages
= sc_restore_messages
;
3165 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3166 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3167 expect_messages
= NULL
;
3169 expect_messages
= sc_maximize_messages
;
3170 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3171 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3172 expect_messages
= NULL
;
3174 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3175 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3177 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3178 expect_messages
= exclusive_messages
;
3182 hr
= IDirectDrawSurface_IsLost(primary
);
3183 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3184 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3185 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3186 hr
= IDirectDrawSurface_IsLost(primary
);
3187 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3190 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3191 expect_messages
= NULL
;
3193 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3194 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3195 "Expected screen size %lux%lu, got %lux%lu.\n",
3196 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3198 GetWindowRect(window
, &r
);
3200 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3201 wine_dbgstr_rect(&r
));
3203 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3204 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3205 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3206 param
.ddraw_width
, ddsd
.dwWidth
);
3207 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3208 param
.ddraw_height
, ddsd
.dwHeight
);
3209 IDirectDrawSurface_Release(primary
);
3212 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3213 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3215 memset(&ddsd
, 0, sizeof(ddsd
));
3216 ddsd
.dwSize
= sizeof(ddsd
);
3217 ddsd
.dwFlags
= DDSD_CAPS
;
3218 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3220 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3221 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3222 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3223 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3224 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3225 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3226 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3227 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3229 GetWindowRect(window
, &r
);
3231 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3232 wine_dbgstr_rect(&r
));
3234 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3235 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3237 GetWindowRect(window
, &r
);
3239 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3240 wine_dbgstr_rect(&r
));
3242 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3243 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3244 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3245 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3246 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3247 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3248 IDirectDrawSurface_Release(primary
);
3250 memset(&ddsd
, 0, sizeof(ddsd
));
3251 ddsd
.dwSize
= sizeof(ddsd
);
3252 ddsd
.dwFlags
= DDSD_CAPS
;
3253 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3255 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3256 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3257 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3258 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3259 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3260 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3261 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3262 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3264 GetWindowRect(window
, &r
);
3266 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3267 wine_dbgstr_rect(&r
));
3269 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3270 expect_messages
= normal_messages
;
3274 hr
= IDirectDrawSurface_IsLost(primary
);
3275 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3276 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3277 devmode
.dmPelsWidth
= param
.user32_width
;
3278 devmode
.dmPelsHeight
= param
.user32_height
;
3279 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3280 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3281 hr
= IDirectDrawSurface_IsLost(primary
);
3282 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3284 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3285 expect_messages
= NULL
;
3286 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3288 GetWindowRect(window
, &r
);
3290 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3291 wine_dbgstr_rect(&r
));
3293 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3294 expect_messages
= normal_messages
;
3298 hr
= IDirectDrawSurface_Restore(primary
);
3299 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3300 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3301 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3303 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3304 IDirectDrawSurface_Release(primary
);
3305 IDirectDraw_Release(ddraw
);
3308 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3309 hr
= IDirectDrawSurface_Restore(primary
);
3310 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3311 hr
= IDirectDrawSurface_IsLost(primary
);
3312 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3314 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3315 expect_messages
= NULL
;
3316 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3318 GetWindowRect(window
, &r
);
3320 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3321 wine_dbgstr_rect(&r
));
3323 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3324 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3325 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3326 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3327 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3328 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3329 IDirectDrawSurface_Release(primary
);
3331 memset(&ddsd
, 0, sizeof(ddsd
));
3332 ddsd
.dwSize
= sizeof(ddsd
);
3333 ddsd
.dwFlags
= DDSD_CAPS
;
3334 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3336 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3337 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3338 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3339 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3340 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3341 param
.ddraw_width
, ddsd
.dwWidth
);
3342 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3343 param
.ddraw_height
, ddsd
.dwHeight
);
3345 GetWindowRect(window
, &r
);
3347 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3348 wine_dbgstr_rect(&r
));
3350 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3351 expect_messages
= normal_messages
;
3355 hr
= IDirectDrawSurface_IsLost(primary
);
3356 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3357 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3358 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3359 hr
= IDirectDrawSurface_IsLost(primary
);
3360 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3362 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3363 expect_messages
= NULL
;
3364 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3366 GetWindowRect(window
, &r
);
3368 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3369 wine_dbgstr_rect(&r
));
3371 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3372 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3373 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3374 param
.ddraw_width
, ddsd
.dwWidth
);
3375 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3376 param
.ddraw_height
, ddsd
.dwHeight
);
3377 IDirectDrawSurface_Release(primary
);
3379 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3380 ok(ret
, "Failed to get display mode.\n");
3381 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3382 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3383 "Expected resolution %lux%lu, got %lux%lu.\n",
3384 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3385 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3386 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3387 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3389 memset(&ddsd
, 0, sizeof(ddsd
));
3390 ddsd
.dwSize
= sizeof(ddsd
);
3391 ddsd
.dwFlags
= DDSD_CAPS
;
3392 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3394 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3395 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3396 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3397 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3398 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3399 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3400 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3401 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3403 GetWindowRect(window
, &r
);
3405 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3406 wine_dbgstr_rect(&r
));
3408 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3409 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3410 * not DDSCL_FULLSCREEN. */
3411 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3412 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3414 GetWindowRect(window
, &r
);
3416 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3417 wine_dbgstr_rect(&r
));
3419 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3420 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3421 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3422 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3423 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3424 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3425 IDirectDrawSurface_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
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3433 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3434 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3435 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3436 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3437 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3438 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3439 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3441 GetWindowRect(window
, &r
);
3443 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3444 wine_dbgstr_rect(&r
));
3446 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3447 expect_messages
= normal_messages
;
3451 hr
= IDirectDrawSurface_IsLost(primary
);
3452 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3453 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3454 devmode
.dmPelsWidth
= param
.user32_width
;
3455 devmode
.dmPelsHeight
= param
.user32_height
;
3456 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3457 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3458 hr
= IDirectDrawSurface_IsLost(primary
);
3459 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3461 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3462 expect_messages
= NULL
;
3463 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3465 GetWindowRect(window
, &r
);
3467 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3468 wine_dbgstr_rect(&r
));
3470 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3471 expect_messages
= normal_messages
;
3475 hr
= IDirectDrawSurface_Restore(primary
);
3476 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3477 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3478 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3479 hr
= IDirectDrawSurface_Restore(primary
);
3480 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3481 hr
= IDirectDrawSurface_IsLost(primary
);
3482 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3484 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3485 expect_messages
= NULL
;
3486 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3488 GetWindowRect(window
, &r
);
3490 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3491 wine_dbgstr_rect(&r
));
3493 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3494 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3495 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3496 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3497 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3498 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3499 IDirectDrawSurface_Release(primary
);
3501 memset(&ddsd
, 0, sizeof(ddsd
));
3502 ddsd
.dwSize
= sizeof(ddsd
);
3503 ddsd
.dwFlags
= DDSD_CAPS
;
3504 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3506 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3507 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3508 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3509 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3510 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3511 param
.ddraw_width
, ddsd
.dwWidth
);
3512 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3513 param
.ddraw_height
, ddsd
.dwHeight
);
3515 GetWindowRect(window
, &r
);
3517 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3518 wine_dbgstr_rect(&r
));
3520 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3521 expect_messages
= normal_messages
;
3525 hr
= IDirectDrawSurface_IsLost(primary
);
3526 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3527 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3528 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3529 hr
= IDirectDrawSurface_IsLost(primary
);
3530 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3532 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3533 expect_messages
= NULL
;
3534 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3536 GetWindowRect(window
, &r
);
3538 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3539 wine_dbgstr_rect(&r
));
3541 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3542 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3543 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3544 param
.ddraw_width
, ddsd
.dwWidth
);
3545 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3546 param
.ddraw_height
, ddsd
.dwHeight
);
3547 IDirectDrawSurface_Release(primary
);
3549 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3550 ok(ret
, "Failed to get display mode.\n");
3551 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3552 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3553 "Expected resolution %lux%lu, got %lux%lu.\n",
3554 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3555 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3556 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3557 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3559 memset(&ddsd
, 0, sizeof(ddsd
));
3560 ddsd
.dwSize
= sizeof(ddsd
);
3561 ddsd
.dwFlags
= DDSD_CAPS
;
3562 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3564 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3565 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3566 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3567 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3568 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3569 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3570 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3571 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3572 IDirectDrawSurface_Release(primary
);
3574 GetWindowRect(window
, &r
);
3576 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3577 wine_dbgstr_rect(&r
));
3579 /* Unlike ddraw2-7, changing from EXCLUSIVE to NORMAL does not restore the resolution */
3580 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3581 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3582 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3583 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3585 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3586 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3588 memset(&ddsd
, 0, sizeof(ddsd
));
3589 ddsd
.dwSize
= sizeof(ddsd
);
3590 ddsd
.dwFlags
= DDSD_CAPS
;
3591 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3593 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3594 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3595 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3596 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3597 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3598 param
.ddraw_width
, ddsd
.dwWidth
);
3599 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3600 param
.ddraw_height
, ddsd
.dwHeight
);
3601 IDirectDrawSurface_Release(primary
);
3602 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3603 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3605 ref
= IDirectDraw_Release(ddraw
);
3606 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3608 GetWindowRect(window
, &r
);
3609 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3610 wine_dbgstr_rect(&r
));
3612 ret
= restore_display_modes(original_modes
, display_count
);
3613 ok(ret
, "Failed to restore display modes.\n");
3615 /* Test that no mode restorations if no mode changes happened */
3616 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3617 devmode
.dmPelsWidth
= param
.user32_width
;
3618 devmode
.dmPelsHeight
= param
.user32_height
;
3619 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3620 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3622 ddraw
= create_ddraw();
3623 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3624 ref
= IDirectDraw_Release(ddraw
);
3625 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3627 memset(&devmode2
, 0, sizeof(devmode2
));
3628 devmode2
.dmSize
= sizeof(devmode2
);
3629 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3630 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3631 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3632 ret
= restore_display_modes(original_modes
, display_count
);
3633 ok(ret
, "Failed to restore display modes.\n");
3635 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3636 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3637 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3639 ddraw
= create_ddraw();
3640 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3641 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3642 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3643 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3644 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3645 ref
= IDirectDraw_Release(ddraw
);
3646 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3648 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3649 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3650 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3651 ret
= restore_display_modes(original_modes
, display_count
);
3652 ok(ret
, "Failed to restore display modes.\n");
3654 /* Test that mode restorations use display settings in the registry after ddraw object releases
3655 * if SetDisplayMode() was called */
3656 ddraw
= create_ddraw();
3657 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3658 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3659 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3661 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3662 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3664 ref
= IDirectDraw_Release(ddraw
);
3665 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3667 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3668 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3669 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3670 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3671 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3672 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3673 ret
= restore_display_modes(original_modes
, display_count
);
3674 ok(ret
, "Failed to restore display modes.\n");
3676 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3677 ddraw
= create_ddraw();
3678 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3679 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3680 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3682 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3683 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3685 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3686 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3688 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3689 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3690 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3691 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3692 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3693 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3695 ref
= IDirectDraw_Release(ddraw
);
3696 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3699 expect_messages
= NULL
;
3700 DestroyWindow(window
);
3701 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3702 ret
= restore_display_modes(original_modes
, display_count
);
3703 ok(ret
, "Failed to restore display modes.\n");
3704 heap_free(original_modes
);
3707 static void test_coop_level_mode_set_multi(void)
3709 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3710 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3711 WCHAR second_monitor_name
[CCHDEVICENAME
];
3712 IDirectDraw
*ddraw1
, *ddraw2
;
3720 memset(&devmode
, 0, sizeof(devmode
));
3721 devmode
.dmSize
= sizeof(devmode
);
3722 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3723 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3724 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3725 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3726 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3727 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3729 ret
= save_display_modes(&original_modes
, &display_count
);
3730 ok(ret
, "Failed to save original display modes.\n");
3732 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3733 0, 0, 100, 100, 0, 0, 0, 0);
3734 ddraw1
= create_ddraw();
3735 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3737 /* With just a single ddraw object, the display mode is restored on
3739 hr
= set_display_mode(ddraw1
, 800, 600);
3740 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3742 win_skip("Broken SetDisplayMode(), skipping test.\n");
3743 IDirectDraw_Release(ddraw1
);
3744 DestroyWindow(window
);
3747 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3748 w
= GetSystemMetrics(SM_CXSCREEN
);
3749 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3750 h
= GetSystemMetrics(SM_CYSCREEN
);
3751 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3753 ref
= IDirectDraw_Release(ddraw1
);
3754 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3755 w
= GetSystemMetrics(SM_CXSCREEN
);
3756 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3757 h
= GetSystemMetrics(SM_CYSCREEN
);
3758 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3760 /* When there are multiple ddraw objects, the display mode is restored to
3761 * the initial mode, before the first SetDisplayMode() call. */
3762 ddraw1
= create_ddraw();
3763 hr
= set_display_mode(ddraw1
, 800, 600);
3764 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3765 w
= GetSystemMetrics(SM_CXSCREEN
);
3766 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3767 h
= GetSystemMetrics(SM_CYSCREEN
);
3768 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3770 ddraw2
= create_ddraw();
3771 hr
= set_display_mode(ddraw2
, 640, 480);
3772 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3773 w
= GetSystemMetrics(SM_CXSCREEN
);
3774 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3775 h
= GetSystemMetrics(SM_CYSCREEN
);
3776 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3778 ref
= IDirectDraw_Release(ddraw2
);
3779 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3780 w
= GetSystemMetrics(SM_CXSCREEN
);
3781 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3782 h
= GetSystemMetrics(SM_CYSCREEN
);
3783 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3785 ref
= IDirectDraw_Release(ddraw1
);
3786 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3787 w
= GetSystemMetrics(SM_CXSCREEN
);
3788 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3789 h
= GetSystemMetrics(SM_CYSCREEN
);
3790 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3792 /* Regardless of release ordering. */
3793 ddraw1
= create_ddraw();
3794 hr
= set_display_mode(ddraw1
, 800, 600);
3795 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3796 w
= GetSystemMetrics(SM_CXSCREEN
);
3797 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3798 h
= GetSystemMetrics(SM_CYSCREEN
);
3799 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3801 ddraw2
= create_ddraw();
3802 hr
= set_display_mode(ddraw2
, 640, 480);
3803 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3804 w
= GetSystemMetrics(SM_CXSCREEN
);
3805 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3806 h
= GetSystemMetrics(SM_CYSCREEN
);
3807 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3809 ref
= IDirectDraw_Release(ddraw1
);
3810 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3811 w
= GetSystemMetrics(SM_CXSCREEN
);
3812 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3813 h
= GetSystemMetrics(SM_CYSCREEN
);
3814 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3816 ref
= IDirectDraw_Release(ddraw2
);
3817 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3818 w
= GetSystemMetrics(SM_CXSCREEN
);
3819 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3820 h
= GetSystemMetrics(SM_CYSCREEN
);
3821 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3823 /* But only for ddraw objects that called SetDisplayMode(). */
3824 ddraw1
= create_ddraw();
3825 ddraw2
= create_ddraw();
3826 hr
= set_display_mode(ddraw2
, 640, 480);
3827 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3828 w
= GetSystemMetrics(SM_CXSCREEN
);
3829 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3830 h
= GetSystemMetrics(SM_CYSCREEN
);
3831 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3833 ref
= IDirectDraw_Release(ddraw1
);
3834 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3835 w
= GetSystemMetrics(SM_CXSCREEN
);
3836 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3837 h
= GetSystemMetrics(SM_CYSCREEN
);
3838 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3840 ref
= IDirectDraw_Release(ddraw2
);
3841 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3842 w
= GetSystemMetrics(SM_CXSCREEN
);
3843 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3844 h
= GetSystemMetrics(SM_CYSCREEN
);
3845 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3847 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3848 * restoring the display mode. */
3849 ddraw1
= create_ddraw();
3850 hr
= set_display_mode(ddraw1
, 800, 600);
3851 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3852 w
= GetSystemMetrics(SM_CXSCREEN
);
3853 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3854 h
= GetSystemMetrics(SM_CYSCREEN
);
3855 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3857 ddraw2
= create_ddraw();
3858 hr
= set_display_mode(ddraw2
, 640, 480);
3859 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3860 w
= GetSystemMetrics(SM_CXSCREEN
);
3861 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3862 h
= GetSystemMetrics(SM_CYSCREEN
);
3863 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3865 hr
= IDirectDraw_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3866 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3868 ref
= IDirectDraw_Release(ddraw1
);
3869 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3870 w
= GetSystemMetrics(SM_CXSCREEN
);
3871 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3872 h
= GetSystemMetrics(SM_CYSCREEN
);
3873 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3875 ref
= IDirectDraw_Release(ddraw2
);
3876 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3877 w
= GetSystemMetrics(SM_CXSCREEN
);
3878 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3879 h
= GetSystemMetrics(SM_CYSCREEN
);
3880 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3882 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3883 ddraw1
= create_ddraw();
3884 hr
= set_display_mode(ddraw1
, 800, 600);
3885 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3886 w
= GetSystemMetrics(SM_CXSCREEN
);
3887 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3888 h
= GetSystemMetrics(SM_CYSCREEN
);
3889 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3891 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3892 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3894 ddraw2
= create_ddraw();
3895 hr
= set_display_mode(ddraw2
, 640, 480);
3896 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
3898 ref
= IDirectDraw_Release(ddraw1
);
3899 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3900 w
= GetSystemMetrics(SM_CXSCREEN
);
3901 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3902 h
= GetSystemMetrics(SM_CYSCREEN
);
3903 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3905 ref
= IDirectDraw_Release(ddraw2
);
3906 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3907 w
= GetSystemMetrics(SM_CXSCREEN
);
3908 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3909 h
= GetSystemMetrics(SM_CYSCREEN
);
3910 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3912 if (display_count
< 2)
3914 skip("Following tests require two monitors.\n");
3918 ret
= restore_display_modes(original_modes
, display_count
);
3919 ok(ret
, "Failed to restore display modes.\n");
3921 second_monitor_name
[0] = '\0';
3922 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
3924 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
3926 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
3930 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
3931 memset(&old_devmode
, 0, sizeof(old_devmode
));
3932 old_devmode
.dmSize
= sizeof(old_devmode
);
3933 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
3934 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3936 devmode
= old_devmode
;
3937 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
3939 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3940 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
3943 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3944 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
3945 "Failed to find a different mode for the second monitor.\n");
3947 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
3948 ddraw1
= create_ddraw();
3949 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3950 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3951 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3953 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3954 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
3956 memset(&devmode2
, 0, sizeof(devmode2
));
3957 devmode2
.dmSize
= sizeof(devmode2
);
3958 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3959 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3960 if (compare_mode_rect(&devmode2
, &old_devmode
))
3962 skip("Failed to change display settings of the second monitor.\n");
3963 ref
= IDirectDraw_Release(ddraw1
);
3964 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3968 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
3969 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3970 ref
= IDirectDraw_Release(ddraw1
);
3971 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3973 memset(&devmode3
, 0, sizeof(devmode3
));
3974 devmode3
.dmSize
= sizeof(devmode3
);
3975 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
3976 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3977 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
3978 ret
= restore_display_modes(original_modes
, display_count
);
3979 ok(ret
, "Failed to restore display modes.\n");
3981 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
3982 * SetDisplayMode() was called */
3983 ddraw1
= create_ddraw();
3984 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3985 hr
= set_display_mode(ddraw1
, 800, 600);
3986 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3988 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3989 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
3991 ref
= IDirectDraw_Release(ddraw1
);
3992 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3994 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3995 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3996 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
3997 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3998 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3999 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4000 ret
= restore_display_modes(original_modes
, display_count
);
4001 ok(ret
, "Failed to restore display modes.\n");
4003 /* Test that mode restorations happen for non-primary monitors as well */
4004 ddraw1
= create_ddraw();
4005 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4006 hr
= set_display_mode(ddraw1
, 800, 600);
4007 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4009 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4010 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4012 hr
= IDirectDraw_RestoreDisplayMode(ddraw1
);
4013 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4015 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4016 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4017 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4018 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4019 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4020 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4022 ref
= IDirectDraw_Release(ddraw1
);
4023 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4024 ret
= restore_display_modes(original_modes
, display_count
);
4025 ok(ret
, "Failed to restore display modes.\n");
4027 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4028 ddraw1
= create_ddraw();
4029 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4030 hr
= set_display_mode(ddraw1
, 800, 600);
4031 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4033 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4034 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4035 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4037 ref
= IDirectDraw_Release(ddraw1
);
4038 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4040 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4041 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4042 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4043 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4044 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4045 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4046 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4047 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4048 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4049 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4050 ret
= restore_display_modes(original_modes
, display_count
);
4051 ok(ret
, "Failed to restore display modes.\n");
4053 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4054 * objects and one of them restores display mode */
4055 ddraw1
= create_ddraw();
4056 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4057 ddraw2
= create_ddraw();
4058 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4059 hr
= set_display_mode(ddraw1
, 800, 600);
4060 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4061 hr
= set_display_mode(ddraw2
, 640, 480);
4062 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4064 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4065 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4067 hr
= IDirectDraw_RestoreDisplayMode(ddraw2
);
4068 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4070 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4071 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4072 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4073 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4074 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4075 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4077 ref
= IDirectDraw_Release(ddraw2
);
4078 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4079 ref
= IDirectDraw_Release(ddraw1
);
4080 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4081 ret
= restore_display_modes(original_modes
, display_count
);
4082 ok(ret
, "Failed to restore display modes.\n");
4084 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4085 * objects and one of them got released */
4086 ddraw1
= create_ddraw();
4087 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4088 ddraw2
= create_ddraw();
4089 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4090 hr
= set_display_mode(ddraw1
, 800, 600);
4091 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4092 hr
= set_display_mode(ddraw2
, 640, 480);
4093 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4095 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4096 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4098 ref
= IDirectDraw_Release(ddraw2
);
4099 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4101 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4102 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4103 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4104 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4105 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4106 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4108 ref
= IDirectDraw_Release(ddraw1
);
4109 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4112 DestroyWindow(window
);
4113 ret
= restore_display_modes(original_modes
, display_count
);
4114 ok(ret
, "Failed to restore display modes.\n");
4115 heap_free(original_modes
);
4118 static void test_initialize(void)
4124 ddraw
= create_ddraw();
4125 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4127 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4128 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx.\n", hr
);
4129 IDirectDraw_Release(ddraw
);
4132 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw
, (void **)&ddraw
);
4133 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw instance, hr %#lx.\n", hr
);
4134 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
4137 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4138 hr
= IDirect3D_Initialize(d3d
, NULL
);
4139 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4140 IDirect3D_Release(d3d
);
4143 skip("D3D interface is not available, skipping test.\n");
4144 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4145 ok(hr
== DD_OK
, "Initialize returned hr %#lx, expected DD_OK.\n", hr
);
4146 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4147 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4148 IDirectDraw_Release(ddraw
);
4151 if (0) /* This crashes on the W2KPROSP4 testbot. */
4154 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirect3D
, (void **)&d3d
);
4155 ok(hr
== E_NOINTERFACE
, "CoCreateInstance returned hr %#lx, expected E_NOINTERFACE.\n", hr
);
4160 static void test_coop_level_surf_create(void)
4162 IDirectDrawSurface
*surface
;
4167 ddraw
= create_ddraw();
4168 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4170 memset(&ddsd
, 0, sizeof(ddsd
));
4171 ddsd
.dwSize
= sizeof(ddsd
);
4172 ddsd
.dwFlags
= DDSD_CAPS
;
4173 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4174 surface
= (void *)0xdeadbeef;
4175 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4176 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4177 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4179 surface
= (void *)0xdeadbeef;
4180 hr
= IDirectDraw_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4181 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4182 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4184 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4185 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4187 surface
= (void *)0xdeadbeef;
4188 hr
= IDirectDraw_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4189 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#lx.\n", hr
);
4190 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4192 IDirectDraw_Release(ddraw
);
4195 static void test_coop_level_multi_window(void)
4197 HWND window1
, window2
;
4201 window1
= create_window();
4202 window2
= create_window();
4203 ddraw
= create_ddraw();
4204 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4206 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4207 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4208 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4209 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4210 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4211 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4213 IDirectDraw_Release(ddraw
);
4214 DestroyWindow(window2
);
4215 DestroyWindow(window1
);
4218 static void test_clear_rect_count(void)
4220 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4221 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
4222 IDirect3DViewport
*viewport
;
4223 IDirect3DDevice
*device
;
4224 IDirectDrawSurface
*rt
;
4230 window
= create_window();
4231 ddraw
= create_ddraw();
4232 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4233 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4235 skip("Failed to create a 3D device, skipping test.\n");
4236 IDirectDraw_Release(ddraw
);
4237 DestroyWindow(window
);
4241 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
4242 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4244 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
4245 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
4246 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
4247 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
4248 viewport
= create_viewport(device
, 0, 0, 640, 480);
4250 viewport_set_background(device
, viewport
, white
);
4251 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4252 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4253 viewport_set_background(device
, viewport
, red
);
4254 hr
= IDirect3DViewport_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4255 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4256 viewport_set_background(device
, viewport
, green
);
4257 hr
= IDirect3DViewport_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
4258 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4259 viewport_set_background(device
, viewport
, blue
);
4260 hr
= IDirect3DViewport_Clear(viewport
, 1, NULL
, D3DCLEAR_TARGET
);
4261 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4263 color
= get_surface_color(rt
, 320, 240);
4264 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4265 "Got unexpected color 0x%08x.\n", color
);
4267 IDirectDrawSurface_Release(rt
);
4268 destroy_viewport(device
, viewport
);
4269 destroy_material(white
);
4270 destroy_material(red
);
4271 destroy_material(green
);
4272 destroy_material(blue
);
4273 IDirect3DDevice_Release(device
);
4274 IDirectDraw_Release(ddraw
);
4275 DestroyWindow(window
);
4284 } activateapp_testdata
;
4286 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4288 if (message
== WM_ACTIVATEAPP
)
4290 if (activateapp_testdata
.ddraw
)
4293 activateapp_testdata
.received
= FALSE
;
4294 hr
= IDirectDraw_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4295 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4296 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#lx.\n", hr
);
4297 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4299 activateapp_testdata
.received
= TRUE
;
4302 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4305 static void test_coop_level_activateapp(void)
4312 IDirectDrawSurface
*surface
;
4314 ddraw
= create_ddraw();
4315 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4317 wc
.lpfnWndProc
= activateapp_test_proc
;
4318 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4319 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4321 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4322 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4324 /* Exclusive with window already active. */
4325 SetForegroundWindow(window
);
4326 activateapp_testdata
.received
= FALSE
;
4327 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4328 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4329 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4330 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4331 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4333 /* Exclusive with window not active. */
4334 SetForegroundWindow(GetDesktopWindow());
4335 activateapp_testdata
.received
= FALSE
;
4336 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4337 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4338 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4339 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4340 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4342 /* Normal with window not active, then exclusive with the same window. */
4343 SetForegroundWindow(GetDesktopWindow());
4344 activateapp_testdata
.received
= FALSE
;
4345 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4346 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4347 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4348 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4349 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4350 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4351 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4352 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4354 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4355 SetForegroundWindow(GetDesktopWindow());
4356 activateapp_testdata
.received
= FALSE
;
4357 activateapp_testdata
.ddraw
= ddraw
;
4358 activateapp_testdata
.window
= window
;
4359 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4360 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4361 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4362 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4363 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4364 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4366 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4367 * succeeding. Another switch to exclusive and back to normal is needed to release the
4368 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4369 * WM_ACTIVATEAPP messages. */
4370 activateapp_testdata
.ddraw
= NULL
;
4371 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4372 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4373 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4374 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4376 /* Setting DDSCL_NORMAL with recursive invocation. */
4377 SetForegroundWindow(GetDesktopWindow());
4378 activateapp_testdata
.received
= FALSE
;
4379 activateapp_testdata
.ddraw
= ddraw
;
4380 activateapp_testdata
.window
= window
;
4381 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4382 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4383 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4384 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4386 /* DDraw is in exclusive mode now. */
4387 memset(&ddsd
, 0, sizeof(ddsd
));
4388 ddsd
.dwSize
= sizeof(ddsd
);
4389 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4390 ddsd
.dwBackBufferCount
= 1;
4391 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4392 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4393 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
4394 IDirectDrawSurface_Release(surface
);
4396 /* Recover again, just to be sure. */
4397 activateapp_testdata
.ddraw
= NULL
;
4398 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4399 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4400 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4401 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4403 DestroyWindow(window
);
4404 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4405 IDirectDraw_Release(ddraw
);
4408 struct format_support_check
4410 const DDPIXELFORMAT
*format
;
4414 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4416 struct format_support_check
*format
= ctx
;
4418 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4420 format
->supported
= TRUE
;
4421 return DDENUMRET_CANCEL
;
4424 return DDENUMRET_OK
;
4427 static void test_unsupported_formats(void)
4430 BOOL expect_success
;
4433 IDirect3DDevice
*device
;
4434 IDirectDrawSurface
*surface
;
4437 DWORD expected_caps
;
4448 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4449 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4455 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4456 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4460 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4462 window
= create_window();
4463 ddraw
= create_ddraw();
4464 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4465 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4467 skip("Failed to create a 3D device, skipping test.\n");
4468 IDirectDraw_Release(ddraw
);
4469 DestroyWindow(window
);
4473 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4475 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4476 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4477 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
4479 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4481 memset(&ddsd
, 0, sizeof(ddsd
));
4482 ddsd
.dwSize
= sizeof(ddsd
);
4483 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4484 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4487 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4489 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4490 expect_success
= FALSE
;
4492 expect_success
= TRUE
;
4494 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4495 ok(SUCCEEDED(hr
) == expect_success
,
4496 "Got unexpected hr %#lx for format %s, caps %#lx, expected %s.\n",
4497 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4501 memset(&ddsd
, 0, sizeof(ddsd
));
4502 ddsd
.dwSize
= sizeof(ddsd
);
4503 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4504 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
4506 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4507 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4508 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4509 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4510 else if (check
.supported
)
4511 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4513 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4515 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4516 "Expected caps %#lx, format %s, input caps %#lx.\n",
4517 expected_caps
, formats
[i
].name
, caps
[j
]);
4519 IDirectDrawSurface_Release(surface
);
4523 IDirect3DDevice_Release(device
);
4524 IDirectDraw_Release(ddraw
);
4525 DestroyWindow(window
);
4528 static void test_rt_caps(const GUID
*device_guid
)
4530 PALETTEENTRY palette_entries
[256];
4531 IDirectDrawPalette
*palette
;
4532 IDirect3DDevice
*device
;
4533 BOOL software_device
;
4542 static const DDPIXELFORMAT p8_fmt
=
4544 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4545 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4550 const DDPIXELFORMAT
*pf
;
4552 HRESULT create_device_hr
;
4553 BOOL create_may_fail
;
4559 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4565 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4571 DDSCAPS_OFFSCREENPLAIN
,
4577 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4578 D3DERR_SURFACENOTINVIDMEM
,
4583 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4589 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4607 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4608 D3DERR_SURFACENOTINVIDMEM
,
4613 DDSCAPS_SYSTEMMEMORY
,
4625 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4626 DDERR_NOPALETTEATTACHED
,
4631 DDSCAPS_OFFSCREENPLAIN
,
4637 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4638 DDERR_NOPALETTEATTACHED
,
4643 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4649 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
4651 TRUE
/* AMD Evergreen */,
4655 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4667 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4669 TRUE
/* Nvidia Kepler */,
4673 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4675 TRUE
/* Nvidia Kepler */,
4679 software_device
= is_software_device_type(device_guid
);
4681 window
= create_window();
4682 ddraw
= create_ddraw();
4683 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4684 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
4686 skip("Failed to create a 3D device, skipping test.\n");
4687 IDirectDraw_Release(ddraw
);
4688 DestroyWindow(window
);
4691 z_depth
= get_device_z_depth(device
);
4692 ok(!!z_depth
, "Failed to get device z depth.\n");
4693 IDirect3DDevice_Release(device
);
4695 memset(palette_entries
, 0, sizeof(palette_entries
));
4696 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
4697 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
4699 memset(&hal_caps
, 0, sizeof(hal_caps
));
4700 hal_caps
.dwSize
= sizeof(hal_caps
);
4701 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
4702 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
4704 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4706 DWORD caps_in
, expected_caps
;
4707 IDirectDrawSurface
*surface
;
4708 DDSURFACEDESC surface_desc
;
4709 IDirect3DDevice
*device
;
4710 HRESULT expected_hr
;
4712 caps_in
= test_data
[i
].caps_in
;
4714 memset(&surface_desc
, 0, sizeof(surface_desc
));
4715 surface_desc
.dwSize
= sizeof(surface_desc
);
4716 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4717 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
4718 if (test_data
[i
].pf
)
4720 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4721 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4723 if (caps_in
& DDSCAPS_ZBUFFER
)
4725 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4726 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
4728 surface_desc
.dwWidth
= 640;
4729 surface_desc
.dwHeight
= 480;
4730 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
4731 expected_hr
= DDERR_NODIRECTDRAWHW
;
4733 expected_hr
= DD_OK
;
4734 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4735 ok(hr
== expected_hr
|| broken(test_data
[i
].create_may_fail
4736 || (software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
)),
4737 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4741 memset(&surface_desc
, 0, sizeof(surface_desc
));
4742 surface_desc
.dwSize
= sizeof(surface_desc
);
4743 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4744 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4746 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
4747 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
4749 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
4751 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
4752 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
4753 || (software_device
&& caps_in
& DDSCAPS_ZBUFFER
4754 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
4755 "Got unexpected caps %#lx, expected %#lx, test %u, software_device %u.\n",
4756 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
4758 hr
= IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
);
4759 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
4760 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
4761 ? DD_OK
: test_data
[i
].create_device_hr
))),
4762 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4763 if (hr
== DDERR_NOPALETTEATTACHED
)
4765 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
4766 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4767 hr
= IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
);
4768 if (software_device
)
4770 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4771 hr
, i
, software_device
);
4772 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4773 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4774 hr
, i
, software_device
);
4776 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4777 hr
, i
, software_device
);
4781 refcount
= IDirect3DDevice_Release(device
);
4782 ok(refcount
== 1, "Test %u: Got unexpected refcount %lu.\n", i
, refcount
);
4785 refcount
= IDirectDrawSurface_Release(surface
);
4786 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
4789 IDirectDrawPalette_Release(palette
);
4790 refcount
= IDirectDraw_Release(ddraw
);
4791 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
4792 DestroyWindow(window
);
4795 static void test_primary_caps(void)
4797 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4798 IDirectDrawSurface
*surface
;
4799 DDSURFACEDESC surface_desc
;
4810 DWORD back_buffer_count
;
4818 DDSCAPS_PRIMARYSURFACE
,
4821 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4825 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4832 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4835 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4839 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4846 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4853 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4860 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4867 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4874 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4876 DDERR_NOEXCLUSIVEMODE
,
4880 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4881 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4887 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4888 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4891 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4894 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4895 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4901 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4902 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4909 window
= create_window();
4910 ddraw
= create_ddraw();
4911 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4913 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4915 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4916 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4918 memset(&surface_desc
, 0, sizeof(surface_desc
));
4919 surface_desc
.dwSize
= sizeof(surface_desc
);
4920 surface_desc
.dwFlags
= DDSD_CAPS
;
4921 if (test_data
[i
].back_buffer_count
!= ~0u)
4922 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4923 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
4924 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
4925 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4926 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
4930 memset(&surface_desc
, 0, sizeof(surface_desc
));
4931 surface_desc
.dwSize
= sizeof(surface_desc
);
4932 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4933 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
4934 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
4935 "Test %u: Got unexpected caps %#lx, expected %#lx.\n",
4936 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
4938 IDirectDrawSurface_Release(surface
);
4941 refcount
= IDirectDraw_Release(ddraw
);
4942 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
4943 DestroyWindow(window
);
4946 static void test_surface_lock(void)
4949 IDirectDrawSurface
*surface
;
4950 IDirect3DDevice
*device
;
4965 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
4966 "videomemory offscreenplain"
4969 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4970 "systemmemory offscreenplain"
4973 DDSCAPS_PRIMARYSURFACE
,
4977 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
4978 "videomemory texture"
4981 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
4982 "systemmemory texture"
4985 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4994 window
= create_window();
4995 ddraw
= create_ddraw();
4996 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4997 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4999 skip("Failed to create a 3D device, skipping test.\n");
5000 IDirectDraw_Release(ddraw
);
5001 DestroyWindow(window
);
5004 z_depth
= get_device_z_depth(device
);
5005 ok(!!z_depth
, "Failed to get device z depth.\n");
5006 IDirect3DDevice_Release(device
);
5008 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5010 memset(&ddsd
, 0, sizeof(ddsd
));
5011 ddsd
.dwSize
= sizeof(ddsd
);
5012 ddsd
.dwFlags
= DDSD_CAPS
;
5013 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5015 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5019 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
5021 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5022 U2(ddsd
).dwZBufferBitDepth
= z_depth
;
5024 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5026 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5027 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5029 memset(&ddsd
, 0, sizeof(ddsd
));
5030 ddsd
.dwSize
= sizeof(ddsd
);
5031 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5032 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5035 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5036 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5039 memset(&ddsd
, 0, sizeof(ddsd
));
5040 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5041 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, tests
[i
].name
);
5043 IDirectDrawSurface_Release(surface
);
5046 refcount
= IDirectDraw_Release(ddraw
);
5047 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5048 DestroyWindow(window
);
5051 static void test_surface_discard(void)
5054 IDirect3DDevice
*device
;
5058 IDirectDrawSurface
*surface
, *target
;
5067 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5068 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5069 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5070 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5074 window
= create_window();
5076 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5080 /* Sigh. Anything other than the first run of the loop randomly fails with
5081 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
5082 * the blit fails, but with sleeps added between surface creation and lock
5083 * the lock can fail too. Interestingly ddraw claims the render target has
5084 * been lost, not the test surface.
5086 * Recreating ddraw every iteration seems to fix this. */
5087 ddraw
= create_ddraw();
5088 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5089 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5091 skip("Failed to create a 3D device, skipping test.\n");
5092 IDirectDraw_Release(ddraw
);
5093 DestroyWindow(window
);
5097 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void**)&target
);
5098 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5100 memset(&ddsd
, 0, sizeof(ddsd
));
5101 ddsd
.dwSize
= sizeof(ddsd
);
5102 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5103 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5106 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5109 skip("Failed to create surface, skipping.\n");
5113 memset(&ddsd
, 0, sizeof(ddsd
));
5114 ddsd
.dwSize
= sizeof(ddsd
);
5115 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5116 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5117 addr
= ddsd
.lpSurface
;
5118 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5119 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5121 memset(&ddsd
, 0, sizeof(ddsd
));
5122 ddsd
.dwSize
= sizeof(ddsd
);
5123 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5124 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5125 discarded
= ddsd
.lpSurface
!= addr
;
5126 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5127 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5129 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
5130 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
5132 memset(&ddsd
, 0, sizeof(ddsd
));
5133 ddsd
.dwSize
= sizeof(ddsd
);
5134 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5135 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5136 discarded
|= ddsd
.lpSurface
!= addr
;
5137 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5138 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5140 IDirectDrawSurface_Release(surface
);
5142 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
5143 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
5144 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
5146 IDirectDrawSurface_Release(target
);
5147 IDirect3DDevice_Release(device
);
5148 IDirectDraw_Release(ddraw
);
5151 DestroyWindow(window
);
5154 static void test_flip(void)
5156 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5157 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5158 DDSCAPS caps
= {DDSCAPS_FLIP
};
5159 DDSURFACEDESC surface_desc
;
5160 unsigned int color
, i
;
5161 BOOL sysmem_primary
;
5163 DWORD expected_caps
;
5175 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5176 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5177 {"TEXTURE", DDSCAPS_TEXTURE
},
5180 window
= create_window();
5181 ddraw
= create_ddraw();
5182 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5184 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5185 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5187 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5189 /* Creating a flippable texture induces a BSoD on some versions of the
5190 * Intel graphics driver. At least Intel GMA 950 with driver version
5191 * 6.14.10.4926 on Windows XP SP3 is affected. */
5192 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5194 win_skip("Skipping flippable texture test.\n");
5198 memset(&surface_desc
, 0, sizeof(surface_desc
));
5199 surface_desc
.dwSize
= sizeof(surface_desc
);
5200 surface_desc
.dwFlags
= DDSD_CAPS
;
5201 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5202 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5203 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5204 surface_desc
.dwWidth
= 512;
5205 surface_desc
.dwHeight
= 512;
5206 surface_desc
.dwBackBufferCount
= 3;
5207 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5208 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5210 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5211 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5212 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5213 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5215 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5216 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5217 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5218 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5220 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5221 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5222 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5223 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5227 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5228 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5229 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5230 ok(hr
== DD_OK
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5231 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5232 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5233 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5235 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5236 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5237 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5238 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5239 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5240 hr
= restore_surfaces(ddraw
);
5241 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#lx.\n", test_data
[i
].name
, hr
);
5243 memset(&surface_desc
, 0, sizeof(surface_desc
));
5244 surface_desc
.dwSize
= sizeof(surface_desc
);
5245 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5246 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5247 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5248 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5249 expected_caps
|= DDSCAPS_VISIBLE
;
5250 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5251 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5252 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5254 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5255 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5256 memset(&surface_desc
, 0, sizeof(surface_desc
));
5257 surface_desc
.dwSize
= sizeof(surface_desc
);
5258 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5259 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5260 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5261 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5262 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5263 expected_caps
|= DDSCAPS_BACKBUFFER
;
5264 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5265 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5267 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5268 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5269 memset(&surface_desc
, 0, sizeof(surface_desc
));
5270 surface_desc
.dwSize
= sizeof(surface_desc
);
5271 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5272 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5273 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5274 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5275 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5276 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5277 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5279 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5280 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5281 memset(&surface_desc
, 0, sizeof(surface_desc
));
5282 surface_desc
.dwSize
= sizeof(surface_desc
);
5283 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5284 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5285 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5286 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5287 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5288 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5290 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5291 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5292 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5293 test_data
[i
].name
, surface
, frontbuffer
);
5294 IDirectDrawSurface_Release(surface
);
5296 memset(&surface_desc
, 0, sizeof(surface_desc
));
5297 surface_desc
.dwSize
= sizeof(surface_desc
);
5298 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5299 surface_desc
.ddsCaps
.dwCaps
= 0;
5300 surface_desc
.dwWidth
= 640;
5301 surface_desc
.dwHeight
= 480;
5302 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5303 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5304 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5305 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5306 IDirectDrawSurface_Release(surface
);
5308 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5309 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5310 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5311 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5312 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5313 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5314 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5315 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5317 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5318 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5319 * as a workaround. */
5320 fill_surface(backbuffer1
, 0xffff0000);
5321 fill_surface(backbuffer2
, 0xff00ff00);
5322 fill_surface(backbuffer3
, 0xff0000ff);
5324 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5325 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5326 color
= get_surface_color(backbuffer1
, 320, 240);
5327 /* The testbot seems to just copy the contents of one surface to all the
5328 * others, instead of properly flipping. */
5329 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5330 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5331 color
= get_surface_color(backbuffer2
, 320, 240);
5332 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5333 fill_surface(backbuffer3
, 0xffff0000);
5335 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5336 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5337 color
= get_surface_color(backbuffer1
, 320, 240);
5338 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5339 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5340 color
= get_surface_color(backbuffer2
, 320, 240);
5341 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5342 fill_surface(backbuffer3
, 0xff00ff00);
5344 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5345 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5346 color
= get_surface_color(backbuffer1
, 320, 240);
5347 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5348 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5349 color
= get_surface_color(backbuffer2
, 320, 240);
5350 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5351 fill_surface(backbuffer3
, 0xff0000ff);
5353 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5354 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5355 color
= get_surface_color(backbuffer2
, 320, 240);
5356 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5357 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5358 color
= get_surface_color(backbuffer3
, 320, 240);
5359 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5360 fill_surface(backbuffer1
, 0xffff0000);
5362 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5363 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5364 color
= get_surface_color(backbuffer1
, 320, 240);
5365 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5366 color
= get_surface_color(backbuffer3
, 320, 240);
5367 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5368 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5369 fill_surface(backbuffer2
, 0xff00ff00);
5371 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5372 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5373 color
= get_surface_color(backbuffer1
, 320, 240);
5374 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5375 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5376 color
= get_surface_color(backbuffer2
, 320, 240);
5377 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5379 IDirectDrawSurface_Release(backbuffer3
);
5380 IDirectDrawSurface_Release(backbuffer2
);
5381 IDirectDrawSurface_Release(backbuffer1
);
5382 IDirectDrawSurface_Release(frontbuffer
);
5385 refcount
= IDirectDraw_Release(ddraw
);
5386 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5387 DestroyWindow(window
);
5390 static void test_sysmem_overlay(void)
5396 IDirectDrawSurface
*surface
;
5399 window
= create_window();
5400 ddraw
= create_ddraw();
5401 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5403 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5404 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5406 memset(&ddsd
, 0, sizeof(ddsd
));
5407 ddsd
.dwSize
= sizeof(ddsd
);
5408 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5411 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5412 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5413 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5414 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
5415 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
5416 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
5417 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
5418 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5419 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#lx.\n", hr
);
5421 ref
= IDirectDraw_Release(ddraw
);
5422 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
5423 DestroyWindow(window
);
5426 static void test_primary_palette(void)
5428 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5429 IDirectDrawSurface
*primary
, *backbuffer
;
5430 PALETTEENTRY palette_entries
[256];
5431 IDirectDrawPalette
*palette
, *tmp
;
5432 DDSURFACEDESC surface_desc
;
5439 window
= create_window();
5440 ddraw
= create_ddraw();
5441 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5442 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
5444 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
5445 IDirectDraw_Release(ddraw
);
5446 DestroyWindow(window
);
5449 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5450 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5452 memset(&surface_desc
, 0, sizeof(surface_desc
));
5453 surface_desc
.dwSize
= sizeof(surface_desc
);
5454 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5455 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5456 surface_desc
.dwBackBufferCount
= 1;
5457 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5458 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5459 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5460 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
5462 memset(palette_entries
, 0, sizeof(palette_entries
));
5463 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5464 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
5465 refcount
= get_refcount((IUnknown
*)palette
);
5466 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5468 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5469 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5470 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
5472 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5473 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5475 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
5476 * and is generally somewhat broken with respect to 8 bpp / palette
5478 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
5480 win_skip("Broken palette handling detected, skipping tests.\n");
5481 IDirectDrawPalette_Release(tmp
);
5482 IDirectDrawPalette_Release(palette
);
5483 /* The Windows 8 testbot keeps extra references to the primary and
5484 * backbuffer while in 8 bpp mode. */
5485 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
5486 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
5490 refcount
= get_refcount((IUnknown
*)palette
);
5491 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5493 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5494 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5495 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5496 "Got unexpected palette caps %#lx.\n", palette_caps
);
5498 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5499 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5500 refcount
= get_refcount((IUnknown
*)palette
);
5501 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5503 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5504 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5505 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
5507 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5508 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5509 refcount
= get_refcount((IUnknown
*)palette
);
5510 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5512 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5513 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
5514 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5515 IDirectDrawPalette_Release(tmp
);
5516 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5517 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5519 refcount
= IDirectDrawPalette_Release(palette
);
5520 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5521 refcount
= IDirectDrawPalette_Release(palette
);
5522 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5524 /* Note that this only seems to work when the palette is attached to the
5525 * primary surface. When attached to a regular surface, attempting to get
5526 * the palette here will cause an access violation. */
5527 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5528 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5530 hr
= IDirectDrawSurface_IsLost(primary
);
5531 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5533 memset(&surface_desc
, 0, sizeof(surface_desc
));
5534 surface_desc
.dwSize
= sizeof(surface_desc
);
5535 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5536 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5537 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5538 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5539 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %lu.\n",
5540 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5542 hr
= set_display_mode(ddraw
, 640, 480);
5543 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
5545 memset(&surface_desc
, 0, sizeof(surface_desc
));
5546 surface_desc
.dwSize
= sizeof(surface_desc
);
5547 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5548 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5549 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5550 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5551 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
5552 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
5553 "Got unexpected bit count %lu.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5555 hr
= IDirectDrawSurface_IsLost(primary
);
5556 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
5557 hr
= IDirectDrawSurface_Restore(primary
);
5558 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
5559 hr
= IDirectDrawSurface_IsLost(primary
);
5560 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
5562 memset(&surface_desc
, 0, sizeof(surface_desc
));
5563 surface_desc
.dwSize
= sizeof(surface_desc
);
5564 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5565 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5566 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5567 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5568 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 32
5569 || U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== 24,
5570 "Got unexpected bit count %lu.\n", U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
5573 refcount
= IDirectDrawSurface_Release(backbuffer
);
5574 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5575 refcount
= IDirectDrawSurface_Release(primary
);
5576 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5577 refcount
= IDirectDraw_Release(ddraw
);
5578 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5579 DestroyWindow(window
);
5582 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5584 UINT
*surface_count
= context
;
5587 IDirectDrawSurface_Release(surface
);
5589 return DDENUMRET_OK
;
5592 static void test_surface_attachment(void)
5594 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5595 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5596 DDSURFACEDESC surface_desc
;
5603 window
= create_window();
5604 ddraw
= create_ddraw();
5605 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5606 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5607 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5609 memset(&surface_desc
, 0, sizeof(surface_desc
));
5610 surface_desc
.dwSize
= sizeof(surface_desc
);
5611 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5612 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5613 U2(surface_desc
).dwMipMapCount
= 3;
5614 surface_desc
.dwWidth
= 128;
5615 surface_desc
.dwHeight
= 128;
5616 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5617 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5619 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5620 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
5621 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5622 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
5623 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5624 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
5627 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5628 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5630 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5631 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5633 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5634 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5636 memset(&surface_desc
, 0, sizeof(surface_desc
));
5637 surface_desc
.dwSize
= sizeof(surface_desc
);
5638 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5639 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5640 surface_desc
.dwWidth
= 16;
5641 surface_desc
.dwHeight
= 16;
5642 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5643 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5645 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5646 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5647 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5648 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5649 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5650 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5651 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5652 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5653 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5654 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5655 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5656 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5658 IDirectDrawSurface_Release(surface4
);
5660 memset(&surface_desc
, 0, sizeof(surface_desc
));
5661 surface_desc
.dwSize
= sizeof(surface_desc
);
5662 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5663 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5664 surface_desc
.dwWidth
= 16;
5665 surface_desc
.dwHeight
= 16;
5666 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5667 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5669 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5671 skip("Running on refrast, skipping some tests.\n");
5672 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5673 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5677 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5678 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5679 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5680 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5681 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5682 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5683 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5684 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5685 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5686 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5687 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5690 IDirectDrawSurface_Release(surface4
);
5691 IDirectDrawSurface_Release(surface3
);
5692 IDirectDrawSurface_Release(surface2
);
5693 IDirectDrawSurface_Release(surface1
);
5695 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5696 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5698 /* Try a single primary and two offscreen plain surfaces. */
5699 memset(&surface_desc
, 0, sizeof(surface_desc
));
5700 surface_desc
.dwSize
= sizeof(surface_desc
);
5701 surface_desc
.dwFlags
= DDSD_CAPS
;
5702 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5703 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5704 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5706 memset(&surface_desc
, 0, sizeof(surface_desc
));
5707 surface_desc
.dwSize
= sizeof(surface_desc
);
5708 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5709 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5710 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5711 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5712 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5713 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5715 memset(&surface_desc
, 0, sizeof(surface_desc
));
5716 surface_desc
.dwSize
= sizeof(surface_desc
);
5717 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5718 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5719 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5720 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5721 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5722 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5724 /* This one has a different size. */
5725 memset(&surface_desc
, 0, sizeof(surface_desc
));
5726 surface_desc
.dwSize
= sizeof(surface_desc
);
5727 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5728 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5729 surface_desc
.dwWidth
= 128;
5730 surface_desc
.dwHeight
= 128;
5731 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5732 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5734 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5735 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5736 /* Try the reverse without detaching first. */
5737 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5738 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5739 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5740 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5742 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5743 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5744 /* Try to detach reversed. */
5745 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5746 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5747 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
5748 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5750 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
5751 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5752 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
5753 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5755 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5756 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5757 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5758 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5760 IDirectDrawSurface_Release(surface4
);
5761 IDirectDrawSurface_Release(surface3
);
5762 IDirectDrawSurface_Release(surface2
);
5763 IDirectDrawSurface_Release(surface1
);
5765 /* Test depth surfaces of different sizes. */
5766 memset(&surface_desc
, 0, sizeof(surface_desc
));
5767 surface_desc
.dwSize
= sizeof(surface_desc
);
5768 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5769 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5770 surface_desc
.dwWidth
= 64;
5771 surface_desc
.dwHeight
= 64;
5772 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5773 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5775 memset(&surface_desc
, 0, sizeof(surface_desc
));
5776 surface_desc
.dwSize
= sizeof(surface_desc
);
5777 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5778 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5779 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5780 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5781 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
5782 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
5783 surface_desc
.dwWidth
= 32;
5784 surface_desc
.dwHeight
= 32;
5785 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5786 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5787 surface_desc
.dwWidth
= 64;
5788 surface_desc
.dwHeight
= 64;
5789 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5790 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5791 surface_desc
.dwWidth
= 128;
5792 surface_desc
.dwHeight
= 128;
5793 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5794 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5796 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5797 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5799 IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5800 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
5801 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#lx.\n", hr
);
5802 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface3
);
5803 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#lx.\n", hr
);
5804 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5805 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5807 IDirectDrawSurface_Release(surface4
);
5808 IDirectDrawSurface_Release(surface3
);
5809 IDirectDrawSurface_Release(surface2
);
5810 IDirectDrawSurface_Release(surface1
);
5812 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
5813 memset(&surface_desc
, 0, sizeof(surface_desc
));
5814 surface_desc
.dwSize
= sizeof(surface_desc
);
5815 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5816 surface_desc
.dwWidth
= 64;
5817 surface_desc
.dwHeight
= 64;
5818 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5819 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5820 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
5821 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
5822 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
5823 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
5824 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
5825 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5826 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5827 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5828 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5830 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5831 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5832 U1(surface_desc
.ddpfPixelFormat
).dwZBufferBitDepth
= 16;
5833 U3(surface_desc
.ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
5834 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5835 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5837 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5838 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5839 refcount
= get_refcount((IUnknown
*)surface2
);
5840 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5841 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5842 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5844 /* Attaching while already attached to other surface. */
5845 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
5846 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5847 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
5848 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5849 IDirectDrawSurface_Release(surface3
);
5851 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5852 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5853 refcount
= get_refcount((IUnknown
*)surface2
);
5854 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5856 /* Automatic detachment on release. */
5857 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5858 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5859 refcount
= get_refcount((IUnknown
*)surface2
);
5860 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5861 refcount
= IDirectDrawSurface_Release(surface1
);
5862 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5863 refcount
= IDirectDrawSurface_Release(surface2
);
5864 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5865 refcount
= IDirectDraw_Release(ddraw
);
5866 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5867 DestroyWindow(window
);
5870 static void test_pixel_format(void)
5872 HWND window
, window2
= NULL
;
5873 HDC hdc
, hdc2
= NULL
;
5875 int format
, test_format
;
5876 PIXELFORMATDESCRIPTOR pfd
;
5877 IDirectDraw
*ddraw
= NULL
;
5878 IDirectDrawClipper
*clipper
= NULL
;
5880 IDirectDrawSurface
*primary
= NULL
, *offscreen
;
5884 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5885 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5888 skip("Failed to create window\n");
5892 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5893 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
5895 hdc
= GetDC(window
);
5898 skip("Failed to get DC\n");
5903 hdc2
= GetDC(window2
);
5905 gl
= LoadLibraryA("opengl32.dll");
5906 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
5908 format
= GetPixelFormat(hdc
);
5909 ok(format
== 0, "new window has pixel format %d\n", format
);
5911 ZeroMemory(&pfd
, sizeof(pfd
));
5912 pfd
.nSize
= sizeof(pfd
);
5914 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
5915 pfd
.iPixelType
= PFD_TYPE_RGBA
;
5916 pfd
.iLayerType
= PFD_MAIN_PLANE
;
5917 format
= ChoosePixelFormat(hdc
, &pfd
);
5920 skip("no pixel format available\n");
5924 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
5926 skip("failed to set pixel format\n");
5930 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5932 skip("failed to set pixel format on second window\n");
5935 ReleaseDC(window2
, hdc2
);
5940 ddraw
= create_ddraw();
5941 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5943 test_format
= GetPixelFormat(hdc
);
5944 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5946 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5949 skip("Failed to set cooperative level, hr %#lx.\n", hr
);
5953 test_format
= GetPixelFormat(hdc
);
5954 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5958 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
5959 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
5960 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
5961 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
5963 test_format
= GetPixelFormat(hdc
);
5964 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5966 test_format
= GetPixelFormat(hdc2
);
5967 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5970 memset(&ddsd
, 0, sizeof(ddsd
));
5971 ddsd
.dwSize
= sizeof(ddsd
);
5972 ddsd
.dwFlags
= DDSD_CAPS
;
5973 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5975 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
5976 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
5978 test_format
= GetPixelFormat(hdc
);
5979 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5983 test_format
= GetPixelFormat(hdc2
);
5984 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5989 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
5990 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
5992 test_format
= GetPixelFormat(hdc
);
5993 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
5995 test_format
= GetPixelFormat(hdc2
);
5996 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
5999 memset(&ddsd
, 0, sizeof(ddsd
));
6000 ddsd
.dwSize
= sizeof(ddsd
);
6001 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6002 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6003 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
6004 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
6005 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
6007 memset(&fx
, 0, sizeof(fx
));
6008 fx
.dwSize
= sizeof(fx
);
6009 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6010 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
6012 test_format
= GetPixelFormat(hdc
);
6013 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6015 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
6016 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
6018 test_format
= GetPixelFormat(hdc
);
6019 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6023 test_format
= GetPixelFormat(hdc2
);
6024 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6027 IDirectDrawSurface_Release(offscreen
);
6030 if (primary
) IDirectDrawSurface_Release(primary
);
6031 if (clipper
) IDirectDrawClipper_Release(clipper
);
6032 if (ddraw
) IDirectDraw_Release(ddraw
);
6033 if (gl
) FreeLibrary(gl
);
6034 if (hdc
) ReleaseDC(window
, hdc
);
6035 if (hdc2
) ReleaseDC(window2
, hdc2
);
6036 DestroyWindow(window
);
6037 if (window2
) DestroyWindow(window2
);
6040 static void test_create_surface_pitch(void)
6042 IDirectDrawSurface
*surface
, *primary
;
6043 DDSURFACEDESC surface_desc
;
6044 DDCAPS caps1
, caps2
;
6065 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6067 DDSD_PITCH
, 0x100, 0x100},
6068 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6069 DDSD_PITCH
, 0x104, DD_OK
,
6070 DDSD_PITCH
, 0x100, 0x100},
6071 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6072 DDSD_PITCH
, 0x0f8, DD_OK
,
6073 DDSD_PITCH
, 0x100, 0x100},
6074 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6075 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6077 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6079 DDSD_PITCH
, 0x100, 0x0fc},
6081 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6082 DDSD_PITCH
, 0x104, DD_OK
,
6083 DDSD_PITCH
, 0x100, 0x0fc},
6084 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6085 DDSD_PITCH
, 0x0f8, DD_OK
,
6086 DDSD_PITCH
, 0x100, 0x0fc},
6087 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6088 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
6089 DDSD_PITCH
, 0x100, 0x0fc},
6090 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6091 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
6093 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6094 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6097 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6098 0, 0, DDERR_INVALIDCAPS
,
6100 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6102 DDSD_PITCH
, 0x100, 0 },
6103 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
,
6105 DDSD_PITCH
, 0x100, 0 },
6106 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6107 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6109 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6110 0, 0, DDERR_INVALIDCAPS
,
6113 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6115 DDSD_PITCH
, 0x100, 0 },
6116 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6117 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6120 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
6122 window
= create_window();
6123 ddraw
= create_ddraw();
6124 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6125 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
6126 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6128 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
6130 /* We need a primary surface and exclusive mode for video memory accounting to work
6131 * right on Windows. Otherwise it gives us junk data, like creating a video memory
6132 * surface freeing up memory. */
6133 memset(&surface_desc
, 0, sizeof(surface_desc
));
6134 surface_desc
.dwSize
= sizeof(surface_desc
);
6135 surface_desc
.dwFlags
= DDSD_CAPS
;
6136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6137 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6138 ok(SUCCEEDED(hr
), "Failed to create a primary surface, hr %#lx.\n", hr
);
6140 memset(&caps1
, 0, sizeof(caps1
));
6141 caps1
.dwSize
= sizeof(caps1
);
6142 hr
= IDirectDraw_GetCaps(ddraw
, &caps1
, NULL
);
6143 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6145 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6147 memset(&surface_desc
, 0, sizeof(surface_desc
));
6148 surface_desc
.dwSize
= sizeof(surface_desc
);
6149 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
6150 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6151 surface_desc
.dwWidth
= 63;
6152 surface_desc
.dwHeight
= 63;
6153 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
6154 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6155 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6156 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6157 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6158 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6159 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6160 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6161 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
6163 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
6164 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, expected_hr
);
6165 surface_desc
.lpSurface
= mem
;
6166 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6168 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
6170 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
6174 memset(&surface_desc
, 0, sizeof(surface_desc
));
6175 surface_desc
.dwSize
= sizeof(surface_desc
);
6176 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6177 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
6178 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
6179 "Test %u: Got unexpected flags %#lx, expected %#lx.\n",
6180 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
6181 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
6183 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
6184 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
6185 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
6186 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
6188 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
6189 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
6190 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
6192 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
6194 memset(&caps2
, 0, sizeof(caps2
));
6195 caps2
.dwSize
= sizeof(caps2
);
6196 hr
= IDirectDraw_GetCaps(ddraw
, &caps2
, NULL
);
6197 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6198 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
6200 /* Star Trek Starfleet Academy cares about this bit here: That creating a system memory
6201 * resource does not influence available video memory. */
6202 ok(caps2
.dwVidMemFree
== caps1
.dwVidMemFree
, "Free video memory changed from %#lx to %#lx, test %u.\n",
6203 caps1
.dwVidMemFree
, caps2
.dwVidMemFree
, i
);
6205 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6207 /* DDSCAPS_ALLOCONLOAD does not seem to delay video memory allocation, at least not on
6210 * The amount of video memory consumed is different from what dwHeight * lPitch would
6211 * suggest, although not by much. */
6212 ok(caps2
.dwVidMemFree
< caps1
.dwVidMemFree
,
6213 "Expected free video memory to change, but it did not, test %u.\n", i
);
6216 IDirectDrawSurface_Release(surface
);
6218 hr
= IDirectDraw_GetCaps(ddraw
, &caps2
, NULL
);
6219 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6220 ok(caps2
.dwVidMemFree
== caps1
.dwVidMemFree
, "Free video memory changed from %#lx to %#lx, test %u.\n",
6221 caps1
.dwVidMemFree
, caps2
.dwVidMemFree
, i
);
6224 HeapFree(GetProcessHeap(), 0, mem
);
6225 refcount
= IDirectDraw_Release(ddraw
);
6226 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6227 DestroyWindow(window
);
6230 static void test_mipmap(void)
6232 IDirectDrawSurface
*surface
, *surface_base
, *surface_mip
;
6233 unsigned int i
, mipmap_count
;
6234 DDSURFACEDESC surface_desc
;
6239 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6248 DWORD mipmap_count_in
;
6250 DWORD mipmap_count_out
;
6254 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
6255 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
6256 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
6257 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
6258 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
6259 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
6262 window
= create_window();
6263 ddraw
= create_ddraw();
6264 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6265 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6266 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6268 memset(&hal_caps
, 0, sizeof(hal_caps
));
6269 hal_caps
.dwSize
= sizeof(hal_caps
);
6270 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
6271 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6272 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6274 skip("Mipmapped textures not supported, skipping tests.\n");
6275 IDirectDraw_Release(ddraw
);
6276 DestroyWindow(window
);
6280 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6282 memset(&surface_desc
, 0, sizeof(surface_desc
));
6283 surface_desc
.dwSize
= sizeof(surface_desc
);
6284 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
6285 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6286 surface_desc
.dwWidth
= tests
[i
].width
;
6287 surface_desc
.dwHeight
= tests
[i
].height
;
6288 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
6289 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
6290 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6291 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
6295 memset(&surface_desc
, 0, sizeof(surface_desc
));
6296 surface_desc
.dwSize
= sizeof(surface_desc
);
6297 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6298 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
6299 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6300 "Test %u: Got unexpected flags %#lx.\n", i
, surface_desc
.dwFlags
);
6301 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
6302 "Test %u: Got unexpected mipmap count %lu.\n", i
, U2(surface_desc
).dwMipMapCount
);
6304 surface_base
= surface
;
6305 IDirectDrawSurface2_AddRef(surface_base
);
6306 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
6307 while (mipmap_count
> 1)
6309 hr
= IDirectDrawSurface_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
6310 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6312 memset(&surface_desc
, 0, sizeof(surface_desc
));
6313 surface_desc
.dwSize
= sizeof(surface_desc
);
6314 hr
= IDirectDrawSurface_GetSurfaceDesc(surface_base
, &surface_desc
);
6315 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#lx.\n", i
, mipmap_count
, hr
);
6316 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6317 "Test %u, %u: Got unexpected flags %#lx.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
6318 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
6319 "Test %u, %u: Got unexpected mipmap count %lu.\n",
6320 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
6322 memset(&surface_desc
, 0, sizeof(surface_desc
));
6323 surface_desc
.dwSize
= sizeof(surface_desc
);
6324 hr
= IDirectDrawSurface_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
6325 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6326 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
6327 "Test %u, %u: unexpected change of mipmap count %lu.\n",
6328 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6329 memset(&surface_desc
, 0, sizeof(surface_desc
));
6330 surface_desc
.dwSize
= sizeof(surface_desc
);
6331 hr
= IDirectDrawSurface_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
6332 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6333 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
6334 "Test %u, %u: Got unexpected child mipmap count %lu.\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6335 IDirectDrawSurface_Unlock(surface_mip
, NULL
);
6336 IDirectDrawSurface_Unlock(surface_base
, NULL
);
6338 IDirectDrawSurface_Release(surface_base
);
6339 surface_base
= surface_mip
;
6342 IDirectDrawSurface_Release(surface_base
);
6344 IDirectDrawSurface_Release(surface
);
6347 refcount
= IDirectDraw_Release(ddraw
);
6348 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6349 DestroyWindow(window
);
6352 static void test_palette_complex(void)
6354 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
6355 DDSURFACEDESC surface_desc
;
6357 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
6361 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6363 PALETTEENTRY palette_entries
[256];
6369 window
= create_window();
6370 ddraw
= create_ddraw();
6371 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6372 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6373 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6375 memset(&hal_caps
, 0, sizeof(hal_caps
));
6376 hal_caps
.dwSize
= sizeof(hal_caps
);
6377 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
6378 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6379 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6381 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
6382 IDirectDraw_Release(ddraw
);
6383 DestroyWindow(window
);
6387 memset(&surface_desc
, 0, sizeof(surface_desc
));
6388 surface_desc
.dwSize
= sizeof(surface_desc
);
6389 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6390 surface_desc
.dwWidth
= 128;
6391 surface_desc
.dwHeight
= 128;
6392 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6393 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6394 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6395 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6396 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6397 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6399 memset(palette_entries
, 0, sizeof(palette_entries
));
6400 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6401 palette_entries
, &palette
, NULL
);
6402 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6404 memset(palette_entries
, 0, sizeof(palette_entries
));
6405 palette_entries
[1].peRed
= 0xff;
6406 palette_entries
[1].peGreen
= 0x80;
6407 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6408 palette_entries
, &palette_mipmap
, NULL
);
6409 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6411 palette2
= (void *)0xdeadbeef;
6412 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
6413 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6414 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
6415 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6416 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6417 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
6418 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
6419 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
6420 IDirectDrawPalette_Release(palette2
);
6423 IDirectDrawSurface_AddRef(mipmap
);
6424 for (i
= 0; i
< 7; ++i
)
6426 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6427 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
6428 palette2
= (void *)0xdeadbeef;
6429 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
6430 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
6431 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
6433 hr
= IDirectDrawSurface_SetPalette(tmp
, palette_mipmap
);
6434 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#lx.\n", i
, hr
);
6436 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
6437 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#lx.\n", i
, hr
);
6438 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
6439 IDirectDrawPalette_Release(palette2
);
6441 hr
= IDirectDrawSurface_GetDC(tmp
, &dc
);
6442 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#lx.\n", i
, hr
);
6443 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6444 ok(count
== 1, "Expected count 1, got %u.\n", count
);
6445 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
6446 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
6447 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
6448 hr
= IDirectDrawSurface_ReleaseDC(tmp
, dc
);
6449 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#lx.\n", i
, hr
);
6451 IDirectDrawSurface_Release(mipmap
);
6455 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6456 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6457 IDirectDrawSurface_Release(mipmap
);
6458 refcount
= IDirectDrawSurface_Release(surface
);
6459 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6460 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
6461 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6462 refcount
= IDirectDrawPalette_Release(palette
);
6463 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6465 refcount
= IDirectDraw_Release(ddraw
);
6466 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6467 DestroyWindow(window
);
6470 static void test_p8_blit(void)
6472 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
6473 DDSURFACEDESC surface_desc
;
6474 unsigned int color
, x
;
6476 IDirectDrawPalette
*palette
, *palette2
;
6480 PALETTEENTRY palette_entries
[256];
6483 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
6484 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
6485 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
6486 static const unsigned int expected
[] =
6488 0x00101010, 0x00010101, 0x00020202, 0x00030303,
6489 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
6492 window
= create_window();
6493 ddraw
= create_ddraw();
6494 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6495 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6496 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6497 is_warp
= ddraw_is_warp(ddraw
);
6499 memset(palette_entries
, 0, sizeof(palette_entries
));
6500 palette_entries
[1].peGreen
= 0xff;
6501 palette_entries
[2].peBlue
= 0xff;
6502 palette_entries
[3].peFlags
= 0xff;
6503 palette_entries
[4].peRed
= 0xff;
6504 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6505 palette_entries
, &palette
, NULL
);
6506 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6507 palette_entries
[1].peBlue
= 0xff;
6508 palette_entries
[2].peGreen
= 0xff;
6509 palette_entries
[3].peRed
= 0xff;
6510 palette_entries
[4].peFlags
= 0x0;
6511 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6512 palette_entries
, &palette2
, NULL
);
6513 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6515 memset(&surface_desc
, 0, sizeof(surface_desc
));
6516 surface_desc
.dwSize
= sizeof(surface_desc
);
6517 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6518 surface_desc
.dwWidth
= 8;
6519 surface_desc
.dwHeight
= 1;
6520 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6521 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6522 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6523 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
6524 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
6525 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6526 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
6527 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6528 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
6529 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6531 memset(&surface_desc
, 0, sizeof(surface_desc
));
6532 surface_desc
.dwSize
= sizeof(surface_desc
);
6533 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6534 surface_desc
.dwWidth
= 8;
6535 surface_desc
.dwHeight
= 1;
6536 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6537 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6538 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
6539 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
6540 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6541 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6542 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6543 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
6544 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
6545 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6547 memset(&surface_desc
, 0, sizeof(surface_desc
));
6548 surface_desc
.dwSize
= sizeof(surface_desc
);
6549 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6550 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
6551 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
6552 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
6553 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
6555 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6556 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
6557 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
6558 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6559 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
6561 fx
.dwSize
= sizeof(fx
);
6562 fx
.dwFillColor
= 0xdeadbeef;
6563 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6564 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6566 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
6567 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6568 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
6569 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
6570 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
6571 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
6572 "Failed to blit, hr %#lx.\n", hr
);
6576 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
6578 color
= get_surface_color(dst
, x
, 0);
6579 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
6580 * blits see below. */
6581 todo_wine
ok(compare_color(color
, expected
[x
], 0)
6582 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
6583 "Pixel %u: Got color %#x, expected %#x.\n",
6584 x
, color
, expected
[x
]);
6588 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
6589 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
6590 hr
= IDirectDrawSurface_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
6591 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
6593 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
6594 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
6595 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
6596 * surface untouched. Error checking (DDBLT_KEYSRC without a key
6597 * for example) also works as expected.
6599 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
6600 * the display mode set to P8 doesn't help either. */
6601 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
6602 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
6603 "Got unexpected P8 color key blit result.\n");
6604 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6605 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
6607 IDirectDrawSurface_Release(src
);
6608 IDirectDrawSurface_Release(dst
);
6609 IDirectDrawSurface_Release(dst_p8
);
6610 IDirectDrawPalette_Release(palette
);
6611 IDirectDrawPalette_Release(palette2
);
6613 refcount
= IDirectDraw_Release(ddraw
);
6614 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6615 DestroyWindow(window
);
6618 static void test_material(void)
6620 IDirect3DMaterial
*background
, *material
;
6621 IDirect3DExecuteBuffer
*execute_buffer
;
6622 D3DMATERIALHANDLE mat_handle
, tmp
;
6623 D3DEXECUTEBUFFERDESC exec_desc
;
6624 IDirect3DViewport
*viewport
;
6625 IDirect3DDevice
*device
;
6626 IDirectDrawSurface
*rt
;
6627 unsigned int color
, i
;
6636 static D3DVERTEX quad
[] =
6638 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6639 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6640 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6641 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6646 D3DCOLOR expected_color
;
6651 {FALSE
, 0x00ffffff},
6653 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6655 window
= create_window();
6656 ddraw
= create_ddraw();
6657 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6658 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6660 skip("Failed to create a 3D device, skipping test.\n");
6661 DestroyWindow(window
);
6665 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
6666 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
6668 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
6669 viewport
= create_viewport(device
, 0, 0, 640, 480);
6670 viewport_set_background(device
, viewport
, background
);
6672 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
6673 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
6674 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
6676 memset(&exec_desc
, 0, sizeof(exec_desc
));
6677 exec_desc
.dwSize
= sizeof(exec_desc
);
6678 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
6679 exec_desc
.dwBufferSize
= 1024;
6680 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
6682 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
6683 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
6685 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6687 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6688 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
6690 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
6691 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
6692 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
6693 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
6694 emit_tquad(&ptr
, 0);
6696 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6697 inst_length
-= sizeof(quad
);
6699 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6700 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
6702 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
6703 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6705 hr
= IDirect3DDevice_BeginScene(device
);
6706 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
6707 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
6708 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6709 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
6710 hr
= IDirect3DDevice_EndScene(device
);
6711 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
6712 color
= get_surface_color(rt
, 320, 240);
6713 if (test_data
[i
].material
)
6714 ok(compare_color(color
, test_data
[i
].expected_color
, 1)
6715 /* The Windows 8 testbot appears to return undefined results. */
6717 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6719 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
6720 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6723 destroy_material(material
);
6724 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
6725 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
6726 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
6728 hr
= IDirect3DViewport_SetBackground(viewport
, mat_handle
);
6729 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
6730 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6731 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6732 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
6733 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6734 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6735 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6736 color
= get_surface_color(rt
, 320, 240);
6737 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6739 hr
= IDirect3DViewport_SetBackground(viewport
, 0);
6740 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
6741 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6742 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6743 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
6744 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6745 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6746 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6747 color
= get_surface_color(rt
, 320, 240);
6748 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6750 destroy_viewport(device
, viewport
);
6751 viewport
= create_viewport(device
, 0, 0, 640, 480);
6753 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6754 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6755 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
6756 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
6757 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6758 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6759 color
= get_surface_color(rt
, 320, 240);
6760 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
6762 IDirect3DExecuteBuffer_Release(execute_buffer
);
6763 destroy_viewport(device
, viewport
);
6764 destroy_material(background
);
6765 destroy_material(material
);
6766 IDirectDrawSurface_Release(rt
);
6767 refcount
= IDirect3DDevice_Release(device
);
6768 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6769 refcount
= IDirectDraw_Release(ddraw
);
6770 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
6771 DestroyWindow(window
);
6774 static void test_lighting(void)
6776 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6777 static D3DMATRIX mat
=
6779 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6780 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6781 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6782 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6786 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6787 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6788 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6789 0.0f
, 0.0f
, 0.5f
, 1.0f
,
6793 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6794 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6795 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
6796 10.f
, 10.0f
, 10.0f
, 1.0f
,
6800 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6801 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6802 0.0f
, 0.0f
, 1.0f
, -1.0f
,
6803 10.f
, 10.0f
, 10.0f
, 0.0f
,
6805 static D3DLVERTEX unlitquad
[] =
6807 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6808 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6809 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6810 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6814 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6815 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6816 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6817 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6819 static D3DVERTEX unlitnquad
[] =
6821 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6822 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6823 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6824 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6828 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6829 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6830 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6831 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6835 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6836 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6837 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6838 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6842 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6843 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6844 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6845 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6849 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6850 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6851 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6852 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6856 D3DMATRIX
*world_matrix
;
6859 const char *message
;
6863 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
6864 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
6865 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
6866 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
6869 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
6870 IDirect3DViewport
*viewport
, *viewport2
;
6871 IDirect3DExecuteBuffer
*execute_buffer
;
6872 unsigned int inst_length
, color
, i
;
6873 D3DEXECUTEBUFFERDESC exec_desc
;
6874 D3DMATERIALHANDLE mat_handle
;
6875 IDirect3DMaterial
*material
;
6876 IDirect3DDevice
*device
;
6877 IDirectDrawSurface
*rt
;
6878 IDirect3DLight
*light
;
6879 D3DLIGHT light_desc
;
6887 window
= create_window();
6888 ddraw
= create_ddraw();
6889 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6890 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6892 skip("Failed to create a 3D device, skipping test.\n");
6893 IDirectDraw_Release(ddraw
);
6894 DestroyWindow(window
);
6898 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
6899 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6901 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
6902 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6904 viewport
= create_viewport(device
, 0, 0, 640, 480);
6905 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
6906 viewport_set_background(device
, viewport
, material
);
6908 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6909 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6911 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
6912 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6913 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
6914 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6915 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
6916 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6917 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
6918 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6919 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
6920 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6921 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
6922 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6924 memset(&exec_desc
, 0, sizeof(exec_desc
));
6925 exec_desc
.dwSize
= sizeof(exec_desc
);
6926 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
6927 exec_desc
.dwBufferSize
= 1024;
6928 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
6930 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
6931 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6933 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6934 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6936 memcpy(exec_desc
.lpData
, unlitquad
, sizeof(unlitquad
));
6937 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitquad
);
6938 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
6939 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
6940 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
6941 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
6942 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
6943 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
6944 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
6945 emit_tquad_tlist(&ptr
, 0);
6947 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6948 inst_length
-= sizeof(unlitquad
);
6950 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6951 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6953 hr
= IDirect3DDevice_BeginScene(device
);
6954 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6956 set_execute_data(execute_buffer
, 4, sizeof(unlitquad
), inst_length
);
6957 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6958 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6960 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6961 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6963 memcpy(exec_desc
.lpData
, litquad
, sizeof(litquad
));
6964 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litquad
);
6965 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
6966 emit_tquad_tlist(&ptr
, 0);
6968 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6969 inst_length
-= sizeof(litquad
);
6971 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6972 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6974 set_execute_data(execute_buffer
, 4, sizeof(litquad
), inst_length
);
6975 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6976 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6978 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6979 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6981 memcpy(exec_desc
.lpData
, unlitnquad
, sizeof(unlitnquad
));
6982 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitnquad
);
6983 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
6984 emit_tquad_tlist(&ptr
, 0);
6986 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6987 inst_length
-= sizeof(unlitnquad
);
6989 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6990 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6992 set_execute_data(execute_buffer
, 4, sizeof(unlitnquad
), inst_length
);
6993 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6994 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6996 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6997 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6999 memcpy(exec_desc
.lpData
, litnquad
, sizeof(litnquad
));
7000 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litnquad
);
7001 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
7002 emit_tquad_tlist(&ptr
, 0);
7004 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7005 inst_length
-= sizeof(litnquad
);
7007 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7008 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7010 set_execute_data(execute_buffer
, 4, sizeof(litnquad
), inst_length
);
7011 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7012 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7014 hr
= IDirect3DDevice_EndScene(device
);
7015 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7017 color
= get_surface_color(rt
, 160, 360);
7018 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
7019 color
= get_surface_color(rt
, 160, 120);
7020 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
7021 color
= get_surface_color(rt
, 480, 360);
7022 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
7023 color
= get_surface_color(rt
, 480, 120);
7024 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
7026 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
7027 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7029 hr
= IDirect3D_CreateLight(d3d
, &light
, NULL
);
7030 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#lx.\n", hr
);
7031 memset(&light_desc
, 0, sizeof(light_desc
));
7032 light_desc
.dwSize
= sizeof(light_desc
);
7033 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
7034 U1(light_desc
.dcvColor
).r
= 0.0f
;
7035 U2(light_desc
.dcvColor
).g
= 0.25f
;
7036 U3(light_desc
.dcvColor
).b
= 1.0f
;
7037 U4(light_desc
.dcvColor
).a
= 1.0f
;
7038 U3(light_desc
.dvDirection
).z
= 1.0f
;
7039 hr
= IDirect3DLight_SetLight(light
, &light_desc
);
7040 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7041 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7042 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7043 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7044 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
7046 viewport2
= create_viewport(device
, 0, 0, 640, 480);
7047 hr
= IDirect3DViewport_AddLight(viewport2
, light
);
7048 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
7049 destroy_viewport(device
, viewport2
);
7051 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7052 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7053 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7054 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7056 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7058 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, tests
[i
].world_matrix
);
7059 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7061 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7062 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7064 hr
= IDirect3DDevice_BeginScene(device
);
7065 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7067 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7068 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7070 memcpy(exec_desc
.lpData
, tests
[i
].quad
, sizeof(nquad
));
7071 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(nquad
);
7072 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7073 emit_set_ls(&ptr
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
7074 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
7075 emit_tquad_tlist(&ptr
, 0);
7077 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7078 inst_length
-= sizeof(nquad
);
7080 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7081 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7083 set_execute_data(execute_buffer
, 4, sizeof(nquad
), inst_length
);
7084 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7085 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7087 hr
= IDirect3DDevice_EndScene(device
);
7088 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7090 color
= get_surface_color(rt
, 320, 240);
7091 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
7094 IDirect3DExecuteBuffer_Release(execute_buffer
);
7095 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
7096 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
7097 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
7098 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7099 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7100 IDirect3DLight_Release(light
);
7101 destroy_material(material
);
7102 destroy_viewport(device
, viewport
);
7103 IDirectDrawSurface_Release(rt
);
7104 refcount
= IDirect3DDevice_Release(device
);
7105 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7106 IDirect3D_Release(d3d
);
7107 refcount
= IDirectDraw_Release(ddraw
);
7108 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
7109 DestroyWindow(window
);
7112 static void test_specular_lighting(void)
7114 static const unsigned int vertices_side
= 5;
7115 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
7116 const unsigned int vertex_count
= vertices_side
* vertices_side
;
7117 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7118 static D3DMATRIX mat
=
7120 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7121 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7122 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7123 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7125 /* Use of D3DLIGHT2 instead of D3DLIGHT is intentional. Using D3DLIGHT
7126 * without dwFlags looks broken on Windows 7: directional light behaves as
7127 * if _LOCALVIEWER state is off, point and spot lights do not work at all
7128 * and always output zero colours. */
7129 static D3DLIGHT2 directional
=
7132 D3DLIGHT_DIRECTIONAL
,
7133 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7134 {{0.0f
}, {0.0f
}, {0.0f
}},
7135 {{0.0f
}, {0.0f
}, {1.0f
}},
7141 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7142 {{0.0f
}, {0.0f
}, {0.0f
}},
7143 {{0.0f
}, {0.0f
}, {0.0f
}},
7152 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7153 {{0.0f
}, {0.0f
}, {0.0f
}},
7154 {{0.0f
}, {0.0f
}, {1.0f
}},
7158 M_PI
/ 12.0f
, M_PI
/ 3.0f
7163 D3DLIGHT_PARALLELPOINT
,
7164 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7165 {{0.5f
}, {0.0f
}, {-1.0f
}},
7166 {{0.0f
}, {0.0f
}, {0.0f
}},
7172 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7173 {{-1.1f
}, {0.0f
}, {1.1f
}},
7174 {{0.0f
}, {0.0f
}, {0.0f
}},
7183 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7184 {{0.0f
}, {0.0f
}, {0.1f
}},
7185 {{0.0f
}, {0.0f
}, {0.0f
}},
7190 static const struct expected_color
7192 unsigned int x
, y
, colour
;
7194 expected_directional_local
[] =
7196 {160, 120, 0x003c3c3c},
7197 {320, 120, 0x00717171},
7198 {480, 120, 0x003c3c3c},
7199 {160, 240, 0x00717171},
7200 {320, 240, 0x00ffffff},
7201 {480, 240, 0x00717171},
7202 {160, 360, 0x003c3c3c},
7203 {320, 360, 0x00717171},
7204 {480, 360, 0x003c3c3c},
7206 expected_point_local
[] =
7208 {160, 120, 0x00000000},
7209 {320, 120, 0x00090909},
7210 {480, 120, 0x00000000},
7211 {160, 240, 0x00090909},
7212 {320, 240, 0x00fafafa},
7213 {480, 240, 0x00090909},
7214 {160, 360, 0x00000000},
7215 {320, 360, 0x00090909},
7216 {480, 360, 0x00000000},
7218 expected_spot_local
[] =
7220 {160, 120, 0x00000000},
7221 {320, 120, 0x00020202},
7222 {480, 120, 0x00000000},
7223 {160, 240, 0x00020202},
7224 {320, 240, 0x00fafafa},
7225 {480, 240, 0x00020202},
7226 {160, 360, 0x00000000},
7227 {320, 360, 0x00020202},
7228 {480, 360, 0x00000000},
7230 expected_parallelpoint
[] =
7232 {160, 120, 0x00050505},
7233 {320, 120, 0x002c2c2c},
7234 {480, 120, 0x006e6e6e},
7235 {160, 240, 0x00090909},
7236 {320, 240, 0x00717171},
7237 {480, 240, 0x00ffffff},
7238 {160, 360, 0x00050505},
7239 {320, 360, 0x002c2c2c},
7240 {480, 360, 0x006e6e6e},
7242 expected_point_far
[] =
7244 {160, 120, 0x00000000},
7245 {320, 120, 0x00000000},
7246 {480, 120, 0x00000000},
7247 {160, 240, 0x00000000},
7248 {320, 240, 0x00ffffff},
7249 {480, 240, 0x00000000},
7250 {160, 360, 0x00000000},
7251 {320, 360, 0x00000000},
7252 {480, 360, 0x00000000},
7256 {160, 120, 0x00000000},
7257 {320, 120, 0x00000000},
7258 {480, 120, 0x00000000},
7259 {160, 240, 0x00000000},
7260 {320, 240, 0x00000000},
7261 {480, 240, 0x00000000},
7262 {160, 360, 0x00000000},
7263 {320, 360, 0x00000000},
7264 {480, 360, 0x00000000},
7269 float specular_power
;
7270 const struct expected_color
*expected
;
7271 unsigned int expected_count
;
7275 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
7276 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
7277 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
7278 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
7279 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7280 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
7281 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7282 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7283 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7284 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7285 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7288 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
7289 IDirect3DMaterial
*material
, *background_material
;
7290 unsigned int inst_length
, colour
, i
, j
, x
, y
;
7291 IDirect3DExecuteBuffer
*execute_buffer
;
7292 D3DEXECUTEBUFFERDESC exec_desc
;
7293 D3DMATERIALHANDLE mat_handle
;
7294 IDirect3DViewport
*viewport
;
7295 IDirect3DDevice
*device
;
7296 IDirectDrawSurface
*rt
;
7297 IDirect3DLight
*light
;
7308 window
= create_window();
7309 ddraw
= create_ddraw();
7310 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7311 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7313 skip("Failed to create a 3D device, skipping test.\n");
7314 IDirectDraw_Release(ddraw
);
7315 DestroyWindow(window
);
7318 is_warp
= ddraw_is_warp(ddraw
);
7320 quad
= heap_alloc(vertex_count
* sizeof(*quad
));
7321 indices
= heap_alloc(indices_count
* sizeof(*indices
));
7322 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
7324 for (x
= 0; x
< vertices_side
; ++x
)
7326 U1(quad
[i
]).x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7327 U2(quad
[i
]).y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7328 U3(quad
[i
]).z
= 1.0f
;
7329 U4(quad
[i
]).nx
= 0.0f
;
7330 U5(quad
[i
]).ny
= 0.0f
;
7331 U6(quad
[i
]).nz
= -1.0f
;
7332 U7(quad
[i
]).tu
= 0.0f
;
7333 U8(quad
[i
++]).tv
= 0.0f
;
7336 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
7338 for (x
= 0; x
< (vertices_side
- 1); ++x
)
7340 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7341 indices
[i
++] = y
* vertices_side
+ x
;
7342 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7343 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7344 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7345 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
7349 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
7350 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7352 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
7353 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7355 viewport
= create_viewport(device
, 0, 0, 640, 480);
7356 background_material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7357 viewport_set_background(device
, viewport
, background_material
);
7359 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7360 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7362 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
7363 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7364 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
7365 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7366 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
7367 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7368 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
7369 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7370 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
7371 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7372 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
7373 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7376 hr
= IDirect3D_CreateLight(d3d
, &light
, NULL
);
7377 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7378 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7379 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7381 memset(&exec_desc
, 0, sizeof(exec_desc
));
7382 exec_desc
.dwSize
= sizeof(exec_desc
);
7383 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
7384 exec_desc
.dwBufferSize
= 10240;
7385 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
7387 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
7388 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7390 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7392 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
7393 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
7394 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
7395 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7397 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
7398 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7400 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7401 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7403 hr
= IDirect3DDevice_BeginScene(device
);
7404 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7406 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7407 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7409 memcpy(exec_desc
.lpData
, quad
, sizeof(*quad
) * vertex_count
);
7410 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(*quad
) * vertex_count
;
7412 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7413 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
7414 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
7415 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
7416 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7417 emit_set_rs(&ptr
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
7419 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, vertex_count
);
7420 emit_tri_indices(&ptr
, indices
, indices_count
/ 3);
7422 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7423 ok(inst_length
<= exec_desc
.dwBufferSize
, "Execute buffer overflow, size %u.\n", inst_length
);
7424 inst_length
-= sizeof(*quad
) * vertex_count
;
7426 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7427 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7429 set_execute_data(execute_buffer
, vertex_count
, sizeof(*quad
) * vertex_count
, inst_length
);
7430 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7431 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7433 hr
= IDirect3DDevice_EndScene(device
);
7434 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7436 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
7438 colour
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
7439 ok(compare_color(colour
, tests
[i
].expected
[j
].colour
, 1)
7440 || broken(is_warp
&& compare_color(colour
, 0x00ff0000, 1)),
7441 "Expected colour 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
7442 tests
[i
].expected
[j
].colour
, tests
[i
].expected
[j
].x
,
7443 tests
[i
].expected
[j
].y
, colour
, i
);
7445 destroy_material(material
);
7448 IDirect3DExecuteBuffer_Release(execute_buffer
);
7449 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
7450 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
7451 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
7453 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7454 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7455 IDirect3DLight_Release(light
);
7456 destroy_material(background_material
);
7457 destroy_viewport(device
, viewport
);
7458 IDirectDrawSurface_Release(rt
);
7459 refcount
= IDirect3DDevice_Release(device
);
7460 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7461 IDirect3D_Release(d3d
);
7462 refcount
= IDirectDraw_Release(ddraw
);
7463 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
7464 DestroyWindow(window
);
7469 static void test_palette_gdi(void)
7471 IDirectDrawSurface
*surface
, *primary
;
7472 DDSURFACEDESC surface_desc
;
7473 unsigned int color
, i
;
7475 IDirectDrawPalette
*palette
, *palette2
;
7479 PALETTEENTRY palette_entries
[256];
7484 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
7485 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
7486 * not the point of this test. */
7487 static const RGBQUAD expected1
[] =
7489 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7490 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
7492 static const RGBQUAD expected2
[] =
7494 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7495 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
7497 static const RGBQUAD expected3
[] =
7499 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
7500 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
7502 HPALETTE ddraw_palette_handle
;
7503 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
7504 RGBQUAD rgbquad
[255];
7505 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
7507 window
= create_window();
7508 ddraw
= create_ddraw();
7509 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7510 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7511 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7513 memset(&surface_desc
, 0, sizeof(surface_desc
));
7514 surface_desc
.dwSize
= sizeof(surface_desc
);
7515 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7516 surface_desc
.dwWidth
= 16;
7517 surface_desc
.dwHeight
= 16;
7518 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7519 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7520 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7521 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 8;
7522 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7523 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7525 /* Avoid colors from the Windows default palette. */
7526 memset(palette_entries
, 0, sizeof(palette_entries
));
7527 palette_entries
[1].peRed
= 0x01;
7528 palette_entries
[2].peGreen
= 0x02;
7529 palette_entries
[3].peBlue
= 0x03;
7530 palette_entries
[4].peRed
= 0x13;
7531 palette_entries
[4].peGreen
= 0x14;
7532 palette_entries
[4].peBlue
= 0x15;
7533 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7534 palette_entries
, &palette
, NULL
);
7535 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7537 /* If there is no palette assigned and the display mode is not 8 bpp, some
7538 * drivers refuse to create a DC while others allow it. If a DC is created,
7539 * the DIB color table is uninitialized and contains random colors. No error
7540 * is generated when trying to read pixels and random garbage is returned.
7542 * The most likely explanation is that if the driver creates a DC, it (or
7543 * the higher-level runtime) uses GetSystemPaletteEntries to find the
7544 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
7545 * contains uninitialized garbage. See comments below for the P8 case. */
7547 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7548 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7549 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7550 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7551 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7552 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7553 "Got unexpected palette %p, expected %p.\n",
7554 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7556 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7557 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7558 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
7560 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
7561 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7562 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7563 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
7565 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7567 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7568 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7569 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7572 /* Update the palette while the DC is in use. This does not modify the DC. */
7573 palette_entries
[4].peRed
= 0x23;
7574 palette_entries
[4].peGreen
= 0x24;
7575 palette_entries
[4].peBlue
= 0x25;
7576 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
7577 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
7579 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7580 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7581 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7582 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7583 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7584 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7586 /* Neither does re-setting the palette. */
7587 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
7588 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7589 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7590 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7592 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7593 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7594 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7595 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7596 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7597 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7599 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7600 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7602 /* Refresh the DC. This updates the palette. */
7603 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7604 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7605 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7606 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7607 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7609 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7610 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7611 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7612 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7614 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7616 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7617 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7618 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7620 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7621 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7623 refcount
= IDirectDrawSurface_Release(surface
);
7624 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7626 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7627 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7628 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
7630 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7631 IDirectDrawPalette_Release(palette
);
7632 IDirectDraw_Release(ddraw
);
7633 DestroyWindow(window
);
7636 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
7638 memset(&surface_desc
, 0, sizeof(surface_desc
));
7639 surface_desc
.dwSize
= sizeof(surface_desc
);
7640 surface_desc
.dwFlags
= DDSD_CAPS
;
7641 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7642 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7643 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7645 memset(&fx
, 0, sizeof(fx
));
7646 fx
.dwSize
= sizeof(fx
);
7647 U5(fx
).dwFillColor
= 3;
7648 SetRect(&r
, 0, 0, 319, 479);
7649 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7650 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
7651 SetRect(&r
, 320, 0, 639, 479);
7652 U5(fx
).dwFillColor
= 4;
7653 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7654 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
7656 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
7657 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7658 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
7659 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7661 color
= GetPixel(dc
, 160, 240);
7662 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
7663 color
= GetPixel(dc
, 480, 240);
7664 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
7666 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7667 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7668 "Got unexpected palette %p, expected %p.\n",
7669 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7670 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
7672 /* The primary uses the system palette. In exclusive mode, the system palette matches
7673 * the ddraw palette attached to the primary, so the result is what you would expect
7674 * from a regular surface. Tests for the interaction between the ddraw palette and
7675 * the system palette are not included pending an application that depends on this.
7676 * The relation between those causes problems on Windows Vista and newer for games
7677 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
7678 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7679 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7680 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7682 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7683 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7684 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7685 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7687 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7689 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7690 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7691 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7693 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
7694 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7696 memset(&surface_desc
, 0, sizeof(surface_desc
));
7697 surface_desc
.dwSize
= sizeof(surface_desc
);
7698 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7699 surface_desc
.dwWidth
= 16;
7700 surface_desc
.dwHeight
= 16;
7701 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7702 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7703 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7705 /* Here the offscreen surface appears to use the primary's palette,
7706 * but in all likelihood it is actually the system palette. */
7707 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7708 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7709 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7710 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7711 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7713 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7714 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7715 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7716 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7718 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7720 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7721 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7722 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7724 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7725 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7727 /* On real hardware a change to the primary surface's palette applies immediately,
7728 * even on device contexts from offscreen surfaces that do not have their own
7729 * palette. On the testbot VMs this is not the case. Don't test this until we
7730 * know of an application that depends on this. */
7732 memset(palette_entries
, 0, sizeof(palette_entries
));
7733 palette_entries
[1].peBlue
= 0x40;
7734 palette_entries
[2].peRed
= 0x40;
7735 palette_entries
[3].peGreen
= 0x40;
7736 palette_entries
[4].peRed
= 0x12;
7737 palette_entries
[4].peGreen
= 0x34;
7738 palette_entries
[4].peBlue
= 0x56;
7739 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7740 palette_entries
, &palette2
, NULL
);
7741 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7742 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
7743 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7745 /* A palette assigned to the offscreen surface overrides the primary / system
7747 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7748 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7749 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7750 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7751 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
7753 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
7754 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7755 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7756 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
7758 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7760 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7761 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7762 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7764 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7765 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7767 refcount
= IDirectDrawSurface_Release(surface
);
7768 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7770 /* The Windows 8 testbot keeps extra references to the primary and
7771 * backbuffer while in 8 bpp mode. */
7772 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
7773 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
7775 refcount
= IDirectDrawSurface_Release(primary
);
7776 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7777 refcount
= IDirectDrawPalette_Release(palette2
);
7778 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7779 refcount
= IDirectDrawPalette_Release(palette
);
7780 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7781 refcount
= IDirectDraw_Release(ddraw
);
7782 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7783 DestroyWindow(window
);
7786 static void test_palette_alpha(void)
7788 IDirectDrawSurface
*surface
;
7789 DDSURFACEDESC surface_desc
;
7791 IDirectDrawPalette
*palette
;
7795 PALETTEENTRY palette_entries
[256];
7800 BOOL attach_allowed
;
7805 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
7806 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
7807 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
7810 window
= create_window();
7811 ddraw
= create_ddraw();
7812 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7813 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
7815 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7816 IDirectDraw_Release(ddraw
);
7817 DestroyWindow(window
);
7820 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7821 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7823 memset(palette_entries
, 0, sizeof(palette_entries
));
7824 palette_entries
[1].peFlags
= 0x42;
7825 palette_entries
[2].peFlags
= 0xff;
7826 palette_entries
[3].peFlags
= 0x80;
7827 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
7828 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7830 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7831 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7832 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
7833 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7834 palette_entries
[0].peFlags
);
7835 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7836 palette_entries
[1].peFlags
);
7837 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7838 palette_entries
[2].peFlags
);
7839 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7840 palette_entries
[3].peFlags
);
7842 IDirectDrawPalette_Release(palette
);
7844 memset(palette_entries
, 0, sizeof(palette_entries
));
7845 palette_entries
[1].peFlags
= 0x42;
7846 palette_entries
[1].peRed
= 0xff;
7847 palette_entries
[2].peFlags
= 0xff;
7848 palette_entries
[3].peFlags
= 0x80;
7849 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
7850 palette_entries
, &palette
, NULL
);
7851 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7853 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7854 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7855 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
7856 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7857 palette_entries
[0].peFlags
);
7858 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7859 palette_entries
[1].peFlags
);
7860 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7861 palette_entries
[2].peFlags
);
7862 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7863 palette_entries
[3].peFlags
);
7865 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
7867 memset(&surface_desc
, 0, sizeof(surface_desc
));
7868 surface_desc
.dwSize
= sizeof(surface_desc
);
7869 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
7870 surface_desc
.dwWidth
= 128;
7871 surface_desc
.dwHeight
= 128;
7872 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7873 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7874 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7876 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7877 if (test_data
[i
].attach_allowed
)
7878 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7880 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
7888 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7889 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
7890 "Failed to get DC, hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
7893 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7894 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
7895 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
7896 rgbquad
.rgbRed
, test_data
[i
].name
);
7897 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
7898 rgbquad
.rgbGreen
, test_data
[i
].name
);
7899 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
7900 rgbquad
.rgbBlue
, test_data
[i
].name
);
7901 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
7902 rgbquad
.rgbReserved
, test_data
[i
].name
);
7903 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7904 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7907 IDirectDrawSurface_Release(surface
);
7910 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
7911 memset(&surface_desc
, 0, sizeof(surface_desc
));
7912 surface_desc
.dwSize
= sizeof(surface_desc
);
7913 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7914 surface_desc
.dwWidth
= 128;
7915 surface_desc
.dwHeight
= 128;
7916 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7917 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7918 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7919 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7920 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7921 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7922 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7923 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7924 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7925 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7926 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
7927 IDirectDrawSurface_Release(surface
);
7929 /* The Windows 8 testbot keeps extra references to the primary
7930 * while in 8 bpp mode. */
7931 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
7932 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
7934 refcount
= IDirectDrawPalette_Release(palette
);
7935 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7936 refcount
= IDirectDraw_Release(ddraw
);
7937 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7938 DestroyWindow(window
);
7941 static void test_lost_device(void)
7943 IDirectDrawSurface
*surface
, *back_buffer
, *back_buffer2
, *ds
;
7944 IDirectDrawSurface
*sysmem_surface
, *vidmem_surface
;
7945 DDSURFACEDESC surface_desc
;
7946 HWND window1
, window2
;
7953 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7954 0, 0, 640, 480, 0, 0, 0, 0);
7955 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
7956 0, 0, 640, 480, 0, 0, 0, 0);
7957 ddraw
= create_ddraw();
7958 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7959 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7960 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7962 memset(&surface_desc
, 0, sizeof(surface_desc
));
7963 surface_desc
.dwSize
= sizeof(surface_desc
);
7964 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
7965 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
7966 surface_desc
.dwBackBufferCount
= 1;
7967 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7968 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7970 memset(&surface_desc
, 0, sizeof(surface_desc
));
7971 surface_desc
.dwSize
= sizeof(surface_desc
);
7972 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7973 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
7974 surface_desc
.dwWidth
= 100;
7975 surface_desc
.dwHeight
= 100;
7976 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
7977 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7979 memset(&surface_desc
, 0, sizeof(surface_desc
));
7980 surface_desc
.dwSize
= sizeof(surface_desc
);
7981 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7982 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
7983 surface_desc
.dwWidth
= 64;
7984 surface_desc
.dwHeight
= 64;
7985 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7986 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7987 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
7988 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7989 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7990 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7991 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
7993 skip("Failed to create video memory surface, skipping related tests.\n");
7994 vidmem_surface
= NULL
;
7997 hr
= IDirectDrawSurface_IsLost(surface
);
7998 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
7999 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8000 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8001 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8002 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8005 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8006 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8009 ret
= SetForegroundWindow(GetDesktopWindow());
8010 ok(ret
, "Failed to set foreground window.\n");
8011 hr
= IDirectDrawSurface_IsLost(surface
);
8012 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8013 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8014 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8015 hr
= IDirectDrawSurface_Restore(surface
);
8016 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8017 hr
= IDirectDrawSurface_IsLost(surface
);
8018 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8019 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8020 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8021 hr
= IDirectDrawSurface_Restore(sysmem_surface
);
8022 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8023 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8024 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8027 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8028 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8029 hr
= IDirectDrawSurface_Restore(vidmem_surface
);
8030 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8031 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8032 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8035 ret
= SetForegroundWindow(window1
);
8036 ok(ret
, "Failed to set foreground window.\n");
8037 hr
= IDirectDrawSurface_IsLost(surface
);
8038 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8039 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8040 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8041 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8042 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8045 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8046 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8049 hr
= restore_surfaces(ddraw
);
8050 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8051 hr
= IDirectDrawSurface_IsLost(surface
);
8052 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8053 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8054 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8055 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8056 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8059 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8060 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8063 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8064 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8065 hr
= IDirectDrawSurface_IsLost(surface
);
8066 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8067 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8068 ok(hr
== DDERR_NOEXCLUSIVEMODE
|| broken(ddraw_is_warp(ddraw
) && hr
== DDERR_SURFACELOST
),
8069 "Got unexpected hr %#lx.\n", hr
);
8070 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8071 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8074 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8075 ok(hr
== DD_OK
|| broken(ddraw_is_warp(ddraw
) && hr
== DDERR_SURFACELOST
), "Got unexpected hr %#lx.\n", hr
);
8078 /* Trying to restore the primary will crash, probably because flippable
8079 * surfaces can't exist in DDSCL_NORMAL. */
8080 IDirectDrawSurface_Release(surface
);
8081 memset(&surface_desc
, 0, sizeof(surface_desc
));
8082 surface_desc
.dwSize
= sizeof(surface_desc
);
8083 surface_desc
.dwFlags
= DDSD_CAPS
;
8084 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8085 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8086 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8087 hr
= restore_surfaces(ddraw
);
8088 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8090 hr
= IDirectDrawSurface_IsLost(surface
);
8091 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8093 ret
= SetForegroundWindow(GetDesktopWindow());
8094 ok(ret
, "Failed to set foreground window.\n");
8095 hr
= IDirectDrawSurface_IsLost(surface
);
8096 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8097 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8098 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8101 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8102 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8105 ret
= SetForegroundWindow(window1
);
8106 ok(ret
, "Failed to set foreground window.\n");
8107 hr
= IDirectDrawSurface_IsLost(surface
);
8108 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8109 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8110 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8113 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8114 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8117 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8118 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8119 hr
= IDirectDrawSurface_IsLost(surface
);
8120 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8121 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8122 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8125 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8126 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8129 hr
= restore_surfaces(ddraw
);
8130 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8131 hr
= IDirectDrawSurface_IsLost(surface
);
8132 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8133 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8134 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8137 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8138 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8141 IDirectDrawSurface_Release(surface
);
8142 memset(&surface_desc
, 0, sizeof(surface_desc
));
8143 surface_desc
.dwSize
= sizeof(surface_desc
);
8144 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8145 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8146 surface_desc
.dwBackBufferCount
= 2;
8147 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8148 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8151 memset(&surface_desc
, 0, sizeof(surface_desc
));
8152 surface_desc
.dwSize
= sizeof(surface_desc
);
8153 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8154 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8156 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
8157 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8158 U2(surface_desc
).dwZBufferBitDepth
= 16;
8159 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
8162 skip("Could not create Z buffer, skipping Z buffer restore test.\n");
8166 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
8167 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8170 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8171 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8172 hr
= IDirectDrawSurface_IsLost(surface
);
8173 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8174 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8175 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8176 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8177 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8180 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8181 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8184 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8185 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8186 hr
= IDirectDrawSurface_IsLost(surface
);
8187 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8188 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8189 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8190 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8191 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8194 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8195 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8198 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8199 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8200 hr
= IDirectDrawSurface_IsLost(surface
);
8201 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8202 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8203 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8204 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8205 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8208 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8209 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8212 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
8213 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8214 hr
= IDirectDrawSurface_IsLost(surface
);
8215 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8216 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8217 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8218 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8219 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8222 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8223 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8226 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8227 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8228 hr
= IDirectDrawSurface_IsLost(surface
);
8229 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8230 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8231 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8232 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8233 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8236 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8237 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8240 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8241 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8242 hr
= IDirectDrawSurface_IsLost(surface
);
8243 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8244 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8245 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8246 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8247 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8250 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8251 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8254 memset(&caps
, 0, sizeof(caps
));
8255 caps
.dwCaps
= DDSCAPS_FLIP
;
8257 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
8258 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8259 ok(back_buffer
!= surface
, "Got the same surface.\n");
8260 hr
= IDirectDrawSurface_Restore(surface
);
8261 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8262 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
8263 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8264 hr
= IDirectDrawSurface_IsLost(back_buffer
);
8265 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8266 IDirectDrawSurface_Release(back_buffer
);
8268 hr
= IDirectDrawSurface_GetAttachedSurface(back_buffer
, &caps
, &back_buffer2
);
8269 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8270 ok(back_buffer2
!= back_buffer
, "Got the same surface.\n");
8271 ok(back_buffer2
!= surface
, "Got the same surface.\n");
8272 hr
= IDirectDrawSurface_IsLost(back_buffer2
);
8273 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8274 IDirectDrawSurface_Release(back_buffer2
);
8278 hr
= IDirectDrawSurface_IsLost(ds
);
8279 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8280 hr
= IDirectDrawSurface_Restore(ds
);
8281 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8282 hr
= IDirectDrawSurface_IsLost(ds
);
8283 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8284 IDirectDrawSurface_Release(ds
);
8288 IDirectDrawSurface_Release(vidmem_surface
);
8289 IDirectDrawSurface_Release(sysmem_surface
);
8290 IDirectDrawSurface_Release(surface
);
8291 refcount
= IDirectDraw_Release(ddraw
);
8292 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8293 DestroyWindow(window2
);
8294 DestroyWindow(window1
);
8297 static void test_surface_desc_lock(void)
8299 IDirectDrawSurface
*surface
;
8300 DDSURFACEDESC surface_desc
;
8306 window
= create_window();
8307 ddraw
= create_ddraw();
8308 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8309 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8310 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8312 memset(&surface_desc
, 0, sizeof(surface_desc
));
8313 surface_desc
.dwSize
= sizeof(surface_desc
);
8314 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8315 surface_desc
.dwWidth
= 16;
8316 surface_desc
.dwHeight
= 16;
8317 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8318 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8319 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8321 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8322 surface_desc
.dwSize
= sizeof(surface_desc
);
8323 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8324 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8325 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8327 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8328 surface_desc
.dwSize
= sizeof(surface_desc
);
8329 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
8330 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
8331 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8332 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8333 surface_desc
.dwSize
= sizeof(surface_desc
);
8334 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8335 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8336 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8337 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8338 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
8340 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8341 surface_desc
.dwSize
= sizeof(surface_desc
);
8342 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8343 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8344 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8346 IDirectDrawSurface_Release(surface
);
8347 refcount
= IDirectDraw_Release(ddraw
);
8348 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8349 DestroyWindow(window
);
8352 static void test_texturemapblend(void)
8356 D3DEXECUTEBUFFERDESC exec_desc
;
8358 static RECT rect
= {0, 0, 64, 128};
8359 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8361 IDirectDrawSurface
*surface
, *rt
;
8362 unsigned int inst_length
, color
;
8363 IDirect3DTexture
*texture
;
8364 D3DTEXTUREHANDLE texture_handle
;
8367 IDirect3DDevice
*device
;
8368 IDirect3DMaterial
*material
;
8369 IDirect3DViewport
*viewport
;
8370 IDirect3DExecuteBuffer
*execute_buffer
;
8374 static const D3DTLVERTEX test1_quads
[] =
8376 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
8377 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
8378 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
8379 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
8380 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
8381 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
8382 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
8383 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
8387 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
8388 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
8389 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
8390 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
8391 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
8392 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
8393 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
8394 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
8397 window
= create_window();
8398 ddraw
= create_ddraw();
8399 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8400 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8402 skip("Failed to create a 3D device, skipping test.\n");
8403 DestroyWindow(window
);
8404 IDirectDraw_Release(ddraw
);
8408 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8409 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8411 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
8412 viewport
= create_viewport(device
, 0, 0, 640, 480);
8413 viewport_set_background(device
, viewport
, material
);
8415 memset(&exec_desc
, 0, sizeof(exec_desc
));
8416 exec_desc
.dwSize
= sizeof(exec_desc
);
8417 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
8418 exec_desc
.dwBufferSize
= 1024;
8419 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
8420 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
8421 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
8423 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
8425 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
8426 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
8427 memset(&ddsd
, 0, sizeof(ddsd
));
8428 ddsd
.dwSize
= sizeof(ddsd
);
8429 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8430 ddsd
.dwHeight
= 128;
8432 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8433 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8434 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8435 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8436 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8437 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8438 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8439 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8440 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8441 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8443 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8444 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8445 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8446 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8448 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8449 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8451 memset(&fx
, 0, sizeof(fx
));
8452 fx
.dwSize
= sizeof(fx
);
8453 U5(fx
).dwFillColor
= 0xff0000ff;
8454 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8455 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8456 U5(fx
).dwFillColor
= 0x800000ff;
8457 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8458 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8460 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8461 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8463 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
8465 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8466 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8467 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8468 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
8469 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
8470 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
8471 /* The history of D3DRENDERSTATE_ALPHABLENDENABLE is quite a mess. In the
8472 * first D3D release there was a D3DRENDERSTATE_BLENDENABLE (enum value 27).
8473 * D3D5 introduced a new and separate D3DRENDERSTATE_ALPHABLENDENABLE (42)
8474 * together with D3DRENDERSTATE_COLORKEYENABLE (41). The docs aren't all
8475 * that clear but they mention that D3DRENDERSTATE_BLENDENABLE overrides the
8477 * Then D3D6 came and got rid of the new D3DRENDERSTATE_ALPHABLENDENABLE
8478 * state (42), renaming the older D3DRENDERSTATE_BLENDENABLE enum (27)
8479 * as D3DRENDERSTATE_ALPHABLENDENABLE.
8480 * There is a comment in the D3D6 docs which mentions that hardware
8481 * rasterizers always used D3DRENDERSTATE_BLENDENABLE to just toggle alpha
8482 * blending while prior to D3D5 software rasterizers toggled both color
8483 * keying and alpha blending according to it. What I gather is that, from
8484 * D3D6 onwards, D3DRENDERSTATE_ALPHABLENDENABLE always only toggles the
8485 * alpha blending state.
8486 * These tests seem to show that actual, current hardware follows the D3D6
8487 * behavior even when using the original D3D interfaces, for the HAL device
8489 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8490 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
8491 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8493 /* SPECULARENABLE shouldn't matter in this test, but WARP begs to
8494 * differ. In the event that color keying is randomly on (see comments
8495 * in test_ck_default for reference), WARP will randomly discard
8496 * fragments based on something, even though texture and diffuse color
8497 * alpha components are non-zero. Setting SPECULARENABLE to FALSE
8498 * prevents this in some cases - presumably WARP multiplies the
8499 * specular color "alpha" channel into the final result and then
8500 * alpha tests the result. Since the specular property normally does
8501 * not have an alpha component the actual specular color we set in
8502 * the vertex data above does not matter. Setting FOGENABLE = FALSE
8503 * does not help either (specular alpha can contain a per-vertex fog
8504 * factor. Doesn't seem to matter here). */
8505 emit_set_rs(&ptr
, D3DRENDERSTATE_SPECULARENABLE
, FALSE
);
8507 emit_tquad(&ptr
, 0);
8508 emit_tquad(&ptr
, 4);
8511 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8512 inst_length
-= sizeof(test1_quads
);
8513 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8514 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8515 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8517 hr
= IDirect3DDevice_BeginScene(device
);
8518 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8519 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8520 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8521 hr
= IDirect3DDevice_EndScene(device
);
8522 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8524 /* The above SPECULARENABLE = FALSE on WARP matters here.*/
8525 color
= get_surface_color(rt
, 5, 5);
8526 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8527 color
= get_surface_color(rt
, 400, 5);
8528 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8529 color
= get_surface_color(rt
, 5, 245);
8530 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8531 color
= get_surface_color(rt
, 400, 245);
8532 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8534 IDirect3DTexture_Release(texture
);
8535 ref
= IDirectDrawSurface_Release(surface
);
8536 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8538 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
8539 memset(&ddsd
, 0, sizeof(ddsd
));
8540 ddsd
.dwSize
= sizeof(ddsd
);
8541 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8542 ddsd
.dwHeight
= 128;
8544 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8545 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8546 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8547 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8548 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8549 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8550 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8552 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8553 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8555 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8556 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8557 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8558 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8560 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8561 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8563 U5(fx
).dwFillColor
= 0xff0000ff;
8564 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8565 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8566 U5(fx
).dwFillColor
= 0x800000ff;
8567 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8568 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8570 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8571 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8573 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8574 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8575 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8577 emit_tquad(&ptr
, 0);
8578 emit_tquad(&ptr
, 4);
8581 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8582 inst_length
-= sizeof(test1_quads
);
8583 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8584 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8585 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8587 hr
= IDirect3DDevice_BeginScene(device
);
8588 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8589 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8590 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8591 hr
= IDirect3DDevice_EndScene(device
);
8592 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8594 /* Despite our best efforts at not making color keying randomly triggering, those
8595 * four broken() results occur every now and then on WARP. Presumably the non-
8596 * existent alpha channel sometimes samples 0.0 instead of the expected 1.0. */
8597 color
= get_surface_color(rt
, 5, 5);
8598 ok(compare_color(color
, 0x000000ff, 2)
8599 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8600 "Got unexpected color 0x%08x.\n", color
);
8601 color
= get_surface_color(rt
, 400, 5);
8602 ok(compare_color(color
, 0x000000ff, 2)
8603 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8604 "Got unexpected color 0x%08x.\n", color
);
8605 color
= get_surface_color(rt
, 5, 245);
8606 ok(compare_color(color
, 0x00000080, 2)
8607 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8608 "Got unexpected color 0x%08x.\n", color
);
8609 color
= get_surface_color(rt
, 400, 245);
8610 ok(compare_color(color
, 0x00000080, 2)
8611 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8612 "Got unexpected color 0x%08x.\n", color
);
8614 IDirect3DTexture_Release(texture
);
8615 ref
= IDirectDrawSurface_Release(surface
);
8616 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8618 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
8619 memset(&ddsd
, 0, sizeof(ddsd
));
8620 ddsd
.dwSize
= sizeof(ddsd
);
8621 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8622 ddsd
.dwHeight
= 128;
8624 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8625 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8626 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8627 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 32;
8628 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8629 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8630 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8631 U5(ddsd
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8632 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8633 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8635 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8636 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8637 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8638 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8640 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8641 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8643 U5(fx
).dwFillColor
= 0x00ffffff;
8644 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8645 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8646 U5(fx
).dwFillColor
= 0x00ffff80;
8647 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8648 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8650 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8651 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8653 memcpy(exec_desc
.lpData
, test2_quads
, sizeof(test2_quads
));
8655 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test2_quads
);
8656 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8657 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
8658 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8660 emit_tquad(&ptr
, 0);
8661 emit_tquad(&ptr
, 4);
8664 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8665 inst_length
-= sizeof(test2_quads
);
8666 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8667 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8668 set_execute_data(execute_buffer
, 8, sizeof(test2_quads
), inst_length
);
8670 hr
= IDirect3DDevice_BeginScene(device
);
8671 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8672 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8673 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8674 hr
= IDirect3DDevice_EndScene(device
);
8675 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8677 /* WARP (Win8 testbot) emulates color keying with the alpha channel like Wine does,
8678 * but even applies it when there's no color key assigned. The surface alpha is zero
8679 * here, so nothing gets drawn.
8681 * The ddraw2 version of this test draws these quads with color keying off due to
8682 * different defaults in ddraw1 and ddraw2. */
8683 color
= get_surface_color(rt
, 5, 5);
8684 ok(compare_color(color
, 0x00ff0040, 2) || broken(compare_color(color
, 0x00000000, 1)),
8685 "Got unexpected color 0x%08x.\n", color
);
8686 color
= get_surface_color(rt
, 400, 5);
8687 ok(compare_color(color
, 0x00ff0080, 2) || broken(compare_color(color
, 0x00000000, 1)),
8688 "Got unexpected color 0x%08x.\n", color
);
8689 color
= get_surface_color(rt
, 5, 245);
8690 ok(compare_color(color
, 0x00800080, 2) || broken(compare_color(color
, 0x00000000, 1)),
8691 "Got unexpected color 0x%08x.\n", color
);
8692 color
= get_surface_color(rt
, 400, 245);
8693 ok(compare_color(color
, 0x008000ff, 2) || broken(compare_color(color
, 0x00000000, 1)),
8694 "Got unexpected color 0x%08x.\n", color
);
8696 IDirect3DTexture_Release(texture
);
8697 ref
= IDirectDrawSurface_Release(surface
);
8698 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8700 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
8701 memset(&ddsd
, 0, sizeof(ddsd
));
8702 ddsd
.dwSize
= sizeof(ddsd
);
8703 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8704 ddsd
.dwHeight
= 128;
8706 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8707 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8708 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8709 U1(ddsd
.ddpfPixelFormat
).dwRGBBitCount
= 16;
8710 U2(ddsd
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
8711 U3(ddsd
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
8712 U4(ddsd
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
8714 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8715 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8717 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8718 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8719 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8720 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8722 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8723 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8725 U5(fx
).dwFillColor
= 0xf800;
8726 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8727 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8728 U5(fx
).dwFillColor
= 0x001f;
8729 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8730 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8732 ckey
.dwColorSpaceLowValue
= 0x001f;
8733 ckey
.dwColorSpaceHighValue
= 0x001f;
8734 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8735 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
8737 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8738 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8740 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
8742 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8743 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8744 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8745 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8746 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
8747 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
8748 * testbot. This is either the fault of Windows 8 or the WARP driver.
8749 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
8750 * devices only, which might imply this doesn't actually do anything on
8752 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
8754 emit_tquad(&ptr
, 0);
8755 emit_tquad(&ptr
, 4);
8758 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8759 inst_length
-= sizeof(test1_quads
);
8760 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8761 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8762 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8764 hr
= IDirect3DDevice_BeginScene(device
);
8765 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8766 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8767 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8768 hr
= IDirect3DDevice_EndScene(device
);
8769 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8771 /* Allow broken WARP results (colorkey disabled). */
8772 color
= get_surface_color(rt
, 5, 5);
8773 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x000000ff, 2)),
8774 "Got unexpected color 0x%08x.\n", color
);
8775 color
= get_surface_color(rt
, 400, 5);
8776 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
8777 color
= get_surface_color(rt
, 5, 245);
8778 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x00000080, 2)),
8779 "Got unexpected color 0x%08x.\n", color
);
8780 color
= get_surface_color(rt
, 400, 245);
8781 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
8783 IDirect3DTexture_Release(texture
);
8784 ref
= IDirectDrawSurface_Release(surface
);
8785 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8787 ref
= IDirect3DExecuteBuffer_Release(execute_buffer
);
8788 ok(ref
== 0, "Execute buffer not properly released, refcount %lu.\n", ref
);
8789 destroy_viewport(device
, viewport
);
8790 ref
= IDirect3DMaterial_Release(material
);
8791 ok(ref
== 0, "Material not properly released, refcount %lu.\n", ref
);
8792 IDirectDrawSurface_Release(rt
);
8793 IDirect3DDevice_Release(device
);
8794 ref
= IDirectDraw_Release(ddraw
);
8795 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8796 DestroyWindow(window
);
8799 static void test_viewport_clear_rect(void)
8802 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8803 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
8804 IDirectDrawSurface
*rt
;
8808 IDirect3DDevice
*device
;
8809 IDirect3DMaterial
*red
, *green
;
8810 IDirect3DViewport
*viewport
, *viewport2
;
8813 window
= create_window();
8814 ddraw
= create_ddraw();
8815 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8816 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8818 skip("Failed to create a 3D device, skipping test.\n");
8819 DestroyWindow(window
);
8820 IDirectDraw_Release(ddraw
);
8824 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8825 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8827 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8828 viewport
= create_viewport(device
, 0, 0, 640, 480);
8829 viewport_set_background(device
, viewport
, red
);
8830 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8831 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8833 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
8834 viewport2
= create_viewport(device
, 100, 100, 20, 20);
8835 viewport_set_background(device
, viewport2
, green
);
8836 hr
= IDirect3DViewport_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
8837 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8839 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
8840 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8841 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
8842 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
8843 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
8844 "Got unexpected color 0x%08x.\n", color
);
8845 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
8846 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
8847 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
8848 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8849 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
8850 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8852 destroy_viewport(device
, viewport2
);
8853 destroy_material(green
);
8854 destroy_viewport(device
, viewport
);
8855 destroy_material(red
);
8856 IDirectDrawSurface_Release(rt
);
8857 IDirect3DDevice_Release(device
);
8858 ref
= IDirectDraw_Release(ddraw
);
8859 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8860 DestroyWindow(window
);
8863 static void test_color_fill(void)
8866 IDirect3DDevice
*device
;
8868 IDirectDrawSurface
*surface
, *surface2
;
8869 DDSURFACEDESC surface_desc
;
8870 unsigned int i
, *color
;
8875 RECT rect
= {5, 5, 7, 7};
8876 DWORD num_fourcc_codes
, *fourcc_codes
;
8878 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
8882 HRESULT colorfill_hr
, depthfill_hr
;
8885 unsigned int result
;
8887 DDPIXELFORMAT format
;
8892 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8893 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8895 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8896 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8900 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8901 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
8903 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8904 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8908 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8909 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
8911 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8912 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8916 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8917 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
8919 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
8920 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
8924 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
8925 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
8926 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
8929 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
8930 * different afterwards. DX9+ GPUs set one of the two luminance values
8931 * in each block, but AMD and Nvidia GPUs disagree on which luminance
8932 * value they set. r200 (dx8) just sets the entire block to the clear
8934 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8935 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
8937 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8938 {0}, {0}, {0}, {0}, {0}
8942 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8943 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
8945 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8946 {0}, {0}, {0}, {0}, {0}
8950 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8951 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
8953 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
8954 {0}, {0}, {0}, {0}, {0}
8958 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
8959 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
8961 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
8962 {0}, {0}, {0}, {0}, {0}
8966 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
8967 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
8969 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8970 {0}, {0}, {0}, {0}, {0}
8974 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
8975 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
8977 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
8978 {0}, {0}, {0}, {0}, {0}
8982 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
8983 * surface works, presumably because it is handled by the runtime instead of
8985 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
8986 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
8988 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8989 {8}, {0}, {0}, {0}, {0}
8993 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
8994 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
8996 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
8997 {8}, {0}, {0}, {0}, {0}
9009 {SRCCOPY
, "SRCCOPY", DD_OK
},
9010 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9011 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9012 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9013 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9014 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9015 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9016 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9017 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9018 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9019 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9020 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9021 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9022 {BLACKNESS
, "BLACKNESS", DD_OK
},
9023 {WHITENESS
, "WHITENESS", DD_OK
},
9024 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9027 window
= create_window();
9028 ddraw
= create_ddraw();
9029 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9030 is_warp
= ddraw_is_warp(ddraw
);
9031 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9033 skip("Failed to create a 3D device, skipping test.\n");
9034 DestroyWindow(window
);
9035 IDirectDraw_Release(ddraw
);
9039 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9040 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9041 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
9042 num_fourcc_codes
* sizeof(*fourcc_codes
));
9045 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9046 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9047 for (i
= 0; i
< num_fourcc_codes
; i
++)
9049 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9050 support_yuy2
= TRUE
;
9051 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9052 support_uyvy
= TRUE
;
9054 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
9056 memset(&hal_caps
, 0, sizeof(hal_caps
));
9057 hal_caps
.dwSize
= sizeof(hal_caps
);
9058 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
9059 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9061 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9062 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9064 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9066 DWORD expected_broken
= tests
[i
].result
;
9067 unsigned int mask
= 0xffffffffu
;
9069 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9070 memset(&fx
, 0, sizeof(fx
));
9071 fx
.dwSize
= sizeof(fx
);
9072 U5(fx
).dwFillColor
= 0xdeadbeef;
9074 memset(&surface_desc
, 0, sizeof(surface_desc
));
9075 surface_desc
.dwSize
= sizeof(surface_desc
);
9076 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9077 surface_desc
.dwWidth
= 64;
9078 surface_desc
.dwHeight
= 64;
9079 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
9080 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9082 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
9084 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
9085 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
9086 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9087 if (!check
.supported
)
9091 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
9093 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
9095 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9098 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9100 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
9101 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
9102 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9103 mask
>>= (32 - U2(surface_desc
).dwZBufferBitDepth
);
9104 /* Some drivers seem to convert depth values incorrectly or not at
9105 * all. Affects at least AMD PALM, 8.17.10.1247. */
9106 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9111 expected
= tests
[i
].result
& mask
;
9112 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
9113 g
= (f
+ 1.0f
) / 2.0f
;
9115 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9116 expected_broken
*= 0x01010101;
9120 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9121 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9123 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9124 todo_wine_if (tests
[i
].format
.dwFourCC
)
9125 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9126 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9128 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9129 todo_wine_if (tests
[i
].format
.dwFourCC
)
9130 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9131 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9133 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9135 memset(&surface_desc
, 0, sizeof(surface_desc
));
9136 surface_desc
.dwSize
= sizeof(surface_desc
);
9137 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9138 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9139 color
= surface_desc
.lpSurface
;
9140 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9141 *color
, tests
[i
].result
, tests
[i
].name
);
9142 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9143 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9146 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9147 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9148 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9149 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9150 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9151 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9153 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9155 memset(&surface_desc
, 0, sizeof(surface_desc
));
9156 surface_desc
.dwSize
= sizeof(surface_desc
);
9157 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9158 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9159 color
= surface_desc
.lpSurface
;
9160 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& U2(surface_desc
).dwZBufferBitDepth
!= 16)
9161 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
9162 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
9163 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9164 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
9165 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9166 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9169 U5(fx
).dwFillColor
= 0xdeadbeef;
9170 fx
.dwROP
= BLACKNESS
;
9171 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9172 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
9173 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9174 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
9175 U5(fx
).dwFillColor
, tests
[i
].name
);
9177 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9179 memset(&surface_desc
, 0, sizeof(surface_desc
));
9180 surface_desc
.dwSize
= sizeof(surface_desc
);
9181 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9182 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9183 color
= surface_desc
.lpSurface
;
9184 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
9185 *color
, tests
[i
].name
);
9186 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9187 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9190 fx
.dwROP
= WHITENESS
;
9191 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9192 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
9193 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9194 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
9195 U5(fx
).dwFillColor
, tests
[i
].name
);
9197 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9199 memset(&surface_desc
, 0, sizeof(surface_desc
));
9200 surface_desc
.dwSize
= sizeof(surface_desc
);
9201 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9202 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9203 color
= surface_desc
.lpSurface
;
9204 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
9205 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
9206 *color
, tests
[i
].name
);
9207 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9208 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9211 IDirectDrawSurface_Release(surface
);
9214 memset(&fx
, 0, sizeof(fx
));
9215 fx
.dwSize
= sizeof(fx
);
9216 U5(fx
).dwFillColor
= 0xdeadbeef;
9217 fx
.dwROP
= WHITENESS
;
9219 memset(&surface_desc
, 0, sizeof(surface_desc
));
9220 surface_desc
.dwSize
= sizeof(surface_desc
);
9221 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9222 surface_desc
.dwWidth
= 64;
9223 surface_desc
.dwHeight
= 64;
9224 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9225 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9226 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9227 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9228 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9229 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9230 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9231 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9232 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9233 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9234 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9237 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
9238 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9239 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
9240 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9242 /* Unused source rectangle. */
9243 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9244 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9245 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9246 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9248 /* Unused source surface. */
9249 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9250 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9251 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9252 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9253 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9254 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9255 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9256 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9258 /* Inverted destination or source rectangle. */
9259 SetRect(&rect
, 5, 7, 7, 5);
9260 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9261 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9262 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9263 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9264 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9265 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9266 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9267 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9268 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9269 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9271 /* Negative rectangle. */
9272 SetRect(&rect
, -1, -1, 5, 5);
9273 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9274 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9275 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9276 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9277 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9278 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9279 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9280 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9281 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9282 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9284 /* Out of bounds rectangle. */
9285 SetRect(&rect
, 0, 0, 65, 65);
9286 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9287 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9288 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9289 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9291 /* Combine multiple flags. */
9292 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9293 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9294 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9295 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9296 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9297 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9299 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
9301 fx
.dwROP
= rops
[i
].rop
;
9302 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9303 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#lx for rop %s.\n", hr
, rops
[i
].name
);
9306 IDirectDrawSurface_Release(surface2
);
9307 IDirectDrawSurface_Release(surface
);
9309 memset(&surface_desc
, 0, sizeof(surface_desc
));
9310 surface_desc
.dwSize
= sizeof(surface_desc
);
9311 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
9312 surface_desc
.dwWidth
= 64;
9313 surface_desc
.dwHeight
= 64;
9314 U2(surface_desc
).dwZBufferBitDepth
= get_device_z_depth(device
);
9315 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9316 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9317 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9318 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9319 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9322 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
9323 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9325 /* Unused source rectangle. */
9326 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9327 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9329 /* Unused source surface. */
9330 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9331 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9332 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9333 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9335 /* Inverted destination or source rectangle. */
9336 SetRect(&rect
, 5, 7, 7, 5);
9337 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9338 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9339 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9340 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9341 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9342 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9343 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9344 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9346 /* Negative rectangle. */
9347 SetRect(&rect
, -1, -1, 5, 5);
9348 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9349 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9350 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9351 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9352 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9353 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9354 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9355 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9357 /* Out of bounds rectangle. */
9358 SetRect(&rect
, 0, 0, 65, 65);
9359 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9360 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9362 /* Combine multiple flags. */
9363 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9364 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9366 IDirectDrawSurface_Release(surface2
);
9367 IDirectDrawSurface_Release(surface
);
9370 IDirect3DDevice_Release(device
);
9371 refcount
= IDirectDraw_Release(ddraw
);
9372 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
9373 DestroyWindow(window
);
9376 static void test_colorkey_precision(void)
9378 static D3DTLVERTEX quad
[] =
9380 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {1.0f
}},
9381 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {0.0f
}},
9382 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {1.0f
}},
9383 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {0.0f
}},
9385 unsigned int inst_length
, data
[4] = {0}, color_mask
, color
, t
, c
;
9386 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9387 IDirect3DDevice
*device
;
9389 IDirectDrawSurface
*rt
;
9390 IDirect3DViewport
*viewport
;
9391 IDirect3DExecuteBuffer
*execute_buffer
;
9392 D3DEXECUTEBUFFERDESC exec_desc
;
9396 IDirectDrawSurface
*src
, *dst
, *texture
;
9397 D3DTEXTUREHANDLE handle
;
9398 IDirect3DTexture
*d3d_texture
;
9399 IDirect3DMaterial
*green
;
9400 DDSURFACEDESC surface_desc
, lock_desc
;
9404 BOOL is_nvidia
, is_warp
;
9407 unsigned int max
, shift
, bpp
, clear
;
9415 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
9417 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9418 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
9423 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
9425 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9426 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9431 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
9433 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9434 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9439 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
9441 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9442 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
9447 window
= create_window();
9448 ddraw
= create_ddraw();
9449 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9450 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9452 skip("Failed to create a 3D device, skipping test.\n");
9453 DestroyWindow(window
);
9454 IDirectDraw_Release(ddraw
);
9457 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
9458 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9460 is_nvidia
= ddraw_is_nvidia(ddraw
);
9461 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
9462 * (color key doesn't match although the values are equal), and a false
9463 * positive when the color key is 0 and the texture contains the value 1.
9464 * I don't want to mark this broken unconditionally since this would
9465 * essentially disable the test on Windows. Also on random occasions
9466 * 254 == 255 and 255 != 255.*/
9467 is_warp
= ddraw_is_warp(ddraw
);
9469 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
9470 viewport
= create_viewport(device
, 0, 0, 640, 480);
9471 viewport_set_background(device
, viewport
, green
);
9473 memset(&exec_desc
, 0, sizeof(exec_desc
));
9474 exec_desc
.dwSize
= sizeof(exec_desc
);
9475 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
9476 exec_desc
.dwBufferSize
= 1024;
9477 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
9478 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
9479 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
9481 memset(&fx
, 0, sizeof(fx
));
9482 fx
.dwSize
= sizeof(fx
);
9483 memset(&lock_desc
, 0, sizeof(lock_desc
));
9484 lock_desc
.dwSize
= sizeof(lock_desc
);
9486 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
9488 if (is_nvidia
&& tests
[t
].skip_nv
)
9490 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
9494 memset(&surface_desc
, 0, sizeof(surface_desc
));
9495 surface_desc
.dwSize
= sizeof(surface_desc
);
9496 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9497 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9498 surface_desc
.dwWidth
= 4;
9499 surface_desc
.dwHeight
= 1;
9500 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
9501 /* Windows XP (at least with the r200 driver, other drivers untested) produces
9502 * garbage when doing color keyed texture->texture blits. */
9503 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9504 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9505 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9506 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9508 U5(fx
).dwFillColor
= tests
[t
].clear
;
9509 /* On the w8 testbot (WARP driver) the blit result has different values in the
9511 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
9512 | U3(tests
[t
].fmt
).dwGBitMask
9513 | U4(tests
[t
].fmt
).dwBBitMask
;
9515 for (c
= 0; c
<= tests
[t
].max
; ++c
)
9517 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
9518 * texture after it has been set once... */
9519 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
9520 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9521 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9522 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9523 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
9524 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9526 hr
= IDirectDrawSurface_QueryInterface(texture
, &IID_IDirect3DTexture
, (void **)&d3d_texture
);
9527 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9528 hr
= IDirect3DTexture_GetHandle(d3d_texture
, device
, &handle
);
9529 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9530 IDirect3DTexture_Release(d3d_texture
);
9532 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
9533 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
9535 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
9537 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
9538 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
9539 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9540 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
9541 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
9542 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
9543 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
9544 * testbot. This is either the fault of Windows 8 or the WARP driver.
9545 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
9546 * devices only, which might imply this doesn't actually do anything on
9548 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9550 emit_tquad(&ptr
, 0);
9551 emit_tquad(&ptr
, 4);
9552 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
9555 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
9556 inst_length
-= sizeof(quad
);
9557 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
9558 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
9559 set_execute_data(execute_buffer
, 8, sizeof(quad
), inst_length
);
9561 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9562 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
9564 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9565 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9566 switch (tests
[t
].bpp
)
9569 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9570 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9571 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9572 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
9576 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9577 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9578 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9579 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
9582 hr
= IDirectDrawSurface_Unlock(src
, 0);
9583 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9584 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9585 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
9587 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9588 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9589 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
9590 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9592 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
9593 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
9595 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
9596 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9597 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9598 switch (tests
[t
].bpp
)
9601 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9602 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9603 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9604 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9608 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9609 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9610 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9611 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9614 hr
= IDirectDrawSurface_Unlock(dst
, 0);
9615 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9619 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9620 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
9622 if (data
[3] == tests
[t
].clear
)
9624 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
9625 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
9626 * even when a different surface is used. The blit itself doesn't draw anything,
9627 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
9628 * never be masked out by the key.
9630 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
9631 * test is disabled entirely.
9633 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
9634 * terrible on WARP. */
9635 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
9636 IDirectDrawSurface_Release(texture
);
9637 IDirectDrawSurface_Release(src
);
9638 IDirectDrawSurface_Release(dst
);
9643 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9644 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
9646 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9647 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
9649 if (c
== tests
[t
].max
)
9650 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9651 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
9653 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9654 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
9656 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9657 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
9659 hr
= IDirect3DDevice_BeginScene(device
);
9660 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9661 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
9662 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9663 hr
= IDirect3DDevice_EndScene(device
);
9664 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9666 color
= get_surface_color(rt
, 80, 240);
9668 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9669 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9670 color
, tests
[t
].name
, c
);
9672 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9673 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9674 color
, tests
[t
].name
, c
);
9676 color
= get_surface_color(rt
, 240, 240);
9677 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9678 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9679 color
, tests
[t
].name
, c
);
9681 color
= get_surface_color(rt
, 400, 240);
9682 if (c
== tests
[t
].max
)
9683 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9684 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9685 color
, tests
[t
].name
, c
);
9687 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9688 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9689 color
, tests
[t
].name
, c
);
9691 IDirectDrawSurface_Release(texture
);
9693 IDirectDrawSurface_Release(src
);
9694 IDirectDrawSurface_Release(dst
);
9698 destroy_viewport(device
, viewport
);
9699 destroy_material(green
);
9700 IDirectDrawSurface_Release(rt
);
9701 IDirect3DExecuteBuffer_Release(execute_buffer
);
9702 IDirect3DDevice_Release(device
);
9703 refcount
= IDirectDraw_Release(ddraw
);
9704 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
9705 DestroyWindow(window
);
9708 static void test_range_colorkey(void)
9713 IDirectDrawSurface
*surface
;
9714 DDSURFACEDESC surface_desc
;
9718 window
= create_window();
9719 ddraw
= create_ddraw();
9720 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9721 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9722 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9724 memset(&surface_desc
, 0, sizeof(surface_desc
));
9725 surface_desc
.dwSize
= sizeof(surface_desc
);
9726 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
9727 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9728 surface_desc
.dwWidth
= 1;
9729 surface_desc
.dwHeight
= 1;
9730 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9731 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
9732 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9733 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9734 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9735 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
9737 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
9738 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9739 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9740 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9741 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9743 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9744 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9745 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9746 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9748 /* Same for DDSCAPS_OFFSCREENPLAIN. */
9749 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9750 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9751 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9752 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9753 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9755 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9756 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9757 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9758 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9760 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9761 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9762 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9763 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9765 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
9766 ckey
.dwColorSpaceLowValue
= 0x00000000;
9767 ckey
.dwColorSpaceHighValue
= 0x00000001;
9768 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9769 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9771 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9772 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9773 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9774 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9776 ckey
.dwColorSpaceLowValue
= 0x00000001;
9777 ckey
.dwColorSpaceHighValue
= 0x00000000;
9778 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9779 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9781 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9782 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9783 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9784 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9786 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
9787 ckey
.dwColorSpaceLowValue
= 0x00000000;
9788 ckey
.dwColorSpaceHighValue
= 0x00000000;
9789 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9790 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9792 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
9793 ckey
.dwColorSpaceLowValue
= 0x00000001;
9794 ckey
.dwColorSpaceHighValue
= 0x00000000;
9795 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9796 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9797 ckey
.dwColorSpaceLowValue
= 0x00000000;
9798 ckey
.dwColorSpaceHighValue
= 0x00000001;
9799 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9800 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9801 /* Range destination keys don't work either. */
9802 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
9803 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9805 /* Just to show it's not because of A, R, and G having equal values. */
9806 ckey
.dwColorSpaceLowValue
= 0x00000000;
9807 ckey
.dwColorSpaceHighValue
= 0x01010101;
9808 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9809 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9811 /* None of these operations modified the key. */
9812 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9813 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9814 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9815 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9817 IDirectDrawSurface_Release(surface
);
9818 refcount
= IDirectDraw_Release(ddraw
);
9819 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9820 DestroyWindow(window
);
9823 static void test_shademode(void)
9825 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9826 unsigned int color0
, color1
, i
, inst_length
;
9827 IDirect3DExecuteBuffer
*execute_buffer
;
9828 D3DEXECUTEBUFFERDESC exec_desc
;
9829 IDirect3DMaterial
*background
;
9830 IDirect3DViewport
*viewport
;
9831 IDirect3DDevice
*device
;
9832 IDirectDrawSurface
*rt
;
9833 const D3DLVERTEX
*quad
;
9839 static const D3DLVERTEX quad_strip
[] =
9841 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9842 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9843 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9844 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9848 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9849 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9850 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9851 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9857 unsigned int color0
, color1
;
9861 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
9862 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9863 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9864 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9865 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x000000ff, 0x0000ff00},
9866 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9869 window
= create_window();
9870 ddraw
= create_ddraw();
9871 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9872 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9874 skip("Failed to create a 3D device, skipping test.\n");
9875 IDirectDraw_Release(ddraw
);
9876 DestroyWindow(window
);
9880 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
9881 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9883 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
9884 viewport
= create_viewport(device
, 0, 0, 640, 480);
9885 viewport_set_background(device
, viewport
, background
);
9887 memset(&exec_desc
, 0, sizeof(exec_desc
));
9888 exec_desc
.dwSize
= sizeof(exec_desc
);
9889 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
9890 exec_desc
.dwBufferSize
= 1024;
9891 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
9893 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
9894 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
9896 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
9897 * the color fixups we have to do for FLAT shading will be dependent on that. */
9899 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
9901 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9902 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
9904 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
9905 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
9907 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
9908 memcpy(exec_desc
.lpData
, quad
, sizeof(quad_strip
));
9909 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad_strip
);
9910 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
9911 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
9912 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9913 emit_set_rs(&ptr
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
9915 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
9916 if (tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
)
9917 emit_tquad(&ptr
, 0);
9919 emit_tquad_tlist(&ptr
, 0);
9921 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
9922 inst_length
-= sizeof(quad_strip
);
9924 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
9925 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
9927 hr
= IDirect3DDevice_BeginScene(device
);
9928 set_execute_data(execute_buffer
, 4, sizeof(quad_strip
), inst_length
);
9929 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
9930 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
9931 hr
= IDirect3DDevice_EndScene(device
);
9932 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9934 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
9935 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
9937 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9938 * each triangle. This requires EXT_provoking_vertex or similar
9939 * functionality being available. */
9940 /* PHONG should be the same as GOURAUD, since no hardware implements
9942 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9943 i
, color0
, tests
[i
].color0
);
9944 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9945 i
, color1
, tests
[i
].color1
);
9948 IDirect3DExecuteBuffer_Release(execute_buffer
);
9949 destroy_viewport(device
, viewport
);
9950 destroy_material(background
);
9951 IDirectDrawSurface_Release(rt
);
9952 refcount
= IDirect3DDevice_Release(device
);
9953 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9954 IDirectDraw_Release(ddraw
);
9955 DestroyWindow(window
);
9958 static void test_lockrect_invalid(void)
9962 IDirectDrawSurface
*surface
;
9965 DDSURFACEDESC surface_desc
;
9967 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
9968 static RECT valid
[] =
9976 static RECT invalid
[] =
9978 {68, 60, 60, 68}, /* left > right */
9979 {60, 68, 68, 60}, /* top > bottom */
9980 {-8, 60, 0, 68}, /* left < surface */
9981 {60, -8, 68, 0}, /* top < surface */
9982 {-16, 60, -8, 68}, /* right < surface */
9983 {60, -16, 68, -8}, /* bottom < surface */
9984 {60, 60, 136, 68}, /* right > surface */
9985 {60, 60, 68, 136}, /* bottom > surface */
9986 {136, 60, 144, 68}, /* left > surface */
9987 {60, 136, 68, 144}, /* top > surface */
9997 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
9998 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
9999 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
10000 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
10003 window
= create_window();
10004 ddraw
= create_ddraw();
10005 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10006 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10007 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10009 memset(&hal_caps
, 0, sizeof(hal_caps
));
10010 hal_caps
.dwSize
= sizeof(hal_caps
);
10011 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
10012 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
10013 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
10015 skip("Required surface types not supported, skipping test.\n");
10019 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
10021 memset(&surface_desc
, 0, sizeof(surface_desc
));
10022 surface_desc
.dwSize
= sizeof(surface_desc
);
10023 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10024 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
10025 surface_desc
.dwWidth
= 128;
10026 surface_desc
.dwHeight
= 128;
10027 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10028 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10029 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
10030 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xff0000;
10031 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
10032 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
10034 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10035 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10037 hr
= IDirectDrawSurface_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
10038 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10040 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
10042 RECT
*rect
= &valid
[i
];
10044 memset(&surface_desc
, 0, sizeof(surface_desc
));
10045 surface_desc
.dwSize
= sizeof(surface_desc
);
10047 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10048 ok(SUCCEEDED(hr
), "Lock failed (%#lx) for rect %s, type %s.\n",
10049 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10051 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10052 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10055 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
10057 RECT
*rect
= &invalid
[i
];
10059 memset(&surface_desc
, 1, sizeof(surface_desc
));
10060 surface_desc
.dwSize
= sizeof(surface_desc
);
10062 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10063 ok(hr
== resources
[r
].hr
, "Lock returned %#lx for rect %s, type %s.\n",
10064 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10067 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10068 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10071 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10074 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10075 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#lx, type %s.\n",
10076 hr
, resources
[r
].name
);
10077 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10078 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#lx, type %s.\n",
10079 hr
, resources
[r
].name
);
10080 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10081 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10083 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10084 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#lx).\n", wine_dbgstr_rect(&valid
[0]), hr
);
10085 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10086 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#lx).\n",
10087 wine_dbgstr_rect(&valid
[0]), hr
);
10089 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
10090 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
10092 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10093 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10095 IDirectDrawSurface_Release(surface
);
10099 IDirectDraw_Release(ddraw
);
10100 DestroyWindow(window
);
10103 static void test_yv12_overlay(void)
10105 IDirectDrawSurface
*src_surface
, *dst_surface
;
10106 RECT rect
= {13, 17, 14, 18};
10107 unsigned int offset
, y
;
10108 unsigned char *base
;
10109 DDSURFACEDESC desc
;
10110 IDirectDraw
*ddraw
;
10114 window
= create_window();
10115 ddraw
= create_ddraw();
10116 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10117 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10118 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10120 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10122 skip("Failed to create a YV12 overlay, skipping test.\n");
10126 memset(&desc
, 0, sizeof(desc
));
10127 desc
.dwSize
= sizeof(desc
);
10128 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10129 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10131 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
10132 "Got unexpected flags %#lx.\n", desc
.dwFlags
);
10133 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
10134 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
10135 "Got unexpected caps %#lx.\n", desc
.ddsCaps
.dwCaps
);
10136 ok(desc
.dwWidth
== 256, "Got unexpected width %lu.\n", desc
.dwWidth
);
10137 ok(desc
.dwHeight
== 256, "Got unexpected height %lu.\n", desc
.dwHeight
);
10138 /* The overlay pitch seems to have 256 byte alignment. */
10139 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %lu.\n", U1(desc
).lPitch
);
10141 /* Fill the surface with some data for the blit test. */
10142 base
= desc
.lpSurface
;
10144 for (y
= 0; y
< desc
.dwHeight
; ++y
)
10146 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
10149 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
10151 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
10154 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
10156 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
10159 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10160 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10162 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
10163 * other block-based formats like DXT the entire Y channel is stored in
10164 * one big chunk of memory, followed by the chroma channels. So partial
10165 * locks do not really make sense. Show that they are allowed nevertheless
10166 * and the offset points into the luminance data. */
10167 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
10168 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10169 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
10170 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %lu.\n",
10171 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
10172 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10173 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10175 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10177 /* Windows XP with a Radeon X1600 GPU refuses to create a second
10178 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
10179 skip("Failed to create a second YV12 surface, skipping blit test.\n");
10180 IDirectDrawSurface_Release(src_surface
);
10184 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
10185 /* VMware rejects YV12 blits. This behavior has not been seen on real
10186 * hardware yet, so mark it broken. */
10187 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#lx.\n", hr
);
10191 memset(&desc
, 0, sizeof(desc
));
10192 desc
.dwSize
= sizeof(desc
);
10193 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10194 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10196 base
= desc
.lpSurface
;
10197 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
10198 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
10199 ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
10200 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
10201 ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
10203 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
10204 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10207 IDirectDrawSurface_Release(dst_surface
);
10208 IDirectDrawSurface_Release(src_surface
);
10210 IDirectDraw_Release(ddraw
);
10211 DestroyWindow(window
);
10214 static BOOL
dwm_enabled(void)
10218 if (!strcmp(winetest_platform
, "wine"))
10220 if (!pDwmIsCompositionEnabled
)
10222 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
10227 static void test_offscreen_overlay(void)
10229 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
10230 DDSURFACEDESC surface_desc
;
10231 IDirectDraw
*ddraw
;
10236 window
= create_window();
10237 ddraw
= create_ddraw();
10238 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10239 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10240 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10242 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10244 skip("Failed to create a UYVY overlay, skipping test.\n");
10248 memset(&surface_desc
, 0, sizeof(surface_desc
));
10249 surface_desc
.dwSize
= sizeof(surface_desc
);
10250 surface_desc
.dwFlags
= DDSD_CAPS
;
10251 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10252 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10253 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10255 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10256 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10257 * surface prevents this by disabling the dwm. */
10258 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10259 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10260 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10261 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10263 /* Try to overlay a NULL surface. */
10264 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
10265 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10266 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
10267 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10269 /* Try to overlay an offscreen surface. */
10270 memset(&surface_desc
, 0, sizeof(surface_desc
));
10271 surface_desc
.dwSize
= sizeof(surface_desc
);
10272 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
10273 surface_desc
.dwWidth
= 64;
10274 surface_desc
.dwHeight
= 64;
10275 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10276 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10277 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10278 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
10279 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
10280 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0xf800;
10281 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x07e0;
10282 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x001f;
10283 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10284 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10286 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
10287 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
10288 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
10289 "Failed to update overlay, hr %#lx.\n", hr
);
10291 /* Try to overlay the primary with a non-overlay surface. */
10292 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10293 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
10294 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10295 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
10297 IDirectDrawSurface_Release(offscreen
);
10298 IDirectDrawSurface_Release(primary
);
10299 IDirectDrawSurface_Release(overlay
);
10301 IDirectDraw_Release(ddraw
);
10302 DestroyWindow(window
);
10305 static void test_overlay_rect(void)
10307 IDirectDrawSurface
*overlay
, *primary
= NULL
;
10308 DDSURFACEDESC surface_desc
;
10309 RECT rect
= {0, 0, 64, 64};
10310 IDirectDraw
*ddraw
;
10316 window
= create_window();
10317 ddraw
= create_ddraw();
10318 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10319 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10320 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10322 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10324 skip("Failed to create a UYVY overlay, skipping test.\n");
10328 memset(&surface_desc
, 0, sizeof(surface_desc
));
10329 surface_desc
.dwSize
= sizeof(surface_desc
);
10330 surface_desc
.dwFlags
= DDSD_CAPS
;
10331 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10332 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10333 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10335 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10336 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10337 * surface prevents this by disabling the dwm. */
10338 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10339 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10340 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10341 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10343 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
10346 win_skip("Cannot disable DWM, skipping overlay test.\n");
10350 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
10351 * used. This is not true in Windows Vista and earlier, but changed in
10353 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10354 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10355 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10356 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10357 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10358 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10360 /* Show that the overlay position is the (top, left) coordinate of the
10361 * destination rectangle. */
10362 OffsetRect(&rect
, 32, 16);
10363 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10364 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10365 pos_x
= -1; pos_y
= -1;
10366 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10367 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
10368 ok(pos_x
== rect
.left
, "Got unexpected pos_x %ld, expected %ld.\n", pos_x
, rect
.left
);
10369 ok(pos_y
== rect
.top
, "Got unexpected pos_y %ld, expected %ld.\n", pos_y
, rect
.top
);
10371 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
10372 * seen that the overlay overlays the whole primary(==screen). */
10373 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
10374 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#lx.\n", hr2
);
10375 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10376 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
10377 if (SUCCEEDED(hr2
))
10379 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
10380 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
10384 ok(pos_x
== 32, "Got unexpected pos_x %ld.\n", pos_x
);
10385 ok(pos_y
== 16, "Got unexpected pos_y %ld.\n", pos_y
);
10388 /* The position cannot be retrieved when the overlay is not shown. */
10389 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
10390 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10391 pos_x
= -1; pos_y
= -1;
10392 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10393 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#lx.\n", hr
);
10394 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
10395 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
10399 IDirectDrawSurface_Release(primary
);
10401 IDirectDrawSurface_Release(overlay
);
10402 IDirectDraw_Release(ddraw
);
10403 DestroyWindow(window
);
10406 static void test_blt(void)
10408 IDirectDrawSurface
*surface
, *rt
;
10409 DDSURFACEDESC surface_desc
;
10410 IDirect3DDevice
*device
;
10411 IDirectDraw
*ddraw
;
10425 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
10426 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
10427 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
10428 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
10429 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
10430 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
10431 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
10432 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
10433 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
10434 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
10437 window
= create_window();
10438 ddraw
= create_ddraw();
10439 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10440 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10442 skip("Failed to create a 3D device, skipping test.\n");
10443 IDirectDraw_Release(ddraw
);
10444 DestroyWindow(window
);
10448 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
10449 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10451 memset(&surface_desc
, 0, sizeof(surface_desc
));
10452 surface_desc
.dwSize
= sizeof(surface_desc
);
10453 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10454 surface_desc
.dwWidth
= 640;
10455 surface_desc
.dwHeight
= 480;
10456 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10457 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10458 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10460 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
10461 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10463 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
10464 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10466 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10468 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10469 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10470 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
10472 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10473 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10474 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
10476 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10477 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10478 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10480 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
10481 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10484 IDirectDrawSurface_Release(surface
);
10485 IDirectDrawSurface_Release(rt
);
10486 refcount
= IDirect3DDevice_Release(device
);
10487 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10488 IDirectDraw_Release(ddraw
);
10489 DestroyWindow(window
);
10492 static void test_blt_z_alpha(void)
10494 DWORD blt_flags
[] =
10498 DDBLT_ALPHADESTCONSTOVERRIDE
,
10499 DDBLT_ALPHADESTNEG
,
10500 DDBLT_ALPHADESTSURFACEOVERRIDE
,
10501 DDBLT_ALPHAEDGEBLEND
,
10504 DDBLT_ALPHASRCCONSTOVERRIDE
,
10506 DDBLT_ALPHASRCSURFACEOVERRIDE
,
10509 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
10510 DDBLT_ZBUFFERDESTOVERRIDE
,
10511 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
10512 DDBLT_ZBUFFERSRCOVERRIDE
,
10514 IDirectDrawSurface
*src_surface
, *dst_surface
;
10515 DDSURFACEDESC surface_desc
;
10516 unsigned int color
, i
;
10517 IDirectDraw
*ddraw
;
10524 window
= create_window();
10525 ddraw
= create_ddraw();
10526 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10527 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10528 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10530 memset(&pf
, 0, sizeof(pf
));
10531 pf
.dwSize
= sizeof(pf
);
10532 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10533 U1(pf
).dwRGBBitCount
= 32;
10534 U2(pf
).dwRBitMask
= 0x00ff0000;
10535 U3(pf
).dwGBitMask
= 0x0000ff00;
10536 U4(pf
).dwBBitMask
= 0x000000ff;
10537 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
10539 memset(&surface_desc
, 0, sizeof(surface_desc
));
10540 surface_desc
.dwSize
= sizeof(surface_desc
);
10541 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10542 surface_desc
.dwWidth
= 64;
10543 surface_desc
.dwHeight
= 64;
10544 surface_desc
.ddpfPixelFormat
= pf
;
10545 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10547 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
10548 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
10549 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
10550 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
10552 memset(&fx
, 0, sizeof(fx
));
10553 fx
.dwSize
= sizeof(fx
);
10554 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
10555 fx
.dwZDestConstBitDepth
= 32;
10556 U1(fx
).dwZDestConst
= 0x11111111;
10557 fx
.dwZSrcConstBitDepth
= 32;
10558 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
10559 fx
.dwAlphaEdgeBlendBitDepth
= 8;
10560 fx
.dwAlphaEdgeBlend
= 0x7f;
10561 fx
.dwAlphaDestConstBitDepth
= 8;
10562 U3(fx
).dwAlphaDestConst
= 0xdd;
10563 fx
.dwAlphaSrcConstBitDepth
= 8;
10564 U4(fx
).dwAlphaSrcConst
= 0x22;
10566 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
10568 U5(fx
).dwFillColor
= 0x3300ff00;
10569 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10570 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10572 U5(fx
).dwFillColor
= 0xccff0000;
10573 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10574 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10576 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
10577 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10579 color
= get_surface_color(dst_surface
, 32, 32);
10580 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
10583 IDirectDrawSurface_Release(dst_surface
);
10584 IDirectDrawSurface_Release(src_surface
);
10585 refcount
= IDirectDraw_Release(ddraw
);
10586 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
10587 DestroyWindow(window
);
10590 static void test_cross_device_blt(void)
10592 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
10593 IDirect3DDevice
*device
, *device2
;
10594 IDirectDraw
*ddraw
, *ddraw2
;
10595 DDSURFACEDESC surface_desc
;
10596 HWND window
, window2
;
10597 unsigned int color
;
10602 window
= create_window();
10603 ddraw
= create_ddraw();
10604 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
10606 skip("Failed to create a 3D device.\n");
10607 IDirectDraw_Release(ddraw
);
10608 DestroyWindow(window
);
10612 window2
= create_window();
10613 ddraw2
= create_ddraw();
10614 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
10616 skip("Failed to create a 3D device.\n");
10617 IDirectDraw_Release(ddraw2
);
10618 IDirect3DDevice_Release(device
);
10619 IDirectDraw_Release(ddraw
);
10620 DestroyWindow(window
);
10621 DestroyWindow(window2
);
10625 memset(&surface_desc
, 0, sizeof(surface_desc
));
10626 surface_desc
.dwSize
= sizeof(surface_desc
);
10627 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10628 surface_desc
.dwWidth
= 640;
10629 surface_desc
.dwHeight
= 480;
10630 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10631 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
10632 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10634 memset(&surface_desc
, 0, sizeof(surface_desc
));
10635 surface_desc
.dwSize
= sizeof(surface_desc
);
10636 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10637 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
10638 surface_desc
.dwBackBufferCount
= 2;
10639 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10640 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10642 memset(&surface_desc
, 0, sizeof(surface_desc
));
10643 surface_desc
.dwSize
= sizeof(surface_desc
);
10644 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10645 surface_desc
.dwWidth
= 640;
10646 surface_desc
.dwHeight
= 480;
10647 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10648 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10649 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10650 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 16;
10651 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
10652 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
10653 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
10654 hr
= IDirectDraw_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10655 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10657 memset(&fx
, 0, sizeof(fx
));
10658 fx
.dwSize
= sizeof(fx
);
10659 U5(fx
).dwFillColor
= 0xff0000ff;
10660 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10661 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
10663 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10664 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10665 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
10666 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10667 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10668 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10669 color
= get_surface_color(surface
, 320, 240);
10670 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10672 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10673 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10674 color
= get_surface_color(sysmem_surface
, 320, 240);
10675 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10677 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10678 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10679 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
10680 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10682 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10683 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10684 color
= get_surface_color(sysmem_surface
, 320, 240);
10685 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10687 IDirectDrawSurface_Release(surface2
);
10688 memset(&surface_desc
, 0, sizeof(surface_desc
));
10689 surface_desc
.dwSize
= sizeof(surface_desc
);
10690 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10691 surface_desc
.dwWidth
= 640;
10692 surface_desc
.dwHeight
= 480;
10693 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10694 hr
= IDirectDraw_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10695 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10696 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10697 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
10699 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10700 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#lx.\n", hr
);
10701 color
= get_surface_color(sysmem_surface
, 320, 240);
10702 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10704 IDirectDrawSurface_Release(surface
);
10705 IDirectDrawSurface_Release(surface2
);
10706 IDirectDrawSurface_Release(sysmem_surface
);
10707 refcount
= IDirect3DDevice_Release(device
);
10708 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10709 refcount
= IDirect3DDevice_Release(device2
);
10710 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10711 IDirectDraw_Release(ddraw
);
10712 IDirectDraw_Release(ddraw2
);
10713 DestroyWindow(window
);
10714 DestroyWindow(window2
);
10717 static void test_getdc(void)
10719 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
10720 DDSURFACEDESC surface_desc
, map_desc
;
10721 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
10722 IDirectDraw
*ddraw
;
10723 unsigned int i
, screen_bpp
;
10728 static const struct
10731 DDPIXELFORMAT format
;
10732 BOOL getdc_supported
;
10733 HRESULT alt_result
;
10737 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10738 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
10739 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10740 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
10741 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10742 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10743 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10744 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10745 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10746 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
10747 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10748 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10749 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10750 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10751 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10752 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
10753 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10754 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10755 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10756 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10757 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
10758 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
10759 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
10760 * This is not implemented in wine yet, so disable the test for now.
10761 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
10762 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
10763 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
10765 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
10766 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10767 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
10768 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
10769 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
10770 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10771 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
10772 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10773 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
10774 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10775 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
10776 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10777 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
10778 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10781 window
= create_window();
10782 ddraw
= create_ddraw();
10783 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10784 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10785 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10787 surface_desc
.dwSize
= sizeof(surface_desc
);
10788 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
10789 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
10790 screen_bpp
= U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
;
10792 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10794 memset(&surface_desc
, 0, sizeof(surface_desc
));
10795 surface_desc
.dwSize
= sizeof(surface_desc
);
10796 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10797 surface_desc
.dwWidth
= 64;
10798 surface_desc
.dwHeight
= 64;
10799 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
10800 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10802 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10804 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10805 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10807 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", test_data
[i
].name
, hr
);
10812 dc
= (void *)0x1234;
10813 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10814 if (test_data
[i
].getdc_supported
)
10815 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
10816 "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10818 ok(FAILED(hr
), "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10822 unsigned int width_bytes
;
10828 type
= GetObjectType(dc
);
10829 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
10830 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
10831 type
= GetObjectType(bitmap
);
10832 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
10834 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
10835 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
10836 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
10837 dib
.dsBm
.bmType
, test_data
[i
].name
);
10838 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
10839 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
10840 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
10841 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
10842 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
10843 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
10844 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
10845 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
10846 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
10847 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
10848 "Got unexpected bit count %d for format %s.\n",
10849 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
10850 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
10851 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
10852 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
10853 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
10854 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
10856 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %lu for format %s.\n",
10857 dib
.dsBmih
.biSize
, test_data
[i
].name
);
10858 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %ld for format %s.\n",
10859 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10860 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %ld for format %s.\n",
10861 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10862 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
10863 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
10864 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
10865 "Got unexpected bit count %u for format %s.\n",
10866 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
10867 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
10868 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
10869 "Got unexpected compression %#lx for format %s.\n",
10870 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
10871 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %lu for format %s.\n",
10872 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
10873 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %ld for format %s.\n",
10874 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
10875 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %ld for format %s.\n",
10876 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
10877 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %lu for format %s.\n",
10878 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
10879 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %lu for format %s.\n",
10880 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
10882 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
10884 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
10885 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
10886 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
10887 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
10888 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
10889 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10893 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
10894 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
10895 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
10897 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
10898 ok(!dib
.dsOffset
, "Got unexpected offset %lu for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
10900 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10901 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10905 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10908 IDirectDrawSurface_Release(surface
);
10913 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
10914 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10916 skip("Failed to create mip-mapped texture for format %s (hr %#lx), skipping tests.\n",
10917 test_data
[i
].name
, hr
);
10921 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
10922 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10923 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
10924 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10925 IDirectDrawSurface_Release(tmp
);
10927 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10928 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10929 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10930 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10931 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10932 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10933 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10934 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10936 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10937 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10938 dc2
= (void *)0x1234;
10939 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10940 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10941 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
10942 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10943 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10944 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10945 ok(hr
== DDERR_NODC
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10947 map_desc
.dwSize
= sizeof(map_desc
);
10948 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10949 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10950 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10951 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10952 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10953 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10954 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10955 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10957 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10958 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10959 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10960 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10961 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10962 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10964 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10965 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10966 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10967 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10968 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10969 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10970 /* Geforce 9600, Windows 7 returns E_FAIL. The unlock still seems to work as intended, after-
10971 * wards the surface can be locked again. ReleaseDC() does not unlock the surface, trying to
10972 * Lock it after ReleaseDC returns DDERR_SURFACEBUSY. ddraw4 and 7 are unaffected. */
10973 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10974 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
10975 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10977 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10978 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10979 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
10980 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10981 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
10982 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10983 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
10984 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10986 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
10987 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10988 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
10989 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10990 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
10991 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10992 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
10993 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10995 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10996 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10997 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
10998 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
10999 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11000 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11001 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11002 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11004 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11005 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11006 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11007 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11008 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11009 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11010 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11011 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11012 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11014 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11015 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11016 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11017 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11018 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11019 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11020 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11021 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11023 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11024 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11025 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11026 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11027 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11028 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11029 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11030 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11032 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11033 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11034 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11035 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11036 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11037 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11038 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11039 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11041 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11042 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11043 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11044 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11045 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11046 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11047 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11048 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11049 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11050 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11052 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11053 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11054 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11055 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11056 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11057 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11058 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11059 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11060 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11061 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11063 IDirectDrawSurface_Release(surface2
);
11064 IDirectDrawSurface_Release(surface
);
11067 IDirectDraw_Release(ddraw
);
11068 DestroyWindow(window
);
11071 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
11072 * The stride is honored for navigating to the next vertex. 3 floats input position
11073 * are read, and 16 bytes extra vertex data are copied around. */
11074 struct transform_input
11076 float x
, y
, z
, unused1
; /* Position data, transformed. */
11077 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
11081 struct transform_output
11084 unsigned int v1
, v2
, v3
, v4
;
11085 unsigned int unused3
, unused4
;
11088 static void test_transform_vertices(void)
11090 unsigned int inst_length
, color
;
11091 IDirect3DDevice
*device
;
11092 IDirectDrawSurface
*rt
;
11093 IDirectDraw
*ddraw
;
11097 IDirect3DViewport
*viewport
;
11098 IDirect3DExecuteBuffer
*execute_buffer
;
11099 IDirect3DMaterial
*background
;
11100 D3DEXECUTEBUFFERDESC exec_desc
;
11102 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
11103 static struct transform_input position_tests
[] =
11105 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11106 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
11107 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
11108 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
11109 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
11110 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
11112 static struct transform_input cliptest
[] =
11114 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
11115 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
11116 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11117 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
11119 static struct transform_input offscreentest
[] =
11121 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11123 struct transform_output out
[ARRAY_SIZE(position_tests
)];
11124 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
11125 D3DTRANSFORMDATA transformdata
;
11126 static const D3DVIEWPORT vp_template
=
11128 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
11130 D3DVIEWPORT vp_data
=
11132 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
11136 static D3DMATRIX mat_scale
=
11138 2.0f
, 0.0f
, 0.0f
, 0.0f
,
11139 0.0f
, 2.0f
, 0.0f
, 0.0f
,
11140 0.0f
, 0.0f
, 2.0f
, 0.0f
,
11141 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11145 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11146 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11147 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11148 1.0f
, 0.0f
, 0.0f
, 1.0f
,
11152 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11153 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11154 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11155 0.0f
, 1.0f
, 0.0f
, 1.0f
,
11157 static const D3DLVERTEX quad
[] =
11159 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11160 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11161 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11162 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11164 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11167 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
11169 out
[i
].unused3
= 0xdeadbeef;
11170 out
[i
].unused4
= 0xcafecafe;
11173 window
= create_window();
11174 ddraw
= create_ddraw();
11175 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11176 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11178 skip("Failed to create a 3D device, skipping test.\n");
11179 IDirectDraw_Release(ddraw
);
11180 DestroyWindow(window
);
11184 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
11185 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11187 viewport
= create_viewport(device
, 0, 0, 256, 256);
11188 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11189 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11191 memset(&transformdata
, 0, sizeof(transformdata
));
11192 transformdata
.dwSize
= sizeof(transformdata
);
11193 transformdata
.lpIn
= position_tests
;
11194 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11195 transformdata
.lpOut
= out
;
11196 transformdata
.dwOutSize
= sizeof(out
[0]);
11197 transformdata
.lpHOut
= NULL
;
11199 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11200 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11201 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11202 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11204 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11206 static const struct vec4 cmp
[] =
11208 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
11209 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
11212 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11213 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11214 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11215 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
11216 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
11217 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
11218 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
11219 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
11222 vp_data
= vp_template
;
11223 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11224 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11225 offscreen
= 0xdeadbeef;
11226 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11227 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11228 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11229 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11231 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11233 static const struct vec4 cmp
[] =
11235 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
11236 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
11238 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11239 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11240 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11245 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11246 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11247 offscreen
= 0xdeadbeef;
11248 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11249 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11250 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11251 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11252 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11254 static const struct vec4 cmp
[] =
11256 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
11257 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11259 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11260 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11261 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11264 transformdata
.lpHOut
= out_h
;
11265 offscreen
= 0xdeadbeef;
11266 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11267 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11268 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11269 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11270 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11272 static const D3DHVERTEX cmp_h
[] =
11274 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
11275 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
11276 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
11278 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
11279 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
11280 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
11281 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
11282 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
11283 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
11285 /* No scheme has been found behind those return values. It seems to be
11286 * whatever data windows has when throwing the vertex away. Modify the
11287 * input test vertices to test this more. Depending on the input data
11288 * it can happen that the z coord gets written into y, or similar things. */
11291 static const struct vec4 cmp
[] =
11293 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
11294 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11296 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11297 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11298 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11302 transformdata
.lpIn
= cliptest
;
11303 transformdata
.dwInSize
= sizeof(cliptest
[0]);
11304 offscreen
= 0xdeadbeef;
11305 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11306 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11307 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11308 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11309 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11311 static const DWORD flags
[] =
11314 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
11316 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
11318 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11321 vp_data
= vp_template
;
11322 vp_data
.dwWidth
= 10;
11323 vp_data
.dwHeight
= 1000;
11324 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11325 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11326 offscreen
= 0xdeadbeef;
11327 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11328 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11329 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11330 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11331 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11333 static const DWORD flags
[] =
11336 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
11338 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
11340 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11343 vp_data
= vp_template
;
11344 vp_data
.dwWidth
= 256;
11345 vp_data
.dwHeight
= 256;
11346 vp_data
.dvScaleX
= 1;
11347 vp_data
.dvScaleY
= 1;
11348 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11349 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11350 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11351 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11352 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11353 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11354 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11356 static const DWORD flags
[] =
11363 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11366 /* Finally try to figure out how the DWORD dwOffscreen works.
11367 * It is a logical AND of the vertices' dwFlags members. */
11368 vp_data
= vp_template
;
11369 vp_data
.dwWidth
= 5;
11370 vp_data
.dwHeight
= 5;
11371 vp_data
.dvScaleX
= 10000.0f
;
11372 vp_data
.dvScaleY
= 10000.0f
;
11373 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11374 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11375 transformdata
.lpIn
= cliptest
;
11376 offscreen
= 0xdeadbeef;
11377 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11378 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11379 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11380 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11382 offscreen
= 0xdeadbeef;
11383 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11384 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11385 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11386 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11387 offscreen
= 0xdeadbeef;
11388 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
11389 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11390 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11391 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11392 hr
= IDirect3DViewport_TransformVertices(viewport
, 3,
11393 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11394 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11395 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11397 transformdata
.lpIn
= cliptest
+ 1;
11398 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11399 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11400 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11401 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11403 transformdata
.lpIn
= cliptest
+ 2;
11404 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11405 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11406 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11407 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11408 offscreen
= 0xdeadbeef;
11409 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
11410 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11411 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11412 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11414 transformdata
.lpIn
= cliptest
+ 3;
11415 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11416 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11417 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11418 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11420 transformdata
.lpIn
= offscreentest
;
11421 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
11422 vp_data
= vp_template
;
11423 vp_data
.dwWidth
= 257;
11424 vp_data
.dwHeight
= 257;
11425 vp_data
.dvScaleX
= 1.0f
;
11426 vp_data
.dvScaleY
= 1.0f
;
11427 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11428 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11429 offscreen
= 0xdeadbeef;
11430 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11431 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11432 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11433 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11435 vp_data
.dwWidth
= 256;
11436 vp_data
.dwHeight
= 256;
11437 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11438 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11439 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11440 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11441 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11442 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %#lx.\n", offscreen
);
11444 /* Test the effect of Matrices.
11446 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
11447 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
11448 * the view matrix and the +1's from the world and projection matrix. */
11451 vp_data
.dwWidth
= 256;
11452 vp_data
.dwHeight
= 256;
11453 vp_data
.dvScaleX
= 5.0f
;
11454 vp_data
.dvScaleY
= 5.0f
;
11455 vp_data
.dvMinZ
= 0.0f
;
11456 vp_data
.dvMaxZ
= 1.0f
;
11457 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11458 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11460 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
11461 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11462 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat_translate1
);
11463 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11465 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
11466 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11467 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat_scale
);
11468 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11470 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
11471 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11472 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat_translate2
);
11473 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11475 memset(&exec_desc
, 0, sizeof(exec_desc
));
11476 exec_desc
.dwSize
= sizeof(exec_desc
);
11477 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
11478 exec_desc
.dwBufferSize
= 1024;
11479 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
11480 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
11481 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
11483 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
11484 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
11485 ptr
= (BYTE
*)exec_desc
.lpData
;
11486 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
11487 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
11488 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
11490 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
11491 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
11492 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
11494 set_execute_data(execute_buffer
, 0, 0, inst_length
);
11495 hr
= IDirect3DDevice_BeginScene(device
);
11496 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11497 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
11498 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
11499 hr
= IDirect3DDevice_EndScene(device
);
11500 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11502 transformdata
.lpIn
= position_tests
;
11503 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11504 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11505 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11506 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11508 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11510 static const struct vec4 cmp
[] =
11512 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
11513 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
11516 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11517 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11518 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11521 /* Invalid flags. */
11522 offscreen
= 0xdeadbeef;
11523 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11524 &transformdata
, 0, &offscreen
);
11525 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11526 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11528 /* NULL transform data. */
11529 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11530 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11531 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11532 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11533 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11534 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11535 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11536 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11538 /* NULL transform data and NULL dwOffscreen.
11540 * Valid transform data + NULL dwOffscreen -> crash. */
11541 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11542 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
11543 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11546 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11547 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11548 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11549 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11550 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11551 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11552 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11553 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
11555 /* Invalid sizes. */
11556 offscreen
= 0xdeadbeef;
11557 transformdata
.dwSize
= sizeof(transformdata
) - 1;
11558 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11559 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11560 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11561 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11562 transformdata
.dwSize
= sizeof(transformdata
) + 1;
11563 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11564 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11565 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11566 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11568 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
11569 transformdata
.dwSize
= sizeof(transformdata
);
11570 transformdata
.lpIn
= NULL
;
11571 transformdata
.lpOut
= NULL
;
11572 offscreen
= 0xdeadbeef;
11573 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11574 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11575 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11576 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
11578 /* Test how vertices are transformed by execute buffers. */
11581 vp_data
.dwWidth
= 200;
11582 vp_data
.dwHeight
= 400;
11583 vp_data
.dvScaleX
= 20.0f
;
11584 vp_data
.dvScaleY
= 50.0f
;
11585 vp_data
.dvMinZ
= 0.0f
;
11586 vp_data
.dvMaxZ
= 1.0f
;
11587 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11588 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11590 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
11591 viewport_set_background(device
, viewport
, background
);
11592 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11593 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
11595 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
11596 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
11597 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
11598 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
11599 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
11600 emit_tquad(&ptr
, 0);
11602 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
11603 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
11604 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
11606 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
11607 hr
= IDirect3DDevice_BeginScene(device
);
11608 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11609 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
11610 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
11611 hr
= IDirect3DDevice_EndScene(device
);
11612 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11614 color
= get_surface_color(rt
, 128, 143);
11615 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11616 color
= get_surface_color(rt
, 132, 143);
11617 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11618 color
= get_surface_color(rt
, 128, 147);
11619 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11620 color
= get_surface_color(rt
, 132, 147);
11621 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11623 color
= get_surface_color(rt
, 177, 217);
11624 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11625 color
= get_surface_color(rt
, 181, 217);
11626 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11627 color
= get_surface_color(rt
, 177, 221);
11628 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11629 color
= get_surface_color(rt
, 181, 221);
11630 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11632 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
11633 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
11634 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
11635 IDirect3DExecuteBuffer_Release(execute_buffer
);
11637 IDirectDrawSurface_Release(rt
);
11638 destroy_viewport(device
, viewport
);
11639 IDirect3DMaterial_Release(background
);
11640 refcount
= IDirect3DDevice_Release(device
);
11641 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11642 IDirectDraw_Release(ddraw
);
11643 DestroyWindow(window
);
11646 static void test_display_mode_surface_pixel_format(void)
11648 unsigned int width
, height
, bpp
;
11649 IDirectDrawSurface
*surface
;
11650 DDSURFACEDESC surface_desc
;
11651 IDirectDraw
*ddraw
;
11656 if (!(ddraw
= create_ddraw()))
11658 skip("Failed to create ddraw.\n");
11662 surface_desc
.dwSize
= sizeof(surface_desc
);
11663 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
11664 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11665 width
= surface_desc
.dwWidth
;
11666 height
= surface_desc
.dwHeight
;
11668 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
11669 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
11670 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
11671 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11674 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 16)))
11676 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24)))
11678 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
11680 ok(bpp
, "Set display mode failed.\n");
11682 surface_desc
.dwSize
= sizeof(surface_desc
);
11683 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
11684 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11685 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
11686 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
11687 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11688 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11690 memset(&surface_desc
, 0, sizeof(surface_desc
));
11691 surface_desc
.dwSize
= sizeof(surface_desc
);
11692 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11693 surface_desc
.dwBackBufferCount
= 1;
11694 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
11695 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11696 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
11697 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11698 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
11699 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
11700 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
11701 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
11702 surface_desc
.ddpfPixelFormat
.dwFlags
);
11703 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11704 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11705 IDirectDrawSurface_Release(surface
);
11707 memset(&surface_desc
, 0, sizeof(surface_desc
));
11708 surface_desc
.dwSize
= sizeof(surface_desc
);
11709 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11710 surface_desc
.dwWidth
= width
;
11711 surface_desc
.dwHeight
= height
;
11712 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11713 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11714 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
11715 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11716 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
11717 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
11718 surface_desc
.ddpfPixelFormat
.dwFlags
);
11719 ok(U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11720 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
, bpp
);
11721 IDirectDrawSurface_Release(surface
);
11723 refcount
= IDirectDraw_Release(ddraw
);
11724 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
11725 DestroyWindow(window
);
11728 static void test_surface_desc_size(void)
11733 DDSURFACEDESC desc1
;
11734 DDSURFACEDESC2 desc2
;
11737 IDirectDrawSurface7
*surface7
;
11738 IDirectDrawSurface
*surface
;
11739 DDSURFACEDESC surface_desc
;
11740 HRESULT expected_hr
, hr
;
11741 IDirectDraw
*ddraw
;
11745 static const struct
11752 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
11753 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
11754 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
11756 static const unsigned int desc_sizes
[] =
11758 sizeof(DDSURFACEDESC
),
11759 sizeof(DDSURFACEDESC2
),
11760 sizeof(DDSURFACEDESC
) + 1,
11761 sizeof(DDSURFACEDESC2
) + 1,
11762 2 * sizeof(DDSURFACEDESC
),
11763 2 * sizeof(DDSURFACEDESC2
),
11764 sizeof(DDSURFACEDESC
) - 1,
11765 sizeof(DDSURFACEDESC2
) - 1,
11766 sizeof(DDSURFACEDESC
) / 2,
11767 sizeof(DDSURFACEDESC2
) / 2,
11772 sizeof(desc
) - 100,
11775 if (!(ddraw
= create_ddraw()))
11777 skip("Failed to create ddraw.\n");
11780 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
11781 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11783 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
11785 memset(&surface_desc
, 0, sizeof(surface_desc
));
11786 surface_desc
.dwSize
= sizeof(surface_desc
);
11787 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11788 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
11789 surface_desc
.dwHeight
= 128;
11790 surface_desc
.dwWidth
= 128;
11791 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11793 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
11796 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
11797 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
11799 /* GetSurfaceDesc() */
11800 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11802 memset(&desc
, 0, sizeof(desc
));
11803 desc
.dwSize
= desc_sizes
[j
];
11804 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11805 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
11806 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11807 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11809 memset(&desc
, 0, sizeof(desc
));
11810 desc
.dwSize
= desc_sizes
[j
];
11811 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11812 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
11813 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11814 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11818 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11820 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
11821 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
11822 DWORD expected_texture_stage
;
11824 memset(&desc
, 0, sizeof(desc
));
11825 desc
.dwSize
= desc_sizes
[j
];
11826 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11827 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11828 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
11829 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11830 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11831 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11832 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
11833 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11834 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
11835 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11838 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
11839 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11840 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
11841 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11842 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11843 todo_wine_if(!expected_texture_stage
)
11844 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11845 "Got unexpected texture stage %#lx, size %u, type %s.\n",
11846 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11847 IDirectDrawSurface_Unlock(surface
, NULL
);
11850 memset(&desc
, 0, sizeof(desc
));
11851 desc
.dwSize
= desc_sizes
[j
];
11852 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11853 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11854 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
11855 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11856 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11857 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11858 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
11859 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11860 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
11861 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11864 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
11865 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11866 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
11867 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11868 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11869 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11870 "Got unexpected texture stage %#lx, size %u, type %s.\n",
11871 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11872 IDirectDrawSurface7_Unlock(surface7
, NULL
);
11876 IDirectDrawSurface7_Release(surface7
);
11877 IDirectDrawSurface_Release(surface
);
11880 /* GetDisplayMode() */
11881 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11883 memset(&desc
, 0xcc, sizeof(desc
));
11884 desc
.dwSize
= desc_sizes
[j
];
11885 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
11886 ? DD_OK
: DDERR_INVALIDPARAMS
;
11887 hr
= IDirectDraw_GetDisplayMode(ddraw
, &desc
.desc1
);
11888 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
11891 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %lu for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
11892 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
11893 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
11897 refcount
= IDirectDraw_Release(ddraw
);
11898 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
11901 static void test_texture_load(void)
11903 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11904 static D3DTLVERTEX tquad
[] =
11906 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
11907 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
11908 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
11909 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
11911 D3DTEXTUREHANDLE dst_texture_handle
, src_texture_handle
;
11912 IDirectDrawSurface
*dst_surface
, *src_surface
;
11913 IDirect3DExecuteBuffer
*execute_buffer
;
11914 unsigned int inst_length
, color
;
11915 D3DEXECUTEBUFFERDESC exec_desc
;
11916 IDirect3DMaterial
*background
;
11917 IDirect3DViewport
*viewport
;
11918 DDSURFACEDESC surface_desc
;
11919 IDirect3DTexture
*texture
;
11920 IDirect3DDevice
*device
;
11921 IDirectDrawSurface
*rt
;
11922 IDirectDraw
*ddraw
;
11929 window
= create_window();
11930 ddraw
= create_ddraw();
11931 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11932 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11934 skip("Failed to create a 3D device, skipping test.\n");
11935 IDirectDraw_Release(ddraw
);
11936 DestroyWindow(window
);
11940 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
11941 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11943 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
11944 viewport
= create_viewport(device
, 0, 0, 640, 480);
11945 viewport_set_background(device
, viewport
, background
);
11947 memset(&exec_desc
, 0, sizeof(exec_desc
));
11948 exec_desc
.dwSize
= sizeof(exec_desc
);
11949 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
11950 exec_desc
.dwBufferSize
= 1024;
11951 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
11952 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
11953 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
11955 memset(&surface_desc
, 0, sizeof(surface_desc
));
11956 surface_desc
.dwSize
= sizeof(surface_desc
);
11957 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11958 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11959 surface_desc
.dwWidth
= 256;
11960 surface_desc
.dwHeight
= 256;
11961 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
11962 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11963 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
11964 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11965 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11966 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11968 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11969 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11970 hr
= IDirectDrawSurface_QueryInterface(src_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
11971 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
11972 hr
= IDirect3DTexture_GetHandle(texture
, device
, &src_texture_handle
);
11973 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
11974 IDirect3DTexture_Release(texture
);
11976 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11977 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
11978 hr
= IDirectDrawSurface_QueryInterface(dst_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
11979 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
11980 hr
= IDirect3DTexture_GetHandle(texture
, device
, &dst_texture_handle
);
11981 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
11982 IDirect3DTexture_Release(texture
);
11984 memset(&fx
, 0, sizeof(fx
));
11985 fx
.dwSize
= sizeof(fx
);
11986 U5(fx
).dwFillColor
= 0x0000ffff;
11987 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11988 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
11990 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
11991 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
11992 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
11993 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
11994 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
11995 emit_texture_load(&ptr
, dst_texture_handle
, src_texture_handle
);
11996 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, dst_texture_handle
);
11997 /* WARP randomly applies color keying without having a key set. */
11998 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
11999 emit_tquad(&ptr
, 0);
12001 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
12002 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
12003 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
12005 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12006 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12007 color
= get_surface_color(rt
, 320, 240);
12008 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
12009 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
12010 hr
= IDirect3DDevice_BeginScene(device
);
12011 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12012 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
12013 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12014 hr
= IDirect3DDevice_EndScene(device
);
12015 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12016 color
= get_surface_color(rt
, 320, 240);
12017 ok(compare_color(color
, 0x0000ffff, 1), "Got unexpected color 0x%08x.\n", color
);
12019 memset(&fx
, 0, sizeof(fx
));
12020 fx
.dwSize
= sizeof(fx
);
12021 U5(fx
).dwFillColor
= 0x000000ff;
12022 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12023 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
12025 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12026 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12027 color
= get_surface_color(rt
, 320, 240);
12028 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
12029 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
12030 hr
= IDirect3DDevice_BeginScene(device
);
12031 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12032 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
12033 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12034 hr
= IDirect3DDevice_EndScene(device
);
12035 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12036 color
= get_surface_color(rt
, 320, 240);
12037 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12039 IDirectDrawSurface_Release(dst_surface
);
12040 IDirectDrawSurface_Release(src_surface
);
12041 IDirectDrawSurface_Release(rt
);
12042 IDirect3DExecuteBuffer_Release(execute_buffer
);
12043 IDirect3DMaterial_Release(background
);
12044 destroy_viewport(device
, viewport
);
12045 IDirect3DDevice_Release(device
);
12046 refcount
= IDirectDraw_Release(ddraw
);
12047 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12048 DestroyWindow(window
);
12051 static void test_ck_operation(void)
12053 IDirectDrawSurface
*src
, *dst
;
12054 IDirectDrawSurface7
*src7
, *dst7
;
12055 DDSURFACEDESC surface_desc
;
12056 unsigned int i
, *color
;
12057 IDirectDraw
*ddraw
;
12064 window
= create_window();
12065 ddraw
= create_ddraw();
12066 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12067 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12068 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12070 memset(&surface_desc
, 0, sizeof(surface_desc
));
12071 surface_desc
.dwSize
= sizeof(surface_desc
);
12072 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12073 surface_desc
.dwWidth
= 4;
12074 surface_desc
.dwHeight
= 1;
12075 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12076 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12077 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12078 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12079 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12080 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12081 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12082 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12084 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12085 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
12086 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
12087 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12088 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12090 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12091 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12092 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12093 color
= surface_desc
.lpSurface
;
12094 color
[0] = 0x77010203;
12095 color
[1] = 0x00010203;
12096 color
[2] = 0x77ff00ff;
12097 color
[3] = 0x00ff00ff;
12098 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
12099 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12101 for (i
= 0; i
< 2; ++i
)
12103 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12104 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12105 color
= surface_desc
.lpSurface
;
12106 color
[0] = 0xcccccccc;
12107 color
[1] = 0xcccccccc;
12108 color
[2] = 0xcccccccc;
12109 color
[3] = 0xcccccccc;
12110 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12111 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12115 hr
= IDirectDrawSurface_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
12116 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12120 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
12121 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12124 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
12125 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12126 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12127 color
= surface_desc
.lpSurface
;
12128 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
12129 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
12130 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
12131 * color keying nor copies it. */
12132 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
12133 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
12134 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12135 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
12136 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12137 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
12138 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
12139 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
12140 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
12141 color
[0], color
[1], color
[2], color
[3], i
);
12142 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12143 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12146 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12147 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12148 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
12149 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12151 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12152 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12153 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12155 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12156 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12157 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12158 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
12159 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12161 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
12162 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
12163 hr
= IDirectDrawSurface_GetSurfaceDesc(src
, &surface_desc
);
12164 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12165 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
12166 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
12167 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12168 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12170 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
12171 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12172 ckey
.dwColorSpaceHighValue
= 0x00000000;
12173 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12174 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12176 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12177 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12178 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12179 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12180 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12182 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12183 ckey
.dwColorSpaceHighValue
= 0x00000001;
12184 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12185 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12187 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12188 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12189 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12190 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12191 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12193 ckey
.dwColorSpaceLowValue
= 0x000000fe;
12194 ckey
.dwColorSpaceHighValue
= 0x000000fd;
12195 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12196 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12198 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12199 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12200 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12201 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
12202 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12204 IDirectDrawSurface_Release(src
);
12205 IDirectDrawSurface_Release(dst
);
12207 /* Test source and destination keys and where they are read from. Use a surface with alpha
12208 * to avoid driver-dependent content in the X channel. */
12209 memset(&surface_desc
, 0, sizeof(surface_desc
));
12210 surface_desc
.dwSize
= sizeof(surface_desc
);
12211 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12212 surface_desc
.dwWidth
= 6;
12213 surface_desc
.dwHeight
= 1;
12214 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12215 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12216 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
12217 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12218 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12219 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12220 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12221 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12222 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12223 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12224 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12226 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
12227 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12228 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
12229 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12230 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
12231 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
12232 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
12233 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#lx.\n", hr
);
12236 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
12237 skip("Failed to set destination color key, skipping related tests.\n");
12241 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12242 ckey
.dwColorSpaceHighValue
= 0x000000ff;
12243 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12244 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12245 ckey
.dwColorSpaceLowValue
= 0x000000aa;
12246 ckey
.dwColorSpaceHighValue
= 0x000000aa;
12247 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12248 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12250 memset(&fx
, 0, sizeof(fx
));
12251 fx
.dwSize
= sizeof(fx
);
12252 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
12253 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
12254 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
12255 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
12257 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12258 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12259 color
= surface_desc
.lpSurface
;
12260 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
12261 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
12262 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
12263 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
12264 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
12265 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
12266 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
12267 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12269 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12270 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12271 color
= surface_desc
.lpSurface
;
12272 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12273 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12274 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12276 /* Test a blit without keying. */
12277 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
12278 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12280 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12281 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12282 color
= surface_desc
.lpSurface
;
12283 /* Should have copied src data unmodified to dst. */
12284 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12285 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12286 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12287 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12289 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12290 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12291 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12294 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12295 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12297 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12298 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12299 color
= surface_desc
.lpSurface
;
12300 /* Src key applied to color[0]. It is unmodified, the others are copied. */
12301 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12302 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12303 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12304 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12306 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12307 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12308 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12310 /* Src override. */
12311 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
12312 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12314 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12315 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12316 color
= surface_desc
.lpSurface
;
12317 /* Override key applied to color[5]. It is unmodified, the others are copied. */
12318 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12319 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
12320 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12321 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12323 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12324 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12325 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12327 /* Src override AND src key. That is not supposed to work. */
12328 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
12329 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12331 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12332 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12333 color
= surface_desc
.lpSurface
;
12334 /* Ensure the destination was not changed. */
12335 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
12336 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
12337 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12338 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12340 /* Use different dst colors for the dst key test. */
12341 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12342 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12343 color
[2] = 0x00001100; /* Dest key in override. */
12344 color
[3] = 0x00001100; /* Dest key in override. */
12345 color
[4] = 0x000000aa; /* Dest key in src surface. */
12346 color
[5] = 0x000000aa; /* Dest key in src surface. */
12347 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12348 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12350 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12351 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12353 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12354 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12355 color
= surface_desc
.lpSurface
;
12356 /* Dst key applied to color[4,5], they are the only changed pixels. */
12357 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12358 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12359 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12360 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12362 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12363 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12364 color
[2] = 0x00001100; /* Dest key in override. */
12365 color
[3] = 0x00001100; /* Dest key in override. */
12366 color
[4] = 0x000000aa; /* Dest key in src surface. */
12367 color
[5] = 0x000000aa; /* Dest key in src surface. */
12368 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12369 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12371 /* What happens with a QI'd newer version of the interface? It takes the key
12372 * from the destination surface. */
12373 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
12374 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
12375 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
12376 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
12378 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
12379 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12381 IDirectDrawSurface7_Release(dst7
);
12382 IDirectDrawSurface7_Release(src7
);
12384 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12385 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12386 color
= surface_desc
.lpSurface
;
12387 /* Dst key applied to color[0,1], they are the only changed pixels. */
12388 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
12389 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12390 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12391 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12393 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12394 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12395 color
[2] = 0x00001100; /* Dest key in override. */
12396 color
[3] = 0x00001100; /* Dest key in override. */
12397 color
[4] = 0x000000aa; /* Dest key in src surface. */
12398 color
[5] = 0x000000aa; /* Dest key in src surface. */
12399 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12400 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12402 /* Dest override key blit. */
12403 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
12404 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12406 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12407 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12408 color
= surface_desc
.lpSurface
;
12409 /* Dst key applied to color[2,3], they are the only changed pixels. */
12410 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
12411 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12412 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12413 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12415 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12416 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12417 color
[2] = 0x00001100; /* Dest key in override. */
12418 color
[3] = 0x00001100; /* Dest key in override. */
12419 color
[4] = 0x000000aa; /* Dest key in src surface. */
12420 color
[5] = 0x000000aa; /* Dest key in src surface. */
12421 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12422 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12424 /* Dest override together with surface key. Supposed to fail. */
12425 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
12426 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12428 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12429 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12430 color
= surface_desc
.lpSurface
;
12431 /* Destination is unchanged. */
12432 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12433 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12434 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12435 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12436 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12437 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12439 /* Source and destination key. This is driver dependent. New HW treats it like
12440 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
12443 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
12444 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12446 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12447 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12448 color
= surface_desc
.lpSurface
;
12449 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
12450 * the driver applies it. */
12451 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12452 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12453 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12454 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12456 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12457 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12458 color
[2] = 0x00001100; /* Dest key in override. */
12459 color
[3] = 0x00001100; /* Dest key in override. */
12460 color
[4] = 0x000000aa; /* Dest key in src surface. */
12461 color
[5] = 0x000000aa; /* Dest key in src surface. */
12462 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12463 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12466 /* Override keys without ddbltfx parameter fail */
12467 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
12468 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12469 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
12470 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12472 /* Try blitting without keys in the source surface. */
12473 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
12474 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12475 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
12476 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12478 /* That fails now. Do not bother to check that the data is unmodified. */
12479 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12480 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12482 /* Surprisingly this still works. It uses the old key from the src surface. */
12483 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12484 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12486 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12487 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12488 color
= surface_desc
.lpSurface
;
12489 /* Dst key applied to color[4,5], they are the only changed pixels. */
12490 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12491 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12492 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12493 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12494 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12495 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12497 /* This returns DDERR_NOCOLORKEY as expected. */
12498 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12499 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
12501 /* GetSurfaceDesc returns a zeroed key as expected. */
12502 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
12503 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
12504 hr
= IDirectDrawSurface_GetSurfaceDesc(src
, &surface_desc
);
12505 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12506 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
12507 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
12508 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12509 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12511 /* Try blitting without keys in the destination surface. */
12512 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
12513 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12514 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
12515 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12517 /* This is weird. It makes sense in v4 and v7, but because v1
12518 * uses the key from the src surface it makes no sense here. */
12519 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12520 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12523 IDirectDrawSurface_Release(src
);
12524 IDirectDrawSurface_Release(dst
);
12525 refcount
= IDirectDraw_Release(ddraw
);
12526 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12527 DestroyWindow(window
);
12530 static void test_depth_readback(void)
12532 unsigned int depth
, expected_depth
, inst_length
, max_diff
, x
, y
;
12533 IDirect3DExecuteBuffer
*execute_buffer
;
12534 IDirect3DMaterial
*blue_background
;
12535 D3DEXECUTEBUFFERDESC exec_desc
;
12536 IDirectDrawSurface
*rt
, *ds
;
12537 IDirect3DViewport
*viewport
;
12538 DDSURFACEDESC surface_desc
;
12539 IDirect3DDevice
*device
;
12540 DWORD z_depth
, z_mask
;
12541 IDirectDraw
*ddraw
;
12547 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12548 static D3DLVERTEX quad
[] =
12550 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
12551 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
12552 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
12553 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
12556 window
= create_window();
12557 ok(!!window
, "Failed to create a window.\n");
12558 ddraw
= create_ddraw();
12559 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12560 if (ddraw_is_nvidia(ddraw
))
12562 /* ddraw1 only has access to D16 Z buffers (and D24 ones, which are even more
12563 * broken on Nvidia), so don't even attempt to run this test on Nvidia cards
12564 * because some of them have broken D16 readback. See the ddraw7 version of
12565 * this test for a more detailed comment. */
12566 skip("Some Nvidia GPUs have broken D16 readback, skipping.\n");
12567 IDirectDraw_Release(ddraw
);
12568 DestroyWindow(window
);
12572 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12574 skip("Failed to create a D3D device, skipping tests.\n");
12575 IDirectDraw_Release(ddraw
);
12576 DestroyWindow(window
);
12580 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
12581 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12582 z_depth
= get_device_z_depth(device
);
12583 z_mask
= 0xffffffff >> (32 - z_depth
);
12584 ds
= get_depth_stencil(device
);
12586 /* Changing depth buffers is hard in d3d1, so we only test with the
12587 * initial depth buffer here. */
12589 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12590 viewport
= create_viewport(device
, 0, 0, 640, 480);
12591 viewport_set_background(device
, viewport
, blue_background
);
12593 memset(&exec_desc
, 0, sizeof(exec_desc
));
12594 exec_desc
.dwSize
= sizeof(exec_desc
);
12595 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
12596 exec_desc
.dwBufferSize
= 1024;
12597 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
12598 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
12599 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
12601 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
12602 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
12604 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
12605 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(quad
);
12606 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
12607 emit_tquad(&ptr
, 0);
12610 inst_length
= ((BYTE
*)ptr
- sizeof(quad
)) - (BYTE
*)exec_desc
.lpData
;
12612 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
12613 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
12615 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
12616 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12617 hr
= IDirect3DDevice_BeginScene(device
);
12618 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12619 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
12620 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
12621 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12622 hr
= IDirect3DDevice_EndScene(device
);
12623 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12625 memset(&surface_desc
, 0, sizeof(surface_desc
));
12626 surface_desc
.dwSize
= sizeof(surface_desc
);
12627 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12628 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12630 for (y
= 60; y
< 480; y
+= 120)
12632 for (x
= 80; x
< 640; x
+= 160)
12634 ptr
= (BYTE
*)surface_desc
.lpSurface
12635 + y
* U1(surface_desc
).lPitch
12636 + x
* (z_depth
== 16 ? 2 : 4);
12637 depth
= *((DWORD
*)ptr
) & z_mask
;
12638 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * z_mask
;
12639 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * z_mask
;
12640 ok(compare_uint(expected_depth
, depth
, max_diff
),
12641 "z_depth %lu: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
12642 z_depth
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
12646 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
12647 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12649 IDirect3DExecuteBuffer_Release(execute_buffer
);
12650 destroy_viewport(device
, viewport
);
12651 destroy_material(blue_background
);
12652 IDirectDrawSurface_Release(ds
);
12653 IDirect3DDevice_Release(device
);
12654 refcount
= IDirectDrawSurface_Release(rt
);
12655 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12656 IDirectDraw_Release(ddraw
);
12657 DestroyWindow(window
);
12660 static void test_clear(void)
12662 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
12663 IDirect3DViewport
*viewport
, *viewport2
, *viewport3
;
12664 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
12665 IDirect3DDevice
*device
;
12666 IDirectDrawSurface
*rt
;
12667 unsigned int color
;
12668 IDirectDraw
*ddraw
;
12674 window
= create_window();
12675 ddraw
= create_ddraw();
12676 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12677 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12679 skip("Failed to create a 3D device, skipping test.\n");
12680 IDirectDraw_Release(ddraw
);
12681 DestroyWindow(window
);
12684 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
12685 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12687 viewport
= create_viewport(device
, 0, 0, 640, 480);
12689 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
12690 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
12691 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
12692 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12694 viewport_set_background(device
, viewport
, white
);
12695 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12696 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12698 /* Positive x, negative y. */
12699 U1(rect
[0]).x1
= 0;
12700 U2(rect
[0]).y1
= 480;
12701 U3(rect
[0]).x2
= 320;
12702 U4(rect
[0]).y2
= 240;
12704 /* Positive x, positive y. */
12705 U1(rect
[1]).x1
= 0;
12706 U2(rect
[1]).y1
= 0;
12707 U3(rect
[1]).x2
= 320;
12708 U4(rect
[1]).y2
= 240;
12710 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
12711 * refuse negative rectangles, but it will not clear them either. */
12712 viewport_set_background(device
, viewport
, red
);
12713 hr
= IDirect3DViewport_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
12714 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12716 color
= get_surface_color(rt
, 160, 360);
12717 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
12718 color
= get_surface_color(rt
, 160, 120);
12719 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
12720 color
= get_surface_color(rt
, 480, 360);
12721 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
12722 color
= get_surface_color(rt
, 480, 120);
12723 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
12725 viewport_set_background(device
, viewport
, white
);
12726 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12727 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12729 /* negative x, negative y.
12730 * Also ignored, except on WARP, which clears the entire screen. */
12731 U1(rect_negneg
).x1
= 640;
12732 U2(rect_negneg
).y1
= 240;
12733 U3(rect_negneg
).x2
= 320;
12734 U4(rect_negneg
).y2
= 0;
12735 viewport_set_background(device
, viewport
, green
);
12736 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
12737 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12739 color
= get_surface_color(rt
, 160, 360);
12740 ok(compare_color(color
, 0x00ffffff, 0)
12741 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12742 "Got unexpected color 0x%08x.\n", color
);
12743 color
= get_surface_color(rt
, 160, 120);
12744 ok(compare_color(color
, 0x00ffffff, 0)
12745 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12746 "Got unexpected color 0x%08x.\n", color
);
12747 color
= get_surface_color(rt
, 480, 360);
12748 ok(compare_color(color
, 0x00ffffff, 0)
12749 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12750 "Got unexpected color 0x%08x.\n", color
);
12751 color
= get_surface_color(rt
, 480, 120);
12752 ok(compare_color(color
, 0x00ffffff, 0)
12753 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12754 "Got unexpected color 0x%08x.\n", color
);
12756 /* Test how the viewport affects clears. */
12757 viewport_set_background(device
, viewport
, white
);
12758 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12759 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12761 viewport2
= create_viewport(device
, 160, 120, 160, 120);
12762 viewport_set_background(device
, viewport2
, blue
);
12763 hr
= IDirect3DViewport_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
12764 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12766 viewport3
= create_viewport(device
, 320, 240, 320, 240);
12767 viewport_set_background(device
, viewport3
, green
);
12769 U1(rect
[0]).x1
= 160;
12770 U2(rect
[0]).y1
= 120;
12771 U3(rect
[0]).x2
= 480;
12772 U4(rect
[0]).y2
= 360;
12773 hr
= IDirect3DViewport_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12774 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12776 /* AMD drivers do not limit the clear area to the viewport rectangle in
12777 * d3d1. It works as intended on other drivers and on d3d2 and newer on
12779 color
= get_surface_color(rt
, 158, 118);
12780 ok(compare_color(color
, 0x00ffffff, 0)
12781 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12782 "(158, 118) has color 0x%08x.\n", color
);
12783 color
= get_surface_color(rt
, 162, 118);
12784 ok(compare_color(color
, 0x00ffffff, 0)
12785 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12786 "(162, 118) has color 0x%08x.\n", color
);
12787 color
= get_surface_color(rt
, 158, 122);
12788 ok(compare_color(color
, 0x00ffffff, 0)
12789 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12790 "(158, 122) has color 0x%08x.\n", color
);
12791 color
= get_surface_color(rt
, 162, 122);
12792 ok(compare_color(color
, 0x000000ff, 0)
12793 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12794 "(162, 122) has color 0x%08x.\n", color
);
12796 color
= get_surface_color(rt
, 318, 238);
12797 ok(compare_color(color
, 0x000000ff, 0)
12798 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12799 "(318, 238) has color 0x%08x.\n", color
);
12800 color
= get_surface_color(rt
, 322, 238);
12801 ok(compare_color(color
, 0x00ffffff, 0)
12802 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12803 "(322, 328) has color 0x%08x.\n", color
);
12804 color
= get_surface_color(rt
, 318, 242);
12805 ok(compare_color(color
, 0x00ffffff, 0)
12806 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12807 "(318, 242) has color 0x%08x.\n", color
);
12808 color
= get_surface_color(rt
, 322, 242);
12809 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
12811 color
= get_surface_color(rt
, 478, 358);
12812 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
12813 color
= get_surface_color(rt
, 482, 358);
12814 ok(compare_color(color
, 0x00ffffff, 0)
12815 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12816 "(482, 358) has color 0x%08x.\n", color
);
12817 color
= get_surface_color(rt
, 478, 362);
12818 ok(compare_color(color
, 0x00ffffff, 0)
12819 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12820 "(478, 362) has color 0x%08x.\n", color
);
12821 color
= get_surface_color(rt
, 482, 362);
12822 ok(compare_color(color
, 0x00ffffff, 0)
12823 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12824 "(482, 362) has color 0x%08x.\n", color
);
12826 /* The clear rectangle is rendertarget absolute, not relative to the
12828 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12829 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12830 U1(rect
[0]).x1
= 330;
12831 U2(rect
[0]).y1
= 250;
12832 U3(rect
[0]).x2
= 340;
12833 U4(rect
[0]).y2
= 260;
12834 hr
= IDirect3DViewport_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12835 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12837 color
= get_surface_color(rt
, 328, 248);
12838 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
12839 color
= get_surface_color(rt
, 332, 248);
12840 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
12841 color
= get_surface_color(rt
, 328, 252);
12842 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
12843 color
= get_surface_color(rt
, 332, 252);
12844 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
12846 color
= get_surface_color(rt
, 338, 248);
12847 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
12848 color
= get_surface_color(rt
, 342, 248);
12849 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
12850 color
= get_surface_color(rt
, 338, 252);
12851 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
12852 color
= get_surface_color(rt
, 342, 252);
12853 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
12855 color
= get_surface_color(rt
, 328, 258);
12856 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
12857 color
= get_surface_color(rt
, 332, 258);
12858 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
12859 color
= get_surface_color(rt
, 328, 262);
12860 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
12861 color
= get_surface_color(rt
, 332, 262);
12862 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
12864 color
= get_surface_color(rt
, 338, 258);
12865 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
12866 color
= get_surface_color(rt
, 342, 258);
12867 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
12868 color
= get_surface_color(rt
, 338, 262);
12869 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
12870 color
= get_surface_color(rt
, 342, 262);
12871 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
12873 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
12876 IDirect3DViewport_Release(viewport3
);
12877 IDirect3DViewport_Release(viewport2
);
12878 IDirect3DViewport_Release(viewport
);
12879 IDirect3DMaterial_Release(white
);
12880 IDirect3DMaterial_Release(red
);
12881 IDirect3DMaterial_Release(green
);
12882 IDirect3DMaterial_Release(blue
);
12883 IDirectDrawSurface_Release(rt
);
12884 refcount
= IDirect3DDevice_Release(device
);
12885 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12886 refcount
= IDirectDraw_Release(ddraw
);
12887 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
12888 DestroyWindow(window
);
12891 struct enum_surfaces_param
12893 IDirectDraw
*ddraw
;
12894 DDSURFACEDESC modes
[20];
12895 unsigned int mode_count
;
12897 IDirectDrawSurface
*surfaces
[8];
12898 unsigned int count
;
12901 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC
*desc
, void *context
)
12903 struct enum_surfaces_param
*param
= context
;
12904 IDirectDrawSurface
*surface
;
12906 if (SUCCEEDED(IDirectDraw_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
12908 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
12909 param
->modes
[param
->mode_count
] = *desc
;
12910 ++param
->mode_count
;
12911 IDirectDrawSurface_Release(surface
);
12914 return DDENUMRET_OK
;
12917 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
12919 struct enum_surfaces_param
*param
= context
;
12920 BOOL found
= FALSE
;
12923 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
12925 if (param
->surfaces
[i
] == surface
)
12932 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
12933 IDirectDrawSurface_Release(surface
);
12936 return DDENUMRET_OK
;
12939 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
12941 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
12942 struct enum_surfaces_param
*param
= context
;
12944 ok(!surface
, "Unexpected surface %p.\n", surface
);
12945 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#lx.\n", desc
->dwFlags
);
12946 if (param
->count
< ARRAY_SIZE(param
->modes
))
12948 const DDSURFACEDESC
*expect
= ¶m
->modes
[param
->count
];
12949 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %lu, got %lu.\n", expect
->dwWidth
, desc
->dwWidth
);
12950 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %lu, got %lu.\n", expect
->dwHeight
, desc
->dwHeight
);
12951 ok(!memcmp(&U4(*desc
).ddpfPixelFormat
, &U4(*expect
).ddpfPixelFormat
, sizeof(U4(*desc
).ddpfPixelFormat
)),
12952 "Pixel formats didn't match.\n");
12957 return DDENUMRET_OK
;
12960 static void test_enum_surfaces(void)
12962 struct enum_surfaces_param param
= {0};
12963 DDPIXELFORMAT current_format
;
12964 IDirectDraw
*ddraw
;
12965 DDSURFACEDESC desc
;
12968 ddraw
= create_ddraw();
12969 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12970 param
.ddraw
= ddraw
;
12972 memset(&desc
, 0, sizeof(desc
));
12973 desc
.dwSize
= sizeof(desc
);
12974 hr
= IDirectDraw_GetDisplayMode(ddraw
, &desc
);
12975 ok(hr
== DD_OK
, "Failed to get display mode, hr %#lx.\n", hr
);
12976 current_format
= desc
.ddpfPixelFormat
;
12978 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
12979 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#lx.\n", hr
);
12981 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
12982 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12984 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
12985 NULL
, NULL
, enum_surfaces_cb
);
12986 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12988 memset(&desc
, 0, sizeof(desc
));
12989 desc
.dwSize
= sizeof(desc
);
12990 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
12991 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
12992 U2(desc
).dwMipMapCount
= 3;
12994 desc
.dwHeight
= 32;
12995 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
12996 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12998 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
12999 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
13000 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
13001 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
13002 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
13003 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13004 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
13007 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13008 &desc
, ¶m
, enum_surfaces_cb
);
13009 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13010 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13013 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13014 NULL
, ¶m
, enum_surfaces_cb
);
13015 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13016 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13018 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
13020 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13021 &desc
, ¶m
, enum_surfaces_cb
);
13022 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13023 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13026 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
13027 &desc
, ¶m
, enum_surfaces_cb
);
13028 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13029 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13033 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13034 &desc
, ¶m
, enum_surfaces_cb
);
13035 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13036 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13040 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
13041 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13042 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13044 IDirectDrawSurface_Release(param
.surfaces
[2]);
13045 IDirectDrawSurface_Release(param
.surfaces
[1]);
13046 IDirectDrawSurface_Release(param
.surfaces
[0]);
13049 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13050 NULL
, ¶m
, enum_surfaces_cb
);
13051 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13052 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13054 memset(&desc
, 0, sizeof(desc
));
13055 desc
.dwSize
= sizeof(desc
);
13056 desc
.dwFlags
= DDSD_CAPS
;
13057 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13059 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
13060 &desc
, ¶m
, enum_surfaces_create_cb
);
13061 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13063 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
13064 &desc
, ¶m
, enum_surfaces_create_cb
);
13065 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13067 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
13068 &desc
, ¶m
, enum_surfaces_create_cb
);
13069 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13071 /* When not passed width and height, the callback is called with every
13072 * available display resolution. */
13074 param
.mode_count
= 0;
13075 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13076 U4(desc
).ddpfPixelFormat
= current_format
;
13077 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
13078 ok(hr
== DD_OK
, "Failed to build mode list, hr %#lx.\n", hr
);
13081 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
13082 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13083 &desc
, ¶m
, enum_surfaces_create_cb
);
13084 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13085 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
13087 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
13088 desc
.dwWidth
= desc
.dwHeight
= 32;
13090 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
13093 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13094 &desc
, ¶m
, enum_surfaces_create_cb
);
13095 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13096 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13098 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
13099 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
13101 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13102 &desc
, ¶m
, enum_surfaces_create_cb
);
13103 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13104 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13105 IDirectDrawSurface_Release(param
.surfaces
[0]);
13107 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13108 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
13109 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
13110 desc
.ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
13113 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13114 &desc
, ¶m
, enum_surfaces_create_cb
);
13115 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13116 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13118 IDirectDraw_Release(ddraw
);
13121 static void test_execute_data(void)
13123 IDirect3DExecuteBuffer
*execute_buffer
;
13124 D3DEXECUTEBUFFERDESC exec_desc
;
13125 IDirect3DDevice
*device
;
13126 IDirectDraw
*ddraw
;
13129 D3DEXECUTEDATA exec_data
;
13131 window
= create_window();
13132 ddraw
= create_ddraw();
13133 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13134 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13136 skip("Failed to create a 3D device, skipping test.\n");
13137 IDirectDraw_Release(ddraw
);
13138 DestroyWindow(window
);
13142 memset(&exec_desc
, 0, sizeof(exec_desc
));
13143 exec_desc
.dwSize
= sizeof(exec_desc
);
13144 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13145 exec_desc
.dwBufferSize
= 1024;
13146 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13148 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13149 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
13151 memset(&exec_data
, 0, sizeof(exec_data
));
13153 /* Success case. */
13154 exec_data
.dwSize
= sizeof(exec_data
);
13155 exec_data
.dwVertexCount
= 3;
13156 exec_data
.dwInstructionOffset
= 3 * sizeof(D3DVERTEX
);
13157 exec_data
.dwInstructionLength
= 10;
13158 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13159 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13161 /* dwSize is checked against the expected struct size. */
13162 exec_data
.dwSize
= sizeof(exec_data
) - 1;
13163 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13164 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13165 exec_data
.dwSize
= sizeof(exec_data
) + 1;
13166 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13167 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13169 /* The rest of the data is not checked for plausibility. */
13170 exec_data
.dwSize
= sizeof(exec_data
);
13171 exec_data
.dwVertexCount
= 0;
13172 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13173 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13174 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
) - 1;
13175 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13176 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13177 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
);
13178 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13179 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13180 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
) + 1;
13181 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13182 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13183 exec_data
.dwVertexCount
= 999999;
13184 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13185 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13186 exec_data
.dwInstructionOffset
= 999999 * sizeof(D3DVERTEX
);
13187 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13188 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13189 exec_data
.dwInstructionLength
= 10240;
13190 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13191 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13193 /* The input structure is not modified. */
13194 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13196 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13197 exec_data
.dwVertexCount
);
13198 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13199 exec_data
.dwInstructionOffset
);
13200 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13201 exec_data
.dwInstructionLength
);
13203 /* No validation in GetExecuteData. */
13204 memset(&exec_data
, 0, sizeof(exec_data
));
13205 exec_desc
.dwSize
= sizeof(exec_desc
);
13206 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13207 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13209 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13211 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13212 exec_data
.dwVertexCount
);
13213 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13214 exec_data
.dwInstructionOffset
);
13215 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13216 exec_data
.dwInstructionLength
);
13218 memset(&exec_data
, 0xaa, sizeof(exec_data
));
13219 exec_desc
.dwSize
= sizeof(exec_desc
) - 1;
13220 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13221 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13222 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13224 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13225 exec_data
.dwVertexCount
);
13226 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13227 exec_data
.dwInstructionOffset
);
13228 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13229 exec_data
.dwInstructionLength
);
13231 exec_desc
.dwSize
= 0;
13232 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13233 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13234 exec_desc
.dwSize
= sizeof(exec_desc
) + 1;
13235 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13236 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13237 exec_desc
.dwSize
= ~0U;
13238 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13239 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13241 IDirect3DExecuteBuffer_Release(execute_buffer
);
13242 IDirect3DDevice_Release(device
);
13243 IDirectDraw_Release(ddraw
);
13244 DestroyWindow(window
);
13247 static void test_viewport(void)
13252 RECT expected_rect
;
13253 const char *message
;
13257 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "(0, 0) - (640, 480) viewport"},
13258 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "(0, 0) - (320, 240) viewport"},
13259 {{ 0, 0, 1280, 960}, {-10, -10, -1, -1}, "(0, 0) - (1280, 960) viewport"},
13260 {{ 0, 0, 2000, 1600}, {-10, -10, -1, -1}, "(0, 0) - (2000, 1600) viewport"},
13261 {{100, 100, 640, 480}, {-10, -10, -1, -1}, "(100, 100) - (640, 480) viewport"},
13262 {{ 0, 0, 8192, 8192}, {-10, -10, -1, -1}, "(0, 0) - (8192, 8192) viewport"},
13264 static D3DMATRIX mat
=
13266 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13267 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13268 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13269 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13271 static D3DLVERTEX quad
[] =
13273 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
13274 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13275 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
13276 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13278 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
13279 IDirect3DViewport
*viewport
, *full_viewport
;
13280 IDirect3DExecuteBuffer
*execute_buffer
;
13281 IDirect3DMaterial
*black_background
;
13282 D3DEXECUTEBUFFERDESC exec_desc
;
13283 IDirect3DDevice
*device
;
13284 IDirectDrawSurface
*rt
;
13285 IDirectDraw
*ddraw
;
13286 D3DRECT clear_rect
;
13296 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13297 0, 0, 640, 480, 0, 0, 0, 0);
13298 ddraw
= create_ddraw();
13299 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13300 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13302 skip("Failed to create a 3D device, skipping test.\n");
13303 IDirectDraw_Release(ddraw
);
13304 DestroyWindow(window
);
13308 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
13309 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13311 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
13312 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
13314 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
13316 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
13317 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13318 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
13319 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13320 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
13321 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13322 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
13323 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13324 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
13325 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13326 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
13327 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13329 memset(&exec_desc
, 0, sizeof(exec_desc
));
13330 exec_desc
.dwSize
= sizeof(exec_desc
);
13331 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13332 exec_desc
.dwBufferSize
= 1024;
13333 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13335 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13336 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
13338 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13339 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
13341 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13342 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13343 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
13344 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
13345 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
13346 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13347 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13348 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13349 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
13350 emit_tquad(&ptr
, 0);
13352 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13353 inst_length
-= sizeof(quad
);
13355 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13356 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
13358 full_viewport
= create_viewport(device
, 0, 0, 640, 480);
13359 viewport_set_background(device
, full_viewport
, black_background
);
13361 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
13362 U3(clear_rect
).x2
= 640;
13363 U4(clear_rect
).y2
= 480;
13365 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
13367 winetest_push_context("%s", tests
[j
].message
);
13369 hr
= IDirect3DViewport_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
13370 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13372 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
13373 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13374 memset(&vp
, 0, sizeof(vp
));
13375 vp
.dwSize
= sizeof(vp
);
13376 vp
.dwX
= tests
[j
].vp
.dwX
;
13377 vp
.dwY
= tests
[j
].vp
.dwY
;
13378 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
13379 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
13380 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
13381 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
13386 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
13387 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
13388 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
13389 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13390 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
13391 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13393 hr
= IDirect3DDevice_BeginScene(device
);
13394 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13396 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
13397 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13398 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13400 hr
= IDirect3DDevice_EndScene(device
);
13401 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13403 check_rect(rt
, tests
[j
].expected_rect
);
13405 destroy_viewport(device
, viewport
);
13407 winetest_pop_context();
13410 destroy_viewport(device
, full_viewport
);
13411 IDirectDrawSurface_Release(rt
);
13413 IDirect3DExecuteBuffer_Release(execute_buffer
);
13414 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
13415 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
13416 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
13417 destroy_material(black_background
);
13418 refcount
= IDirect3DDevice_Release(device
);
13419 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13420 IDirect3D2_Release(d3d
);
13421 IDirectDraw_Release(ddraw
);
13422 DestroyWindow(window
);
13425 static void test_find_device(void)
13427 D3DFINDDEVICESEARCH search
= {0};
13428 D3DFINDDEVICERESULT result
= {0};
13429 IDirect3DDevice
*device
;
13430 IDirectDraw
*ddraw
;
13440 D3DDEVICEDESC_V1 hw_desc
;
13441 D3DDEVICEDESC_V1 sw_desc
;
13448 D3DDEVICEDESC_V2 hw_desc
;
13449 D3DDEVICEDESC_V2 sw_desc
;
13452 static const struct
13459 {&IID_IDirect3D
, DDERR_NOTFOUND
},
13460 {&IID_IDirect3DRampDevice
, D3D_OK
},
13461 {&IID_IDirect3DRGBDevice
, D3D_OK
},
13462 {&IID_IDirect3DMMXDevice
, DDERR_NOTFOUND
},
13463 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
13464 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
13465 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
13468 ddraw
= create_ddraw();
13469 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13471 if (FAILED(IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
)))
13473 skip("D3D interface is not available, skipping test.\n");
13474 IDirectDraw_Release(ddraw
);
13478 result
.dwSize
= sizeof(result
);
13479 search
.dwSize
= sizeof(search
);
13480 hr
= IDirect3D_FindDevice(d3d
, NULL
, NULL
);
13481 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13482 hr
= IDirect3D_FindDevice(d3d
, NULL
, &result
);
13483 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13484 hr
= IDirect3D_FindDevice(d3d
, &search
, NULL
);
13485 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13486 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13487 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13488 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %lu.\n", result
.dwSize
);
13489 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v1
.hw_desc
),
13490 "Got unexpected HW desc size %lu.\n", result
.ddHwDesc
.dwSize
);
13491 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v1
.sw_desc
),
13492 "Got unexpected SW desc size %lu.\n", result
.ddSwDesc
.dwSize
);
13494 memset(&search
, 0, sizeof(search
));
13495 memset(&result
, 0, sizeof(result
));
13496 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13497 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13499 search
.dwSize
= sizeof(search
) + 1;
13500 result
.dwSize
= sizeof(result
) + 1;
13501 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13502 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13504 search
.dwSize
= sizeof(search
);
13506 memset(&result_v1
, 0, sizeof(result_v1
));
13507 result_v1
.size
= sizeof(result_v1
);
13508 hr
= IDirect3D_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
13509 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13510 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v1
.hw_desc
),
13511 "Got unexpected HW desc size %lu.\n", result_v1
.hw_desc
.dwSize
);
13512 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v1
.sw_desc
),
13513 "Got unexpected SW desc size %lu.\n", result_v1
.sw_desc
.dwSize
);
13515 memset(&result_v2
, 0, sizeof(result_v2
));
13516 result_v2
.size
= sizeof(result_v2
);
13517 hr
= IDirect3D_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
13518 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13519 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v1
.hw_desc
),
13520 "Got unexpected HW desc size %lu.\n", result_v2
.hw_desc
.dwSize
);
13521 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v1
.sw_desc
),
13522 "Got unexpected SW desc size %lu.\n", result_v2
.sw_desc
.dwSize
);
13524 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13526 memset(&search
, 0, sizeof(search
));
13527 search
.dwSize
= sizeof(search
);
13528 search
.dwFlags
= D3DFDS_GUID
;
13529 search
.guid
= *tests
[i
].guid
;
13531 memset(&result
, 0, sizeof(result
));
13532 result
.dwSize
= sizeof(result
);
13534 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13535 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13536 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %lu.\n", i
, result
.dwSize
);
13539 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v1
.hw_desc
),
13540 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
13541 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v1
.sw_desc
),
13542 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
13546 ok(!result
.ddHwDesc
.dwSize
,
13547 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
13548 ok(!result
.ddSwDesc
.dwSize
,
13549 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
13553 /* The HAL device can only be enumerated if hardware acceleration is present. */
13554 search
.dwSize
= sizeof(search
);
13555 search
.dwFlags
= D3DFDS_GUID
;
13556 search
.guid
= IID_IDirect3DHALDevice
;
13557 result
.dwSize
= sizeof(result
);
13558 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13560 window
= create_window();
13561 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
13563 ok(!!device
, "Failed to create a 3D device.\n");
13565 ok(!device
, "Succeeded to create a 3D device.\n");
13567 IDirect3DDevice_Release(device
);
13568 DestroyWindow(window
);
13570 /* Curiously the colour model criteria seem to be ignored. */
13571 search
.dwSize
= sizeof(search
);
13572 search
.dwFlags
= D3DFDS_COLORMODEL
;
13573 search
.dcmColorModel
= 0xdeadbeef;
13574 result
.dwSize
= sizeof(result
);
13575 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13576 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13578 IDirect3D_Release(d3d
);
13579 IDirectDraw_Release(ddraw
);
13582 static IDirectDraw
*killfocus_ddraw
;
13583 static IDirectDrawSurface
*killfocus_surface
;
13585 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
13589 if (message
== WM_KILLFOCUS
)
13591 ref
= IDirectDrawSurface_Release(killfocus_surface
);
13592 ok(!ref
, "Unexpected surface refcount %lu.\n", ref
);
13593 ref
= IDirectDraw_Release(killfocus_ddraw
);
13594 ok(!ref
, "Unexpected ddraw refcount %lu.\n", ref
);
13595 killfocus_ddraw
= NULL
;
13598 return DefWindowProcA(window
, message
, wparam
, lparam
);
13601 static void test_killfocus(void)
13603 DDSURFACEDESC surface_desc
;
13606 WNDCLASSA wc
= {0};
13608 wc
.lpfnWndProc
= killfocus_proc
;
13609 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
13610 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
13612 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
13613 0, 0, 640, 480, 0, 0, 0, 0);
13615 killfocus_ddraw
= create_ddraw();
13616 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
13618 hr
= IDirectDraw_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
13619 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13621 memset(&surface_desc
, 0, sizeof(surface_desc
));
13622 surface_desc
.dwSize
= sizeof(surface_desc
);
13623 surface_desc
.dwFlags
= DDSD_CAPS
;
13624 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13625 hr
= IDirectDraw_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
13626 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13628 SetForegroundWindow(GetDesktopWindow());
13629 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
13631 DestroyWindow(window
);
13632 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
13635 static void test_gdi_surface(void)
13637 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
13638 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
13639 DDSURFACEDESC surface_desc
;
13640 IDirectDraw
*ddraw
;
13645 window
= create_window();
13646 ddraw
= create_ddraw();
13647 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13648 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13649 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13651 /* Retrieving the GDI surface requires a primary surface to exist. */
13652 gdi_surface
= (void *)0xc0dec0de;
13653 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13654 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13655 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
13657 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13658 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13660 memset(&surface_desc
, 0, sizeof(surface_desc
));
13661 surface_desc
.dwSize
= sizeof(surface_desc
);
13662 surface_desc
.dwFlags
= DDSD_CAPS
;
13663 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13664 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13665 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13667 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13668 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13669 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13670 IDirectDrawSurface_Release(gdi_surface
);
13672 /* Flipping to the GDI surface requires the primary surface to be
13674 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13675 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#lx.\n", hr
);
13677 IDirectDrawSurface_Release(primary
);
13679 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13680 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13682 memset(&surface_desc
, 0, sizeof(surface_desc
));
13683 surface_desc
.dwSize
= sizeof(surface_desc
);
13684 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13685 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
13686 U5(surface_desc
).dwBackBufferCount
= 1;
13687 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13688 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13689 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
13690 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13691 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
13693 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13694 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13695 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13696 IDirectDrawSurface_Release(gdi_surface
);
13698 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
13699 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13700 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13701 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13702 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
13703 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
13704 IDirectDrawSurface_Release(gdi_surface
);
13706 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13707 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13709 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13710 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13711 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13712 IDirectDrawSurface_Release(gdi_surface
);
13714 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13715 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13717 IDirectDrawSurface_Release(backbuffer
);
13718 IDirectDrawSurface_Release(primary
);
13720 refcount
= IDirectDraw_Release(ddraw
);
13721 ok(!refcount
, "%lu references left.\n", refcount
);
13722 DestroyWindow(window
);
13725 static void test_alphatest(void)
13727 #define ALPHATEST_PASSED 0x0000ff00
13728 #define ALPHATEST_FAILED 0x00ff0000
13729 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
13730 IDirect3DExecuteBuffer
*execute_buffer
;
13731 IDirect3DMaterial
*blue
, *failed
;
13732 D3DEXECUTEBUFFERDESC exec_desc
;
13733 IDirect3DViewport
*viewport
;
13734 IDirect3DDevice
*device
;
13735 IDirectDrawSurface
*rt
;
13736 unsigned int color
, i
;
13737 IDirectDraw
*ddraw
;
13744 static const struct
13747 unsigned int color_less
, color_equal
, color_greater
;
13751 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13752 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13753 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13754 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13755 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13756 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13757 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13758 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13760 static D3DLVERTEX quad
[] =
13762 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13763 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13764 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13765 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13768 window
= create_window();
13769 ddraw
= create_ddraw();
13770 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13771 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13773 skip("Failed to create a 3D device.\n");
13774 IDirectDraw_Release(ddraw
);
13775 DestroyWindow(window
);
13778 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
13779 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13781 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13782 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13784 viewport
= create_viewport(device
, 0, 0, 640, 480);
13786 viewport_set_background(device
, viewport
, blue
);
13787 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13788 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13790 memset(&exec_desc
, 0, sizeof(exec_desc
));
13791 exec_desc
.dwSize
= sizeof(exec_desc
);
13792 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13793 exec_desc
.dwBufferSize
= 1024;
13794 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13796 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13797 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13799 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13800 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13802 ptr
= exec_desc
.lpData
;
13803 emit_set_rs(&ptr
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13804 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13805 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
13807 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13809 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13810 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13812 set_execute_data(execute_buffer
, 0, 0, inst_length
);
13813 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13814 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13816 viewport_set_background(device
, viewport
, failed
);
13817 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13819 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13820 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13822 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13823 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13824 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
13825 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAREF
, 0x70);
13826 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, ARRAY_SIZE(quad
));
13827 emit_tquad(&ptr
, 0);
13829 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13830 inst_length
-= sizeof(quad
);
13832 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13833 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13835 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13836 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13837 hr
= IDirect3DDevice_BeginScene(device
);
13838 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13839 set_execute_data(execute_buffer
, ARRAY_SIZE(quad
), sizeof(quad
), inst_length
);
13840 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13841 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13842 hr
= IDirect3DDevice_EndScene(device
);
13843 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13844 color
= get_surface_color(rt
, 320, 240);
13845 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13846 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13847 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13849 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13850 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13852 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13853 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13854 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
13855 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, ARRAY_SIZE(quad
));
13856 emit_tquad(&ptr
, 0);
13858 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13859 inst_length
-= sizeof(quad
);
13861 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13862 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13864 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13865 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13866 hr
= IDirect3DDevice_BeginScene(device
);
13867 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13868 set_execute_data(execute_buffer
, ARRAY_SIZE(quad
), sizeof(quad
), inst_length
);
13869 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13870 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13871 hr
= IDirect3DDevice_EndScene(device
);
13872 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13873 color
= get_surface_color(rt
, 320, 240);
13874 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13875 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13876 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13879 IDirect3DExecuteBuffer_Release(execute_buffer
);
13880 destroy_viewport(device
, viewport
);
13881 destroy_material(failed
);
13882 destroy_material(blue
);
13883 IDirectDrawSurface_Release(rt
);
13884 refcount
= IDirect3DDevice_Release(device
);
13885 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13886 refcount
= IDirectDraw_Release(ddraw
);
13887 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
13888 DestroyWindow(window
);
13891 static void test_clipper_refcount(void)
13893 IDirectDrawSurface
*surface
;
13894 IDirectDrawClipper
*clipper
, *clipper2
;
13895 DDSURFACEDESC surface_desc
;
13896 IDirectDraw
*ddraw
;
13901 const IDirectDrawClipperVtbl
*orig_vtbl
;
13903 window
= create_window();
13904 ddraw
= create_ddraw();
13905 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13906 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13907 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13909 memset(&surface_desc
, 0, sizeof(surface_desc
));
13910 surface_desc
.dwSize
= sizeof(surface_desc
);
13911 surface_desc
.dwFlags
= DDSD_CAPS
;
13912 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13913 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13914 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13916 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
13917 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
13918 refcount
= get_refcount((IUnknown
*)clipper
);
13919 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
13921 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
13923 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
13924 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
13925 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
13926 clipper
->lpVtbl
, clipper2
->lpVtbl
);
13927 orig_vtbl
= clipper
->lpVtbl
;
13928 IDirectDrawClipper_Release(clipper2
);
13930 /* Surfaces hold a reference to clippers. No surprises there. */
13931 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13932 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
13933 refcount
= get_refcount((IUnknown
*)clipper
);
13934 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
13936 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
13937 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
13938 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
13939 refcount
= IDirectDrawClipper_Release(clipper2
);
13940 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
13942 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
13943 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
13944 refcount
= get_refcount((IUnknown
*)clipper
);
13945 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
13947 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13948 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
13949 refcount
= get_refcount((IUnknown
*)clipper
);
13950 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
13952 refcount
= IDirectDrawSurface_Release(surface
);
13953 ok(!refcount
, "%lu references left.\n", refcount
);
13954 refcount
= get_refcount((IUnknown
*)clipper
);
13955 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
13957 /* SetClipper with an invalid pointer crashes. */
13959 /* Clipper methods work with a broken vtable, with the exception of Release. */
13960 clipper
->lpVtbl
= (void *)0xdeadbeef;
13961 refcount
= orig_vtbl
->AddRef(clipper
);
13962 todo_wine
ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
13963 refcount
= orig_vtbl
->Release(clipper
);
13964 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
13966 clipper
->lpVtbl
= orig_vtbl
;
13967 refcount
= orig_vtbl
->Release(clipper
);
13968 todo_wine
ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
13970 /* Fix the refcount difference because Wine did not increase the ref in the
13971 * AddRef call above. */
13974 refcount
= IDirectDrawClipper_Release(clipper
);
13975 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
13978 /* Steal the reference and see what happens - releasing the surface works fine.
13979 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
13980 * release it after the GetClipper call is likely to crash, and certain to crash
13981 * if we allocate and zero as much heap memory as we can get. */
13982 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13983 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13984 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
13985 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
13986 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
13987 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
13989 IDirectDrawClipper_Release(clipper
);
13990 IDirectDrawClipper_Release(clipper
);
13994 /* Disabled because it causes heap corruption (HeapValidate fails and random
13995 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
13996 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
13997 * is affected too. Some testbot machines have crashes directly in GetClipper
13998 * or proceed with a corrupted heap too.
14000 * The same Windows and driver versions run the test without heap corruption on
14001 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
14002 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14003 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
14004 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14007 /* Show that invoking the Release method does not crash, but don't get the
14008 * vtable through the clipper pointer because it is no longer pointing to
14010 refcount
= orig_vtbl
->Release(clipper
);
14011 ok(!refcount
, "%lu references left.\n", refcount
);
14013 refcount
= IDirectDrawSurface_Release(surface
);
14014 ok(!refcount
, "%lu references left.\n", refcount
);
14016 /* It looks like the protection against invalid thispointers is part of
14017 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
14018 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
14019 ok(!!clipper
, "failed to allocate memory\n");
14021 /* Assigning the vtable to our fake clipper does NOT make a difference on
14022 * native - there is a different member of the clipper implementation struct
14023 * that is used to determine if a clipper is valid. */
14024 clipper
->lpVtbl
= orig_vtbl
;
14026 refcount
= orig_vtbl
->AddRef(clipper
);
14027 todo_wine
ok(!refcount
, "Got refcount %lu.\n", refcount
);
14028 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
14029 ok(!refcount
, "Got refcount %lu.\n", refcount
);
14032 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
14033 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14034 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14037 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
14038 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14039 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14041 /* Nope, we can't initialize our fake clipper. */
14042 hr
= orig_vtbl
->Initialize(clipper
, ddraw
, 0);
14043 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14045 HeapFree(GetProcessHeap(), 0, clipper
);
14047 refcount
= IDirectDraw_Release(ddraw
);
14048 ok(!refcount
, "%lu references left.\n", refcount
);
14049 DestroyWindow(window
);
14052 static void test_caps(void)
14054 DWORD caps_never
, caps_always
, caps_hal
;
14055 DDCAPS hal_caps
, hel_caps
;
14056 IDirectDraw
*ddraw
;
14060 caps_never
= DDSCAPS_RESERVED1
14062 | DDSCAPS_PRIMARYSURFACELEFT
14063 | DDSCAPS_SYSTEMMEMORY
14065 | DDSCAPS_WRITEONLY
14066 | DDSCAPS_LIVEVIDEO
14069 | DDSCAPS_RESERVED2
14072 | DDSCAPS_ALLOCONLOAD
14073 | DDSCAPS_VIDEOPORT
14074 | DDSCAPS_STANDARDVGAMODE
14075 | DDSCAPS_OPTIMIZED
;
14077 caps_always
= DDSCAPS_FLIP
14078 | DDSCAPS_OFFSCREENPLAIN
14079 | DDSCAPS_PRIMARYSURFACE
14084 caps_hal
= DDSCAPS_BACKBUFFER
14086 | DDSCAPS_FRONTBUFFER
14088 | DDSCAPS_VIDEOMEMORY
14089 | DDSCAPS_LOCALVIDMEM
14090 | DDSCAPS_NONLOCALVIDMEM
;
14092 ddraw
= create_ddraw();
14093 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14095 memset(&hal_caps
, 0, sizeof(hal_caps
));
14096 memset(&hel_caps
, 0, sizeof(hel_caps
));
14097 hal_caps
.dwSize
= sizeof(hal_caps
);
14098 hel_caps
.dwSize
= sizeof(hel_caps
);
14099 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14100 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14101 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14102 "Got unexpected caps %#lx, expected %#lx.\n",
14103 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14104 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14105 "Got unexpected caps %#lx, expected %#lx.\n",
14106 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14108 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
14109 if (hal_caps
.ddsCaps
.dwCaps
)
14111 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14112 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14113 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14114 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14116 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14117 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14118 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14119 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14121 IDirectDraw_Release(ddraw
);
14123 if (hal_caps
.ddsCaps
.dwCaps
)
14125 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw
, NULL
);
14126 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14128 memset(&hal_caps
, 0, sizeof(hal_caps
));
14129 memset(&hel_caps
, 0, sizeof(hel_caps
));
14130 hal_caps
.dwSize
= sizeof(hal_caps
);
14131 hel_caps
.dwSize
= sizeof(hel_caps
);
14132 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14133 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14134 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14135 "Got unexpected caps %#lx, expected %#lx.\n",
14136 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14137 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14138 "Got unexpected caps %#lx, expected %#lx.\n",
14139 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14141 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14142 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14143 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14144 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14147 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14148 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14149 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14150 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14154 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14157 IDirectDraw_Release(ddraw
);
14160 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw
, NULL
);
14161 ok(hr
== DD_OK
|| (is_ddraw64
&& hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
14164 memset(&hal_caps
, 0, sizeof(hal_caps
));
14165 memset(&hel_caps
, 0, sizeof(hel_caps
));
14166 hal_caps
.dwSize
= sizeof(hal_caps
);
14167 hel_caps
.dwSize
= sizeof(hel_caps
);
14168 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14169 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14170 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14171 "Got unexpected caps %#lx, expected %#lx.\n",
14172 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14173 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14174 "Got unexpected caps %#lx, expected %#lx.\n",
14175 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14177 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14178 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14179 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14180 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14181 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14183 IDirectDraw_Release(ddraw
);
14187 static void test_d32_support(void)
14189 IDirectDrawSurface
*surface
;
14190 DDSURFACEDESC surface_desc
;
14191 IDirectDraw
*ddraw
;
14196 window
= create_window();
14197 ddraw
= create_ddraw();
14198 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14199 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14200 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14202 memset(&surface_desc
, 0, sizeof(surface_desc
));
14203 surface_desc
.dwSize
= sizeof(surface_desc
);
14204 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
14205 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14206 U2(surface_desc
).dwZBufferBitDepth
= 32;
14207 surface_desc
.dwWidth
= 64;
14208 surface_desc
.dwHeight
= 64;
14209 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14210 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14212 memset(&surface_desc
, 0, sizeof(surface_desc
));
14213 surface_desc
.dwSize
= sizeof(surface_desc
);
14214 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
14215 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14216 ok((surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "Got unexpected flags %#lx.\n", surface_desc
.dwFlags
);
14217 ok(U2(surface_desc
).dwZBufferBitDepth
== 32,
14218 "Got unexpected dwZBufferBitDepth %lu.\n", U2(surface_desc
).dwZBufferBitDepth
);
14219 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
14220 "Got unexpected surface caps %#lx.\n", surface_desc
.ddsCaps
.dwCaps
);
14221 IDirectDrawSurface_Release(surface
);
14223 refcount
= IDirectDraw_Release(ddraw
);
14224 ok(!refcount
, "%lu references left.\n", refcount
);
14225 DestroyWindow(window
);
14228 struct find_different_mode_param
14230 unsigned int old_width
;
14231 unsigned int old_height
;
14232 unsigned int new_width
;
14233 unsigned int new_height
;
14236 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC
*surface_desc
, void *context
)
14238 struct find_different_mode_param
*param
= context
;
14240 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
14241 return DDENUMRET_OK
;
14243 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
)
14245 /* See test_coop_level_mode_set_enum_cb() for why enumeration might accidentally continue. */
14246 if (!param
->new_width
|| (param
->new_width
< registry_mode
.dmPelsWidth
14247 && param
->new_height
< registry_mode
.dmPelsHeight
))
14249 param
->new_width
= surface_desc
->dwWidth
;
14250 param
->new_height
= surface_desc
->dwHeight
;
14252 return DDENUMRET_CANCEL
;
14255 return DDENUMRET_OK
;
14258 static void test_cursor_clipping(void)
14260 struct find_different_mode_param param
;
14261 DDSURFACEDESC surface_desc
;
14262 RECT rect
, clip_rect
;
14263 IDirectDraw
*ddraw
;
14268 window
= create_window();
14269 ok(!!window
, "Failed to create a window.\n");
14270 ddraw
= create_ddraw();
14271 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14273 memset(&surface_desc
, 0, sizeof(surface_desc
));
14274 surface_desc
.dwSize
= sizeof(surface_desc
);
14275 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14276 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14278 memset(¶m
, 0, sizeof(param
));
14279 param
.old_width
= surface_desc
.dwWidth
;
14280 param
.old_height
= surface_desc
.dwHeight
;
14281 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
14282 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
14283 if (!(param
.new_width
&& param
.new_height
))
14285 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
14289 ret
= ClipCursor(NULL
);
14290 ok(ret
, "ClipCursor failed, error %lu.\n", GetLastError());
14291 get_virtual_rect(&rect
);
14292 ret
= GetClipCursor(&clip_rect
);
14293 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14294 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14295 wine_dbgstr_rect(&clip_rect
));
14297 /* Set cooperative level to normal */
14298 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14299 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14301 get_virtual_rect(&rect
);
14302 ret
= GetClipCursor(&clip_rect
);
14303 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14304 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14305 wine_dbgstr_rect(&clip_rect
));
14307 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
14308 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
14311 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
14315 get_virtual_rect(&rect
);
14316 ret
= GetClipCursor(&clip_rect
);
14317 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14318 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14319 wine_dbgstr_rect(&clip_rect
));
14321 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
14322 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
14324 get_virtual_rect(&rect
);
14325 ret
= GetClipCursor(&clip_rect
);
14326 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14327 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14328 wine_dbgstr_rect(&clip_rect
));
14330 /* Switch to full screen cooperative level */
14331 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14332 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14334 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
14335 ret
= GetClipCursor(&clip_rect
);
14336 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14337 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14338 wine_dbgstr_rect(&clip_rect
));
14340 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
14341 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
14344 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
14348 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
14349 ret
= GetClipCursor(&clip_rect
);
14350 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14351 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14352 wine_dbgstr_rect(&clip_rect
));
14354 /* Restore display mode */
14355 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
14356 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
14358 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
14359 ret
= GetClipCursor(&clip_rect
);
14360 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14361 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14362 wine_dbgstr_rect(&clip_rect
));
14364 /* Switch to normal cooperative level */
14365 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14366 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14368 get_virtual_rect(&rect
);
14369 ret
= GetClipCursor(&clip_rect
);
14370 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14371 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14372 wine_dbgstr_rect(&clip_rect
));
14375 IDirectDraw_Release(ddraw
);
14376 DestroyWindow(window
);
14379 static void check_vtbl_protection_(int line
, const void *vtbl
)
14381 MEMORY_BASIC_INFORMATION info
;
14382 SIZE_T ret
= VirtualQuery(vtbl
, &info
, sizeof(info
));
14383 ok_(__FILE__
, line
)(ret
== sizeof(info
), "Failed to query memory.\n");
14384 ok_(__FILE__
, line
)(info
.Protect
& (PAGE_READWRITE
| PAGE_WRITECOPY
), "Got protection %#lx.\n", info
.Protect
);
14386 #define check_vtbl_protection(a) check_vtbl_protection_(__LINE__, a)
14388 static void test_vtbl_protection(void)
14390 PALETTEENTRY palette_entries
[256];
14391 IDirectDrawSurface7
*surface7
;
14392 IDirectDrawSurface4
*surface4
;
14393 IDirectDrawSurface3
*surface3
;
14394 IDirectDrawSurface2
*surface2
;
14395 IDirectDrawSurface
*surface1
;
14396 IDirectDrawPalette
*palette
;
14397 DDSURFACEDESC surface_desc
;
14398 IDirectDraw
*ddraw
;
14403 window
= create_window();
14404 ddraw
= create_ddraw();
14405 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14406 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14407 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14409 memset(&surface_desc
, 0, sizeof(surface_desc
));
14410 surface_desc
.dwSize
= sizeof(surface_desc
);
14411 surface_desc
.dwFlags
= DDSD_CAPS
;
14412 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14413 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
14414 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14415 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
14416 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14417 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
14418 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14419 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface4
, (void **)&surface4
);
14420 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14421 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
14422 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14424 memset(palette_entries
, 0, sizeof(palette_entries
));
14425 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
14426 palette_entries
, &palette
, NULL
);
14427 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14429 check_vtbl_protection(ddraw
->lpVtbl
);
14430 check_vtbl_protection(palette
->lpVtbl
);
14431 check_vtbl_protection(surface1
->lpVtbl
);
14432 check_vtbl_protection(surface2
->lpVtbl
);
14433 check_vtbl_protection(surface3
->lpVtbl
);
14434 check_vtbl_protection(surface4
->lpVtbl
);
14435 check_vtbl_protection(surface7
->lpVtbl
);
14437 IDirectDrawPalette_Release(palette
);
14438 IDirectDrawSurface_Release(surface1
);
14439 IDirectDrawSurface2_Release(surface2
);
14440 IDirectDrawSurface3_Release(surface3
);
14441 IDirectDrawSurface4_Release(surface4
);
14442 IDirectDrawSurface7_Release(surface7
);
14443 refcount
= IDirectDraw_Release(ddraw
);
14444 ok(!refcount
, "%lu references left.\n", refcount
);
14445 DestroyWindow(window
);
14448 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
14451 RECT primary_rect
, window_rect
, new_rect
;
14452 IDirectDraw
*ddraw
;
14457 ddraw
= create_ddraw();
14458 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14459 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
14460 monitor_rect
->top
, 100, 100, NULL
, NULL
, NULL
, NULL
);
14461 ok(!!window
, "Failed to create a window.\n");
14464 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14465 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14467 ret
= GetWindowRect(window
, &window_rect
);
14468 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14469 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
14470 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14471 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14473 new_rect
= window_rect
;
14477 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
14478 new_rect
.bottom
- new_rect
.top
, TRUE
);
14479 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14480 ret
= GetWindowRect(window
, &window_rect
);
14481 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14482 ok(EqualRect(&window_rect
, &new_rect
),
14483 "Expected window rect %s, got %s.\n",
14484 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14485 /* After processing window events window rectangle gets restored. But only once, the size set
14486 * on the second resize remains. */
14488 ret
= GetWindowRect(window
, &window_rect
);
14489 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14490 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
14491 * it may get adjusted depending on window manager. */
14492 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
14493 "Expected window rect %s, got %s.\n",
14494 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14496 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
14497 new_rect
.bottom
- new_rect
.top
, TRUE
);
14498 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14499 ret
= GetWindowRect(window
, &window_rect
);
14500 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14501 ok(EqualRect(&window_rect
, &new_rect
),
14502 "Expected window rect %s, got %s.\n",
14503 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14505 ret
= GetWindowRect(window
, &window_rect
);
14506 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14507 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
14508 "Expected window rect %s, got %s.\n",
14509 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14511 /* Window activation should restore the window to fit the whole primary monitor */
14512 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
14513 SWP_NOZORDER
| SWP_NOSIZE
);
14514 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
14515 ret
= SetForegroundWindow(GetDesktopWindow());
14516 ok(ret
, "Failed to set foreground window.\n");
14518 ret
= ShowWindow(window
, SW_RESTORE
);
14519 ok(ret
, "Failed to restore window, error %lu.\n", GetLastError());
14521 ret
= SetForegroundWindow(window
);
14522 ok(ret
, "SetForegroundWindow failed, error %lu.\n", GetLastError());
14524 ret
= GetWindowRect(window
, &window_rect
);
14525 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14526 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14527 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14529 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14530 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14531 ret
= GetWindowRect(window
, &window_rect
);
14532 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14533 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14534 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14536 DestroyWindow(window
);
14537 IDirectDraw_Release(ddraw
);
14541 static void test_window_position(void)
14543 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
14546 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
14549 DDSURFACEDESC surface_desc
;
14550 IDirectDraw
*ddraw
;
14555 ddraw
= create_ddraw();
14556 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14557 window
= create_window();
14558 ok(!!window
, "Failed to create a window.\n");
14560 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
14561 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
14562 SWP_NOZORDER
| SWP_NOSIZE
);
14563 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
14565 surface_desc
.dwSize
= sizeof(surface_desc
);
14566 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14567 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14568 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %lu.\n",
14569 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
14570 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %lu.\n",
14571 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
14573 DestroyWindow(window
);
14574 IDirectDraw_Release(ddraw
);
14578 static void test_get_display_mode(void)
14580 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
14581 DDSURFACEDESC surface_desc
;
14582 IDirectDraw
*ddraw
;
14587 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
14589 ddraw
= create_ddraw();
14590 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14592 memset(&devmode
, 0, sizeof(devmode
));
14593 devmode
.dmSize
= sizeof(devmode
);
14594 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
14595 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
14597 surface_desc
.dwSize
= sizeof(surface_desc
);
14598 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14599 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14600 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Got dwSize %lu.\n", surface_desc
.dwSize
);
14601 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#lx, got %#lx.\n", flags
,
14602 surface_desc
.dwFlags
);
14603 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %lu, got %lu.\n",
14604 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
14605 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %lu, got %lu.\n",
14606 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
14607 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %lu, got %lu.\n",
14608 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
14609 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
14610 "Got ddpfPixelFormat.dwSize %lu.\n", surface_desc
.ddpfPixelFormat
.dwSize
);
14611 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
14612 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
14613 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
14614 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
14615 "Expected pitch %lu, got %lu.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
14616 surface_desc
.lPitch
);
14618 IDirectDraw_Release(ddraw
);
14621 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
14623 test_func(&IID_IDirect3DHALDevice
);
14624 test_func(&IID_IDirect3DRGBDevice
);
14627 static void test_texture_wrong_caps(const GUID
*device_guid
)
14629 static D3DTLVERTEX quad
[] =
14631 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
14632 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
14633 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
14634 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
14636 static DDPIXELFORMAT fmt
=
14638 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
14639 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
14641 unsigned int inst_length
, color
, expected_color
;
14642 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14643 IDirect3DExecuteBuffer
*execute_buffer
;
14644 IDirectDrawSurface
*surface
, *rt
;
14645 D3DTEXTUREHANDLE texture_handle
;
14646 D3DEXECUTEBUFFERDESC exec_desc
;
14647 IDirect3DMaterial
*background
;
14648 IDirect3DViewport
*viewport
;
14649 IDirect3DTexture
*texture
;
14650 IDirect3DDevice
*device
;
14651 IDirectDraw
*ddraw
;
14652 DDSURFACEDESC ddsd
;
14658 window
= create_window();
14659 ddraw
= create_ddraw();
14660 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14661 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
14663 skip("Failed to create a 3D device, skipping test.\n");
14664 DestroyWindow(window
);
14667 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
14668 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14670 viewport
= create_viewport(device
, 0, 0, 640, 480);
14672 memset(&ddsd
, 0, sizeof(ddsd
));
14673 ddsd
.dwSize
= sizeof(ddsd
);
14674 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
14675 ddsd
.dwHeight
= 16;
14677 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14678 U4(ddsd
).ddpfPixelFormat
= fmt
;
14679 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
14680 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14681 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
14682 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14683 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
14684 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14686 fill_surface(surface
, 0xff00ff00);
14688 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
14689 viewport_set_background(device
, viewport
, background
);
14691 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
14692 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14693 if (is_software_device_type(device_guid
))
14694 fill_surface(rt
, 0xffff0000);
14696 memset(&exec_desc
, 0, sizeof(exec_desc
));
14697 exec_desc
.dwSize
= sizeof(exec_desc
);
14698 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
14699 exec_desc
.dwBufferSize
= 1024;
14700 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
14701 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
14702 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14704 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
14705 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14706 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
14707 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(quad
);
14708 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
14709 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
14710 emit_tquad(&ptr
, 0);
14712 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(quad
);
14713 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
14714 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14716 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
14718 hr
= IDirect3DDevice_BeginScene(device
);
14719 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14720 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
14721 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14722 hr
= IDirect3DDevice_EndScene(device
);
14723 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14725 expected_color
= is_software_device_type(device_guid
) ? 0x0000ff00 : 0x00ffffff;
14726 color
= get_surface_color(rt
, 320, 240);
14727 ok(compare_color(color
, expected_color
, 1), "Got color 0x%08x, expected 0x%08x.\n", color
, expected_color
);
14729 IDirect3DTexture_Release(texture
);
14730 IDirectDrawSurface_Release(surface
);
14731 IDirectDrawSurface_Release(rt
);
14732 IDirect3DExecuteBuffer_Release(execute_buffer
);
14733 destroy_material(background
);
14734 destroy_viewport(device
, viewport
);
14736 IDirect3DDevice_Release(device
);
14737 refcount
= IDirectDraw_Release(ddraw
);
14738 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
14739 DestroyWindow(window
);
14742 static void test_filling_convention(void)
14744 unsigned int inst_length
, colour
, expected
, i
, x
, y
;
14745 static const DWORD colour_bottom
= 0x00ffff00;
14746 static const DWORD colour_clear
= 0x000000ff;
14747 static const DWORD colour_right
= 0x00000000;
14748 static const DWORD colour_left
= 0x00ff0000;
14749 static const DWORD colour_top
= 0x0000ff00;
14750 IDirect3DExecuteBuffer
*execute_buffer
;
14751 D3DEXECUTEBUFFERDESC exec_desc
;
14752 IDirectDrawSurface
*backbuffer
;
14753 IDirect3DMaterial
*background
;
14754 IDirect3DViewport
*viewport
;
14755 IDirect3DDevice
*device
;
14756 IDirectDraw
*ddraw
;
14763 static const unsigned int vp_size
= 8;
14764 D3DRECT clear_rect
= {{0}, {0}, {vp_size
}, {vp_size
}};
14766 /* This test data follows the examples in MSDN's
14767 * "Rasterization Rules (Direct3D 9)" article.
14769 * See the d3d9 test for a comment about the eps value. */
14770 static const float eps
= 1.0f
/ 64.0f
;
14771 D3DLVERTEX center_tris
[] =
14774 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14775 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14776 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14779 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14780 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14781 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14784 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14785 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14786 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14789 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14790 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14791 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14796 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14797 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14798 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14801 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14802 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14803 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14806 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14807 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14808 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14811 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14812 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14813 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14815 nudge_right_tris
[] =
14818 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14819 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14820 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14823 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14824 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14825 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14828 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14829 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14830 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14833 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14834 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14835 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14837 nudge_left_tris
[] =
14839 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14840 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14841 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14844 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14845 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14846 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14849 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14850 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14851 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14854 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14855 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14856 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14861 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14862 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14863 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14866 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14867 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14868 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14871 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14872 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14873 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14876 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14877 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14878 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14880 nudge_bottom_tris
[] =
14883 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14884 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14885 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14888 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14889 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14890 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14893 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14894 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14895 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14898 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14899 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14900 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14903 D3DTLVERTEX center_tris_t
[] =
14906 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14907 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14908 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14911 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14912 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14913 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14916 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14917 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14918 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14921 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14922 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14923 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14928 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14929 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14930 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
14933 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14934 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14935 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
14938 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14939 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14940 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
14943 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14944 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14945 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
14952 const char *expected
[8];
14958 D3DPROCESSVERTICES_TRANSFORM
,
14972 D3DPROCESSVERTICES_TRANSFORM
,
14986 D3DPROCESSVERTICES_TRANSFORM
,
15000 D3DPROCESSVERTICES_TRANSFORM
,
15014 D3DPROCESSVERTICES_TRANSFORM
,
15028 D3DPROCESSVERTICES_TRANSFORM
,
15042 D3DPROCESSVERTICES_COPY
,
15056 D3DPROCESSVERTICES_COPY
,
15069 static WORD indices
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
15071 window
= create_window();
15072 ddraw
= create_ddraw();
15073 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15074 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
15076 skip("Failed to create a 3D device.\n");
15077 IDirectDraw_Release(ddraw
);
15078 DestroyWindow(window
);
15082 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&backbuffer
);
15083 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15085 viewport
= create_viewport(device
, 0, 0, vp_size
, vp_size
);
15086 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
15087 viewport_set_background(device
, viewport
, background
);
15089 memset(&exec_desc
, 0, sizeof(exec_desc
));
15090 exec_desc
.dwSize
= sizeof(exec_desc
);
15091 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
15092 exec_desc
.dwBufferSize
= 1024;
15093 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
15095 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
15096 ok(hr
== D3D_OK
, "Failed to create execute buffer, hr %#lx.\n", hr
);
15098 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15100 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
15101 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15103 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
15104 ok(hr
== D3D_OK
, "Failed to lock execute buffer, hr %#lx.\n", hr
);
15106 /* All test geometry has the same vertex count and vertex size. */
15107 memcpy(exec_desc
.lpData
, tests
[i
].geometry
, sizeof(center_tris
));
15108 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(center_tris
);
15109 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
15110 /* Old WARP versions (w8, early win10) apply color keying without textures. */
15111 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
15113 emit_process_vertices(&ptr
, tests
[i
].op
, 0, 12);
15114 emit_tri_indices(&ptr
, indices
, 4);
15116 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
15117 inst_length
-= sizeof(center_tris
);
15119 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
15120 ok(hr
== D3D_OK
, "Failed to lock execute buffer, hr %#lx.\n", hr
);
15122 set_execute_data(execute_buffer
, 12, sizeof(center_tris
), inst_length
);
15124 hr
= IDirect3DDevice_BeginScene(device
);
15125 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15126 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
15127 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15128 hr
= IDirect3DDevice_EndScene(device
);
15129 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15131 for (y
= 0; y
< 8; y
++)
15133 for (x
= 0; x
< 8; x
++)
15136 switch (tests
[i
].expected
[y
][x
])
15138 case 'l': todo
= TRUE
;
15140 expected
= colour_left
;
15142 case 't': todo
= TRUE
;
15144 expected
= colour_top
;
15146 case 'r': todo
= TRUE
;
15148 expected
= colour_right
;
15150 case 'b': todo
= TRUE
;
15152 expected
= colour_bottom
;
15155 expected
= colour_clear
;
15158 ok(0, "Unexpected entry in expected test char\n");
15159 expected
= 0xdeadbeef;
15161 colour
= get_surface_color(backbuffer
, x
, y
);
15162 /* The nudge-to-bottom test fails on cards that give us a bottom-left
15163 * filling convention. The cause isn't the bottom part of the filling
15164 * convention, but because wined3d will nudge geometry to the left to
15165 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
15166 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
15167 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u.\n",
15173 destroy_viewport(device
, viewport
);
15174 IDirectDrawSurface_Release(backbuffer
);
15175 IDirect3DDevice_Release(device
);
15176 refcount
= IDirectDraw_Release(ddraw
);
15177 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15178 DestroyWindow(window
);
15181 static HRESULT WINAPI
test_enum_devices_caps_callback(GUID
*guid
, char *device_desc
,
15182 char *device_name
, D3DDEVICEDESC
*hal
, D3DDEVICEDESC
*hel
, void *ctx
)
15184 if(IsEqualGUID(&IID_IDirect3DRGBDevice
, guid
))
15186 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15187 "RGB Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15188 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15189 "RGB Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15190 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15191 "RGB Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15192 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15193 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15195 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15196 "RGB Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15197 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15198 "RGB Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15199 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15200 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15201 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15202 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15204 ok(hal
->dcmColorModel
== 0, "RGB Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15205 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "RGB Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15207 ok(hal
->dwFlags
== 0, "RGB Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15208 ok(hel
->dwFlags
!= 0, "RGB Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15210 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15211 "RGB Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15212 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15213 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15214 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15215 "RGB Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15216 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15217 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15219 else if(IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
15221 ok(hal
->dcmColorModel
== D3DCOLOR_RGB
, "HAL Device hal caps has colormodel %lu\n", hel
->dcmColorModel
);
15222 ok(hel
->dcmColorModel
== 0, "HAL Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15224 ok(hal
->dwFlags
!= 0, "HAL Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15225 ok(hel
->dwFlags
!= 0, "HAL Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15227 ok(hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
,
15228 "HAL Device hal device caps does not have D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15229 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15230 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15231 ok(hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
,
15232 "HAL Device hal device caps does not have D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15233 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15234 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15236 else if(IsEqualGUID(&IID_IDirect3DRefDevice
, guid
))
15238 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15239 "REF Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15240 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15241 "REF Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15242 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15243 "REF Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15244 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15245 "REF Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15247 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15248 "REF Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15249 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15250 "REF Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15251 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15252 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15253 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15254 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15256 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15257 "REF Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15258 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15259 "REF Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15260 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15261 "REF Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15262 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15263 "REF Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15265 else if(IsEqualGUID(&IID_IDirect3DRampDevice
, guid
))
15267 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15268 "Ramp Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15269 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15270 "Ramp Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15271 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15272 "Ramp Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15273 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15274 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15276 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15277 "Ramp Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15278 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15279 "Ramp Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15280 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15281 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15282 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15283 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15285 ok(hal
->dcmColorModel
== 0, "Ramp Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15286 ok(hel
->dcmColorModel
== D3DCOLOR_MONO
, "Ramp Device hel caps has colormodel %lu\n",
15287 hel
->dcmColorModel
);
15289 ok(hal
->dwFlags
== 0, "Ramp Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15290 ok(hel
->dwFlags
!= 0, "Ramp Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15292 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15293 "Ramp Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15294 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15295 "Ramp Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15296 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15297 "Ramp Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15298 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15299 "Ramp Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15301 else if(IsEqualGUID(&IID_IDirect3DMMXDevice
, guid
))
15303 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15304 "MMX Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15305 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15306 "MMX Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15307 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15308 "MMX Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15309 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15310 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15312 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15313 "MMX Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15314 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15315 "MMX Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15316 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15317 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15318 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15319 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15321 ok(hal
->dcmColorModel
== 0, "MMX Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15322 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "MMX Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15324 ok(hal
->dwFlags
== 0, "MMX Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15325 ok(hel
->dwFlags
!= 0, "MMX Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15327 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15328 "MMX Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15329 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15330 "MMX Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15331 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15332 "MMX Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15333 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15334 "MMX Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15338 ok(FALSE
, "Unexpected device enumerated: \"%s\" \"%s\"\n", device_desc
, device_name
);
15339 if (hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15340 trace("hal line has pow2 set\n");
15342 trace("hal line does NOT have pow2 set\n");
15343 if (hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15344 trace("hal tri has pow2 set\n");
15346 trace("hal tri does NOT have pow2 set\n");
15347 if (hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15348 trace("hel line has pow2 set\n");
15350 trace("hel line does NOT have pow2 set\n");
15351 if (hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15352 trace("hel tri has pow2 set\n");
15354 trace("hel tri does NOT have pow2 set\n");
15357 return DDENUMRET_OK
;
15360 static void test_enum_devices(void)
15362 IDirectDraw
*ddraw
;
15367 ddraw
= create_ddraw();
15368 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15370 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
15373 skip("D3D interface is not available, skipping test.\n");
15374 IDirectDraw_Release(ddraw
);
15378 hr
= IDirect3D_EnumDevices(d3d
, NULL
, NULL
);
15379 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
15381 hr
= IDirect3D_EnumDevices(d3d
, test_enum_devices_caps_callback
, NULL
);
15382 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
15384 IDirect3D_Release(d3d
);
15385 refcount
= IDirectDraw_Release(ddraw
);
15386 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15391 DDDEVICEIDENTIFIER identifier
;
15392 DEVMODEW current_mode
;
15393 IDirectDraw
*ddraw
;
15396 if (!(ddraw
= create_ddraw()))
15398 skip("Failed to create a ddraw object, skipping tests.\n");
15402 if (ddraw_get_identifier(ddraw
, &identifier
))
15404 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
15405 trace("Description string: \"%s\"\n", identifier
.szDescription
);
15406 trace("Driver version %d.%d.%d.%d\n",
15407 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
15408 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
15410 IDirectDraw_Release(ddraw
);
15412 memset(¤t_mode
, 0, sizeof(current_mode
));
15413 current_mode
.dmSize
= sizeof(current_mode
);
15414 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
15415 registry_mode
.dmSize
= sizeof(registry_mode
);
15416 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
15417 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
15418 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
15420 skip("Current mode does not match registry mode, skipping test.\n");
15424 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
15425 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
15427 test_coop_level_create_device_window();
15428 test_clipper_blt();
15429 test_coop_level_d3d_state();
15430 test_surface_interface_mismatch();
15431 test_coop_level_threaded();
15432 test_viewport_object();
15433 run_for_each_device_type(test_zenable
);
15434 run_for_each_device_type(test_ck_rgba
);
15440 test_window_style();
15441 test_redundant_mode_set();
15442 test_coop_level_mode_set();
15443 test_coop_level_mode_set_multi();
15445 test_coop_level_surf_create();
15446 test_coop_level_multi_window();
15447 test_clear_rect_count();
15448 test_coop_level_activateapp();
15449 test_unsupported_formats();
15450 run_for_each_device_type(test_rt_caps
);
15451 test_primary_caps();
15452 test_surface_lock();
15453 test_surface_discard();
15455 test_sysmem_overlay();
15456 test_primary_palette();
15457 test_surface_attachment();
15458 test_pixel_format();
15459 test_create_surface_pitch();
15461 test_palette_complex();
15465 test_specular_lighting();
15466 test_palette_gdi();
15467 test_palette_alpha();
15468 test_lost_device();
15469 test_surface_desc_lock();
15470 test_texturemapblend();
15471 test_viewport_clear_rect();
15473 test_colorkey_precision();
15474 test_range_colorkey();
15476 test_lockrect_invalid();
15477 test_yv12_overlay();
15478 test_offscreen_overlay();
15479 test_overlay_rect();
15481 test_blt_z_alpha();
15482 test_cross_device_blt();
15484 test_transform_vertices();
15485 test_display_mode_surface_pixel_format();
15486 test_surface_desc_size();
15487 test_texture_load();
15488 test_ck_operation();
15489 test_depth_readback();
15491 test_enum_surfaces();
15492 test_execute_data();
15494 test_find_device();
15496 test_gdi_surface();
15498 test_clipper_refcount();
15500 test_d32_support();
15501 test_cursor_clipping();
15502 test_vtbl_protection();
15503 test_window_position();
15504 test_get_display_mode();
15505 run_for_each_device_type(test_texture_wrong_caps
);
15506 test_filling_convention();
15507 test_enum_devices();