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"
29 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
30 static DEVMODEW registry_mode
;
32 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
44 struct create_window_thread_param
47 HANDLE window_created
;
48 HANDLE destroy_window
;
52 static BOOL
compare_uint(unsigned int x
, unsigned int y
, unsigned int max_diff
)
54 unsigned int diff
= x
> y
? x
- y
: y
- x
;
56 return diff
<= max_diff
;
59 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
69 return compare_uint(x
, y
, ulps
);
72 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
74 return compare_float(vec
->x
, x
, ulps
)
75 && compare_float(vec
->y
, y
, ulps
)
76 && compare_float(vec
->z
, z
, ulps
)
77 && compare_float(vec
->w
, w
, ulps
);
80 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
82 return compare_uint(c1
& 0xff, c2
& 0xff, max_diff
)
83 && compare_uint((c1
>> 8) & 0xff, (c2
>> 8) & 0xff, max_diff
)
84 && compare_uint((c1
>> 16) & 0xff, (c2
>> 16) & 0xff, max_diff
)
85 && compare_uint((c1
>> 24) & 0xff, (c2
>> 24) & 0xff, max_diff
);
88 static void get_virtual_rect(RECT
*rect
)
90 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
91 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
92 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
93 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
96 /* Try to make sure pending X events have been processed before continuing */
97 static void flush_events(void)
103 time
= GetTickCount() + diff
;
106 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
108 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
109 DispatchMessageA(&msg
);
110 diff
= time
- GetTickCount();
114 static BOOL
ddraw_get_identifier(IDirectDraw
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
116 IDirectDraw4
*ddraw4
;
119 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw4
, (void **)&ddraw4
);
120 ok(SUCCEEDED(hr
), "Failed to get IDirectDraw4 interface, hr %#lx.\n", hr
);
121 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw4
, identifier
, 0);
122 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#lx.\n", hr
);
123 IDirectDraw4_Release(ddraw4
);
125 return SUCCEEDED(hr
);
128 static BOOL
ddraw_is_warp(IDirectDraw
*ddraw
)
130 DDDEVICEIDENTIFIER identifier
;
132 return strcmp(winetest_platform
, "wine")
133 && ddraw_get_identifier(ddraw
, &identifier
)
134 && strstr(identifier
.szDriver
, "warp");
137 static BOOL
ddraw_is_vendor(IDirectDraw
*ddraw
, DWORD vendor
)
139 DDDEVICEIDENTIFIER identifier
;
141 return strcmp(winetest_platform
, "wine")
142 && ddraw_get_identifier(ddraw
, &identifier
)
143 && identifier
.dwVendorId
== vendor
;
146 static BOOL
ddraw_is_amd(IDirectDraw
*ddraw
)
148 return ddraw_is_vendor(ddraw
, 0x1002);
151 static BOOL
ddraw_is_intel(IDirectDraw
*ddraw
)
153 return ddraw_is_vendor(ddraw
, 0x8086);
156 static BOOL
ddraw_is_nvidia(IDirectDraw
*ddraw
)
158 return ddraw_is_vendor(ddraw
, 0x10de);
161 static BOOL
ddraw_is_vmware(IDirectDraw
*ddraw
)
163 return ddraw_is_vendor(ddraw
, 0x15ad);
166 static BOOL
is_software_device_type(const GUID
*device_guid
)
168 return device_guid
!= &IID_IDirect3DHALDevice
;
171 static IDirectDrawSurface
*create_overlay(IDirectDraw
*ddraw
,
172 unsigned int width
, unsigned int height
, DWORD format
)
174 IDirectDrawSurface
*surface
;
177 memset(&desc
, 0, sizeof(desc
));
178 desc
.dwSize
= sizeof(desc
);
179 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
180 desc
.dwWidth
= width
;
181 desc
.dwHeight
= height
;
182 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
183 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
184 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
185 desc
.ddpfPixelFormat
.dwFourCC
= format
;
187 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
192 static HWND
create_window(void)
194 RECT r
= {0, 0, 640, 480};
196 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
198 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
199 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
202 static DWORD WINAPI
create_window_thread_proc(void *param
)
204 struct create_window_thread_param
*p
= param
;
208 p
->window
= create_window();
209 ret
= SetEvent(p
->window_created
);
210 ok(ret
, "SetEvent failed, last error %lu.\n", GetLastError());
216 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
217 DispatchMessageA(&msg
);
218 res
= WaitForSingleObject(p
->destroy_window
, 100);
219 if (res
== WAIT_OBJECT_0
)
221 if (res
!= WAIT_TIMEOUT
)
223 ok(0, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
228 DestroyWindow(p
->window
);
233 static void create_window_thread(struct create_window_thread_param
*p
)
237 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
238 ok(!!p
->window_created
, "CreateEvent failed, last error %lu.\n", GetLastError());
239 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
240 ok(!!p
->destroy_window
, "CreateEvent failed, last error %lu.\n", GetLastError());
241 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
242 ok(!!p
->thread
, "Failed to create thread, last error %lu.\n", GetLastError());
243 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
244 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %lu.\n", res
, GetLastError());
247 static void destroy_window_thread(struct create_window_thread_param
*p
)
249 SetEvent(p
->destroy_window
);
250 WaitForSingleObject(p
->thread
, INFINITE
);
251 CloseHandle(p
->destroy_window
);
252 CloseHandle(p
->window_created
);
253 CloseHandle(p
->thread
);
256 static IDirectDrawSurface
*get_depth_stencil(IDirect3DDevice
*device
)
258 IDirectDrawSurface
*rt
, *ret
;
259 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
262 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
263 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
264 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ret
);
265 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#lx.\n", hr
);
266 IDirectDrawSurface_Release(rt
);
270 /* Free original_modes after finished using it */
271 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
273 unsigned int number
, size
= 2, count
= 0, index
= 0;
274 DISPLAY_DEVICEW display_device
;
275 DEVMODEW
*modes
, *tmp
;
277 if (!(modes
= malloc(size
* sizeof(*modes
))))
280 display_device
.cb
= sizeof(display_device
);
281 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
283 /* Skip software devices */
284 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
287 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
293 if (!(tmp
= realloc(modes
, size
* sizeof(*modes
))))
301 memset(&modes
[count
], 0, sizeof(modes
[count
]));
302 modes
[count
].dmSize
= sizeof(modes
[count
]);
303 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
309 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
312 *original_modes
= modes
;
313 *display_count
= count
;
317 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
322 for (index
= 0; index
< count
; ++index
)
324 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
325 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
326 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
329 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
330 return ret
== DISP_CHANGE_SUCCESSFUL
;
333 static HRESULT
set_display_mode(IDirectDraw
*ddraw
, DWORD width
, DWORD height
)
335 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
337 return IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24);
340 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
342 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
343 DDSURFACEDESC surface_desc
;
347 memset(&surface_desc
, 0, sizeof(surface_desc
));
348 surface_desc
.dwSize
= sizeof(surface_desc
);
350 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
351 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
355 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
357 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
358 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
363 static void fill_surface(IDirectDrawSurface
*surface
, D3DCOLOR color
)
365 DDSURFACEDESC surface_desc
= {sizeof(surface_desc
)};
370 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
371 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
373 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
375 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* surface_desc
.lPitch
);
376 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
382 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
383 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
386 static void check_rect(IDirectDrawSurface
*surface
, RECT r
)
388 LONG x_coords
[2][2] =
390 {r
.left
- 1, r
.left
+ 1},
391 {r
.right
+ 1, r
.right
- 1},
393 LONG y_coords
[2][2] =
395 {r
.top
- 1, r
.top
+ 1},
396 {r
.bottom
+ 1, r
.bottom
- 1}
398 unsigned int i
, j
, x_side
, y_side
, color
;
401 for (i
= 0; i
< 2; ++i
)
403 for (j
= 0; j
< 2; ++j
)
405 for (x_side
= 0; x_side
< 2; ++x_side
)
407 for (y_side
= 0; y_side
< 2; ++y_side
)
409 unsigned int expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
411 x
= x_coords
[i
][x_side
];
412 y
= y_coords
[j
][y_side
];
413 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
415 color
= get_surface_color(surface
, x
, y
);
416 ok(color
== expected
, "Pixel (%ld, %ld) has color %08x, expected %08x.\n", x
, y
, color
, expected
);
423 static void emit_process_vertices(void **ptr
, DWORD flags
, WORD base_idx
, DWORD vertex_count
)
425 D3DINSTRUCTION
*inst
= *ptr
;
426 D3DPROCESSVERTICES
*pv
= (D3DPROCESSVERTICES
*)(inst
+ 1);
428 inst
->bOpcode
= D3DOP_PROCESSVERTICES
;
429 inst
->bSize
= sizeof(*pv
);
433 pv
->wStart
= base_idx
;
435 pv
->dwCount
= vertex_count
;
441 static void emit_set_ts(void **ptr
, D3DTRANSFORMSTATETYPE state
, DWORD value
)
443 D3DINSTRUCTION
*inst
= *ptr
;
444 D3DSTATE
*ts
= (D3DSTATE
*)(inst
+ 1);
446 inst
->bOpcode
= D3DOP_STATETRANSFORM
;
447 inst
->bSize
= sizeof(*ts
);
450 ts
->dtstTransformStateType
= state
;
451 ts
->dwArg
[0] = value
;
456 static void emit_set_ls(void **ptr
, D3DLIGHTSTATETYPE state
, DWORD value
)
458 D3DINSTRUCTION
*inst
= *ptr
;
459 D3DSTATE
*ls
= (D3DSTATE
*)(inst
+ 1);
461 inst
->bOpcode
= D3DOP_STATELIGHT
;
462 inst
->bSize
= sizeof(*ls
);
465 ls
->dlstLightStateType
= state
;
466 ls
->dwArg
[0] = value
;
471 static void emit_set_rs(void **ptr
, D3DRENDERSTATETYPE state
, DWORD value
)
473 D3DINSTRUCTION
*inst
= *ptr
;
474 D3DSTATE
*rs
= (D3DSTATE
*)(inst
+ 1);
476 inst
->bOpcode
= D3DOP_STATERENDER
;
477 inst
->bSize
= sizeof(*rs
);
480 rs
->drstRenderStateType
= state
;
481 rs
->dwArg
[0] = value
;
486 static void emit_tquad(void **ptr
, WORD base_idx
)
488 D3DINSTRUCTION
*inst
= *ptr
;
489 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
491 inst
->bOpcode
= D3DOP_TRIANGLE
;
492 inst
->bSize
= sizeof(*tri
);
496 tri
->v2
= base_idx
+ 1;
497 tri
->v3
= base_idx
+ 2;
498 tri
->wFlags
= D3DTRIFLAG_START
;
501 tri
->v1
= base_idx
+ 2;
502 tri
->v2
= base_idx
+ 1;
503 tri
->v3
= base_idx
+ 3;
504 tri
->wFlags
= D3DTRIFLAG_ODD
;
510 static void emit_tquad_tlist(void **ptr
, WORD base_idx
)
512 D3DINSTRUCTION
*inst
= *ptr
;
513 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
515 inst
->bOpcode
= D3DOP_TRIANGLE
;
516 inst
->bSize
= sizeof(*tri
);
520 tri
->v2
= base_idx
+ 1;
521 tri
->v3
= base_idx
+ 2;
522 tri
->wFlags
= D3DTRIFLAG_START
;
525 tri
->v1
= base_idx
+ 2;
526 tri
->v2
= base_idx
+ 3;
528 tri
->wFlags
= D3DTRIFLAG_START
;
534 static void emit_tri_indices(void **ptr
, WORD
*indices
, unsigned int primitive_count
)
536 D3DINSTRUCTION
*inst
= *ptr
;
537 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
540 inst
->bOpcode
= D3DOP_TRIANGLE
;
541 inst
->bSize
= sizeof(*tri
);
542 inst
->wCount
= primitive_count
;
544 for (i
= 0; i
< primitive_count
; ++i
)
546 tri
->v1
= indices
[i
* 3];
547 tri
->v2
= indices
[i
* 3 + 1];
548 tri
->v3
= indices
[i
* 3 + 2];
549 tri
->wFlags
= D3DTRIFLAG_START
;
555 static void emit_texture_load(void **ptr
, D3DTEXTUREHANDLE dst_texture
,
556 D3DTEXTUREHANDLE src_texture
)
558 D3DINSTRUCTION
*instruction
= *ptr
;
559 D3DTEXTURELOAD
*texture_load
= (D3DTEXTURELOAD
*)(instruction
+ 1);
561 instruction
->bOpcode
= D3DOP_TEXTURELOAD
;
562 instruction
->bSize
= sizeof(*texture_load
);
563 instruction
->wCount
= 1;
565 texture_load
->hDestTexture
= dst_texture
;
566 texture_load
->hSrcTexture
= src_texture
;
572 static void emit_end(void **ptr
)
574 D3DINSTRUCTION
*inst
= *ptr
;
576 inst
->bOpcode
= D3DOP_EXIT
;
583 static void set_execute_data(IDirect3DExecuteBuffer
*execute_buffer
, UINT vertex_count
, UINT offset
, UINT len
)
585 D3DEXECUTEDATA exec_data
;
588 memset(&exec_data
, 0, sizeof(exec_data
));
589 exec_data
.dwSize
= sizeof(exec_data
);
590 exec_data
.dwVertexCount
= vertex_count
;
591 exec_data
.dwInstructionOffset
= offset
;
592 exec_data
.dwInstructionLength
= len
;
593 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
594 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
597 static DWORD
get_device_z_depth(IDirect3DDevice
*device
)
599 DDSCAPS caps
= {DDSCAPS_ZBUFFER
};
600 IDirectDrawSurface
*ds
, *rt
;
604 if (FAILED(IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
)))
607 hr
= IDirectDrawSurface_GetAttachedSurface(rt
, &caps
, &ds
);
608 IDirectDrawSurface_Release(rt
);
612 desc
.dwSize
= sizeof(desc
);
613 hr
= IDirectDrawSurface_GetSurfaceDesc(ds
, &desc
);
614 IDirectDrawSurface_Release(ds
);
618 return desc
.dwZBufferBitDepth
;
621 static IDirectDraw
*create_ddraw(void)
625 if (FAILED(DirectDrawCreate(NULL
, &ddraw
, NULL
)))
631 static IDirect3DDevice
*create_device_ex(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
, const GUID
*device_guid
)
633 /* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
634 * for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
635 * 16 bit buffers in ddraw1/2. Stencil was added in ddraw4, so we cannot create a D24S8
637 static const DWORD z_depths
[] = {16, 32, 24};
638 IDirectDrawSurface
*surface
, *ds
;
639 IDirect3DDevice
*device
= NULL
;
640 DDSURFACEDESC surface_desc
;
644 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, coop_level
);
645 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
647 memset(&surface_desc
, 0, sizeof(surface_desc
));
648 surface_desc
.dwSize
= sizeof(surface_desc
);
649 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
650 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
651 if (is_software_device_type(device_guid
))
652 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
653 surface_desc
.dwWidth
= 640;
654 surface_desc
.dwHeight
= 480;
656 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
657 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
659 if (coop_level
& DDSCL_NORMAL
)
661 IDirectDrawClipper
*clipper
;
663 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
664 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
665 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
666 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
667 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
668 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#lx.\n", hr
);
669 IDirectDrawClipper_Release(clipper
);
672 /* We used to use EnumDevices() for this, but it seems
673 * D3DDEVICEDESC.dwDeviceZBufferBitDepth only has a very casual
674 * relationship with reality. */
675 for (i
= 0; i
< ARRAY_SIZE(z_depths
); ++i
)
677 memset(&surface_desc
, 0, sizeof(surface_desc
));
678 surface_desc
.dwSize
= sizeof(surface_desc
);
679 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
680 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
681 if (is_software_device_type(device_guid
))
682 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
683 surface_desc
.dwZBufferBitDepth
= z_depths
[i
];
684 surface_desc
.dwWidth
= 640;
685 surface_desc
.dwHeight
= 480;
686 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
)))
689 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
690 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
691 IDirectDrawSurface_Release(ds
);
695 if (SUCCEEDED(IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
)))
698 IDirectDrawSurface_DeleteAttachedSurface(surface
, 0, ds
);
701 IDirectDrawSurface_Release(surface
);
705 static IDirect3DDevice
*create_device(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
)
707 return create_device_ex(ddraw
, window
, coop_level
, &IID_IDirect3DHALDevice
);
710 static IDirect3DViewport
*create_viewport(IDirect3DDevice
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
712 IDirect3DViewport
*viewport
;
717 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
718 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
719 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
720 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#lx.\n", hr
);
721 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
722 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#lx.\n", hr
);
723 memset(&vp
, 0, sizeof(vp
));
724 vp
.dwSize
= sizeof(vp
);
729 vp
.dvScaleX
= (float)w
/ 2.0f
;
730 vp
.dvScaleY
= (float)h
/ 2.0f
;
735 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
736 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#lx.\n", hr
);
737 IDirect3D_Release(d3d
);
742 static void viewport_set_background(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
,
743 IDirect3DMaterial
*material
)
745 D3DMATERIALHANDLE material_handle
;
748 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
749 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
750 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
751 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
754 static void destroy_viewport(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
)
758 hr
= IDirect3DDevice_DeleteViewport(device
, viewport
);
759 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#lx.\n", hr
);
760 IDirect3DViewport_Release(viewport
);
763 static IDirect3DMaterial
*create_material(IDirect3DDevice
*device
, D3DMATERIAL
*mat
)
765 IDirect3DMaterial
*material
;
769 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
770 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#lx.\n", hr
);
771 hr
= IDirect3D_CreateMaterial(d3d
, &material
, NULL
);
772 ok(SUCCEEDED(hr
), "Failed to create material, hr %#lx.\n", hr
);
773 hr
= IDirect3DMaterial_SetMaterial(material
, mat
);
774 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#lx.\n", hr
);
775 IDirect3D_Release(d3d
);
780 static IDirect3DMaterial
*create_diffuse_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
784 memset(&mat
, 0, sizeof(mat
));
785 mat
.dwSize
= sizeof(mat
);
791 return create_material(device
, &mat
);
794 static IDirect3DMaterial
*create_diffuse_and_ambient_material(IDirect3DDevice
*device
,
795 float r
, float g
, float b
, float a
)
799 memset(&mat
, 0, sizeof(mat
));
800 mat
.dwSize
= sizeof(mat
);
811 return create_material(device
, &mat
);
814 static IDirect3DMaterial
*create_emissive_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
818 memset(&mat
, 0, sizeof(mat
));
819 mat
.dwSize
= sizeof(mat
);
825 return create_material(device
, &mat
);
828 static IDirect3DMaterial
*create_specular_material(IDirect3DDevice
*device
,
829 float r
, float g
, float b
, float a
, float power
)
833 memset(&mat
, 0, sizeof(mat
));
834 mat
.dwSize
= sizeof(mat
);
841 return create_material(device
, &mat
);
844 static void destroy_material(IDirect3DMaterial
*material
)
846 IDirect3DMaterial_Release(material
);
853 WPARAM expect_wparam
;
856 static const struct message
*expect_messages
;
858 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
860 if (expect_messages
&& message
== expect_messages
->message
)
862 if (expect_messages
->check_wparam
)
863 ok (wparam
== expect_messages
->expect_wparam
,
864 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
865 wparam
, message
, expect_messages
->expect_wparam
);
870 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
873 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
874 * interface. This prevents subsequent SetCooperativeLevel() calls on a
875 * different window from failing with DDERR_HWNDALREADYSET. */
876 static void fix_wndproc(HWND window
, LONG_PTR proc
)
881 if (!(ddraw
= create_ddraw()))
884 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
885 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
886 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
887 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
888 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
890 IDirectDraw_Release(ddraw
);
893 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
895 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
896 ok(SUCCEEDED(hr
) || hr
== DDERR_IMPLICITLYCREATED
, "Failed to restore surface, hr %#lx.\n", hr
);
897 IDirectDrawSurface_Release(surface
);
902 static HRESULT
restore_surfaces(IDirectDraw
*ddraw
)
904 return IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
905 NULL
, NULL
, restore_callback
);
908 static void test_coop_level_create_device_window(void)
910 HWND focus_window
, device_window
;
914 focus_window
= create_window();
915 ddraw
= create_ddraw();
916 ok(!!ddraw
, "Failed to create a ddraw object.\n");
918 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
919 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
920 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
921 ok(!device_window
, "Unexpected device window found.\n");
922 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
923 ok(hr
== DDERR_INVALIDPARAMS
, "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
| DDSCL_NORMAL
);
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
| DDSCL_FULLSCREEN
);
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_EXCLUSIVE
| DDSCL_FULLSCREEN
);
935 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#lx.\n", hr
);
936 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
937 ok(!device_window
, "Unexpected device window found.\n");
939 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
940 if (broken(hr
== DDERR_INVALIDPARAMS
))
942 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
943 IDirectDraw_Release(ddraw
);
944 DestroyWindow(focus_window
);
948 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
949 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
950 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
951 ok(!device_window
, "Unexpected device window found.\n");
952 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
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");
957 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
958 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
959 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
960 ok(!device_window
, "Unexpected device window found.\n");
961 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
962 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
963 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#lx.\n", hr
);
964 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
965 ok(!!device_window
, "Device window not found.\n");
967 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
968 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
969 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
970 ok(!device_window
, "Unexpected device window found.\n");
971 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
972 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
973 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
974 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
975 ok(!!device_window
, "Device window not found.\n");
977 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
978 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
979 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
980 ok(!device_window
, "Unexpected device window found.\n");
981 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
982 ok(hr
== DDERR_NOFOCUSWINDOW
, "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
, focus_window
, DDSCL_SETFOCUSWINDOW
);
986 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
987 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
988 ok(!device_window
, "Unexpected device window found.\n");
989 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
990 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
991 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
992 ok(!!device_window
, "Device window not found.\n");
994 IDirectDraw_Release(ddraw
);
995 DestroyWindow(focus_window
);
998 static void test_clipper_blt(void)
1000 IDirectDrawSurface
*src_surface
, *dst_surface
;
1001 unsigned int color
, i
, j
, x
, y
;
1002 RECT client_rect
, src_rect
;
1003 IDirectDrawClipper
*clipper
;
1004 DDSURFACEDESC surface_desc
;
1015 static const DWORD src_data
[] =
1017 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1018 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1019 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
1021 static const unsigned int expected1
[] =
1023 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1024 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
1025 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1026 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
1028 /* Nvidia on Windows seems to have an off-by-one error
1029 * when processing source rectangles. Our left = 1 and
1030 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
1031 * read as well, but only for the edge pixels on the
1032 * output image. The bug happens on the y axis as well,
1033 * but we only read one row there, and all source rows
1034 * contain the same data. This bug is not dependent on
1035 * the presence of a clipper. */
1036 static const D3DCOLOR expected1_broken
[] =
1038 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1039 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1040 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
1041 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
1043 static const unsigned int expected2
[] =
1045 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1046 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
1047 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1048 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
1051 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1052 10, 10, 640, 480, 0, 0, 0, 0);
1053 ShowWindow(window
, SW_SHOW
);
1054 ddraw
= create_ddraw();
1055 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1057 ret
= GetClientRect(window
, &client_rect
);
1058 ok(ret
, "Failed to get client rect.\n");
1059 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
1060 ok(ret
, "Failed to map client rect.\n");
1062 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1063 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1065 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
1066 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
1067 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1068 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1069 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1070 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1071 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1072 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1073 rgn_data
= malloc(ret
);
1074 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
1075 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#lx.\n", hr
);
1076 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#lx.\n", rgn_data
->rdh
.dwSize
);
1077 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#lx.\n", rgn_data
->rdh
.iType
);
1078 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %lu.\n", rgn_data
->rdh
.nCount
);
1079 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
1080 "Got unexpected bounding rect %s, expected %s.\n",
1081 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
1084 r1
= CreateRectRgn(0, 0, 320, 240);
1085 ok(!!r1
, "Failed to create region.\n");
1086 r2
= CreateRectRgn(320, 240, 640, 480);
1087 ok(!!r2
, "Failed to create region.\n");
1088 CombineRgn(r1
, r1
, r2
, RGN_OR
);
1089 ret
= GetRegionData(r1
, 0, NULL
);
1090 rgn_data
= malloc(ret
);
1091 ret
= GetRegionData(r1
, ret
, rgn_data
);
1092 ok(!!ret
, "Failed to get region data.\n");
1097 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1098 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#lx.\n", hr
);
1099 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1100 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1101 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1102 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1106 memset(&surface_desc
, 0, sizeof(surface_desc
));
1107 surface_desc
.dwSize
= sizeof(surface_desc
);
1108 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1109 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1110 surface_desc
.dwWidth
= 640;
1111 surface_desc
.dwHeight
= 480;
1112 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1113 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1114 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
1115 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
1116 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
1117 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
1119 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
1120 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
1121 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
1122 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
1124 memset(&fx
, 0, sizeof(fx
));
1125 fx
.dwSize
= sizeof(fx
);
1126 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1127 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
1128 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1129 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1131 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
1132 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
1133 ok(surface_desc
.lPitch
== 2560, "Got unexpected surface pitch %lu.\n", surface_desc
.lPitch
);
1134 ptr
= surface_desc
.lpSurface
;
1135 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
1136 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
1137 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
1138 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
1139 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
1141 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
1142 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
1144 SetRect(&src_rect
, 1, 1, 5, 2);
1145 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
1146 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
1147 for (i
= 0; i
< 4; ++i
)
1149 for (j
= 0; j
< 4; ++j
)
1151 x
= 80 * ((2 * j
) + 1);
1152 y
= 60 * ((2 * i
) + 1);
1153 color
= get_surface_color(dst_surface
, x
, y
);
1154 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1155 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1156 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1160 fx
.dwFillColor
= 0xff0000ff;
1161 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1162 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
1163 for (i
= 0; i
< 4; ++i
)
1165 for (j
= 0; j
< 4; ++j
)
1167 x
= 80 * ((2 * j
) + 1);
1168 y
= 60 * ((2 * i
) + 1);
1169 color
= get_surface_color(dst_surface
, x
, y
);
1170 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1171 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1175 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1176 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#lx.\n", hr
);
1178 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1179 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1180 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1181 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1182 DestroyWindow(window
);
1183 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1184 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
1185 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1186 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
1187 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1188 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#lx.\n", hr
);
1189 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1190 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#lx.\n", hr
);
1191 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1192 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1193 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1194 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#lx.\n", hr
);
1196 IDirectDrawSurface_Release(dst_surface
);
1197 IDirectDrawSurface_Release(src_surface
);
1198 refcount
= IDirectDrawClipper_Release(clipper
);
1199 ok(!refcount
, "Clipper has %lu references left.\n", refcount
);
1200 IDirectDraw_Release(ddraw
);
1203 static void test_coop_level_d3d_state(void)
1205 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1206 IDirectDrawSurface
*rt
, *surface
;
1207 IDirect3DMaterial
*background
;
1208 IDirect3DViewport
*viewport
;
1209 IDirect3DDevice
*device
;
1210 D3DMATERIAL material
;
1217 window
= create_window();
1218 ddraw
= create_ddraw();
1219 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1220 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1222 skip("Failed to create a 3D device, skipping test.\n");
1223 IDirectDraw_Release(ddraw
);
1224 DestroyWindow(window
);
1228 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1229 viewport
= create_viewport(device
, 0, 0, 640, 480);
1230 viewport_set_background(device
, viewport
, background
);
1232 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1233 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1234 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1235 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1236 color
= get_surface_color(rt
, 320, 240);
1237 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1239 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1240 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1241 hr
= IDirectDrawSurface_IsLost(rt
);
1242 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1244 memset(&lock
, 0, sizeof(lock
));
1245 lock
.dwSize
= sizeof(lock
);
1246 lock
.lpSurface
= (void *)0xdeadbeef;
1247 hr
= IDirectDrawSurface_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1248 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
1249 ok(lock
.lpSurface
== (void *)0xdeadbeef, "Got unexpected lock.lpSurface %p.\n", lock
.lpSurface
);
1251 hr
= restore_surfaces(ddraw
);
1252 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1254 hr
= IDirectDrawSurface_Lock(rt
, NULL
, &lock
, DDLOCK_READONLY
, NULL
);
1255 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1256 hr
= IDirectDrawSurface2_Unlock(rt
, NULL
);
1257 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1259 memset(&material
, 0, sizeof(material
));
1260 material
.dwSize
= sizeof(material
);
1261 material
.diffuse
.r
= 0.0f
;
1262 material
.diffuse
.g
= 1.0f
;
1263 material
.diffuse
.b
= 0.0f
;
1264 material
.diffuse
.a
= 1.0f
;
1265 hr
= IDirect3DMaterial_SetMaterial(background
, &material
);
1266 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1268 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&surface
);
1269 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1270 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1271 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1272 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1273 color
= get_surface_color(rt
, 320, 240);
1274 ok(compare_color(color
, 0x0000ff00, 1) || broken(compare_color(color
, 0x00000000, 1)),
1275 "Got unexpected color 0x%08x.\n", color
);
1277 destroy_viewport(device
, viewport
);
1278 destroy_material(background
);
1279 IDirectDrawSurface_Release(surface
);
1280 IDirectDrawSurface_Release(rt
);
1281 IDirect3DDevice_Release(device
);
1282 IDirectDraw_Release(ddraw
);
1283 DestroyWindow(window
);
1286 static void test_surface_interface_mismatch(void)
1288 IDirectDraw
*ddraw
= NULL
;
1289 IDirectDrawSurface
*surface
= NULL
, *ds
;
1290 IDirectDrawSurface3
*surface3
= NULL
;
1291 IDirect3DDevice
*device
= NULL
;
1292 IDirect3DViewport
*viewport
= NULL
;
1293 IDirect3DMaterial
*background
= NULL
;
1294 DDSURFACEDESC surface_desc
;
1300 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1302 window
= create_window();
1303 ddraw
= create_ddraw();
1304 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1305 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1307 skip("Failed to create a 3D device, skipping test.\n");
1308 IDirectDraw_Release(ddraw
);
1309 DestroyWindow(window
);
1312 z_depth
= get_device_z_depth(device
);
1313 ok(!!z_depth
, "Failed to get device z depth.\n");
1314 IDirect3DDevice_Release(device
);
1317 memset(&surface_desc
, 0, sizeof(surface_desc
));
1318 surface_desc
.dwSize
= sizeof(surface_desc
);
1319 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1320 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1321 surface_desc
.dwWidth
= 640;
1322 surface_desc
.dwHeight
= 480;
1324 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1325 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
1327 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1330 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
1334 memset(&surface_desc
, 0, sizeof(surface_desc
));
1335 surface_desc
.dwSize
= sizeof(surface_desc
);
1336 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
1337 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1338 surface_desc
.dwZBufferBitDepth
= z_depth
;
1339 surface_desc
.dwWidth
= 640;
1340 surface_desc
.dwHeight
= 480;
1341 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1342 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#lx.\n", hr
);
1346 /* Using a different surface interface version still works */
1347 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1348 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#lx.\n", hr
);
1349 refcount
= IDirectDrawSurface_Release(ds
);
1350 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
1355 hr
= IDirectDrawSurface3_QueryInterface(surface3
, &IID_IDirect3DHALDevice
, (void **)&device
);
1356 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1360 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1361 viewport
= create_viewport(device
, 0, 0, 640, 480);
1362 viewport_set_background(device
, viewport
, background
);
1364 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1365 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
1366 color
= get_surface_color(surface
, 320, 240);
1367 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1371 destroy_viewport(device
, viewport
);
1373 destroy_material(background
);
1374 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1375 if (surface
) IDirectDrawSurface_Release(surface
);
1376 if (device
) IDirect3DDevice_Release(device
);
1377 if (ddraw
) IDirectDraw_Release(ddraw
);
1378 DestroyWindow(window
);
1381 static void test_coop_level_threaded(void)
1383 struct create_window_thread_param p
;
1387 ddraw
= create_ddraw();
1388 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1389 create_window_thread(&p
);
1391 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1392 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
1394 destroy_window_thread(&p
);
1395 IDirectDraw_Release(ddraw
);
1398 static BOOL
compare_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
1400 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
1401 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
1402 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
1403 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
1406 static void init_format_b5g6r5(DDPIXELFORMAT
*format
)
1408 format
->dwSize
= sizeof(*format
);
1409 format
->dwFlags
= DDPF_RGB
;
1410 format
->dwRGBBitCount
= 16;
1411 format
->dwRBitMask
= 0xf800;
1412 format
->dwGBitMask
= 0x07e0;
1413 format
->dwBBitMask
= 0x001f;
1416 static ULONG
get_refcount(IUnknown
*test_iface
)
1418 IUnknown_AddRef(test_iface
);
1419 return IUnknown_Release(test_iface
);
1422 static void test_viewport_object(void)
1424 IDirect3DViewport
*viewport
, *another_vp
;
1425 IDirectDrawGammaControl
*gamma
;
1426 IDirect3DViewport2
*viewport2
;
1427 IDirect3DViewport3
*viewport3
;
1428 IDirect3DDevice
*device
;
1443 window
= create_window();
1444 ddraw
= create_ddraw();
1445 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1446 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1448 skip("Failed to create a 3D device, skipping test.\n");
1449 IDirectDraw_Release(ddraw
);
1450 DestroyWindow(window
);
1454 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
1455 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1456 ref
= get_refcount((IUnknown
*) d3d
);
1457 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1459 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
1460 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1461 ref
= get_refcount((IUnknown
*)viewport
);
1462 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1463 ref
= get_refcount((IUnknown
*)d3d
);
1464 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1466 memset(&desc
, 0, sizeof(desc
));
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
) + 1;
1470 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1471 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1472 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1473 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1474 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1475 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1476 hr
= IDirect3DViewport_GetViewport(viewport
, &desc
.vp1
);
1477 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#lx.\n", hr
);
1478 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %lu.\n", desc
.vp1
.dwSize
);
1480 /* E_FAIL return values are returned by Winetestbot Windows NT machines. While not supporting
1481 * newer interfaces is legitimate for old ddraw versions, E_FAIL violates Microsoft's rules
1482 * for QueryInterface, hence the broken() */
1483 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1484 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1485 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
1486 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1488 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport2
, (void **)&viewport2
);
1489 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1491 ref
= get_refcount((IUnknown
*)viewport
);
1492 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1493 ref
= get_refcount((IUnknown
*)viewport2
);
1494 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1496 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
1497 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1499 ref
= get_refcount((IUnknown
*)viewport
);
1500 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1501 ref
= get_refcount((IUnknown
*)viewport3
);
1502 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1503 IDirect3DViewport3_Release(viewport3
);
1505 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IUnknown
, (void **)&unknown
);
1506 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1507 ref
= get_refcount((IUnknown
*)viewport
);
1508 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1509 ref
= get_refcount(unknown
);
1510 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1511 IUnknown_Release(unknown
);
1513 hr
= IDirect3DDevice_DeleteViewport(device
, NULL
);
1514 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1516 hr
= IDirect3D_CreateViewport(d3d
, &another_vp
, NULL
);
1517 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1519 /* AddViewport(NULL): Segfault */
1520 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
1521 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1522 ref
= get_refcount((IUnknown
*) viewport
);
1523 ok(ref
== 3, "Got unexpected refcount %lu.\n", ref
);
1524 hr
= IDirect3DDevice_AddViewport(device
, another_vp
);
1525 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1526 ref
= get_refcount((IUnknown
*) another_vp
);
1527 ok(ref
== 2, "Got unexpected refcount %lu.\n", ref
);
1529 memset(&vp
, 0, sizeof(vp
));
1536 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1537 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1540 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1541 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
1543 vp
.dwSize
= sizeof(vp
);
1544 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1545 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1547 vp2
.dwSize
= sizeof(vp2
);
1550 vp2
.dwWidth
= 640 - vp2
.dwX
;
1551 vp2
.dwHeight
= 480 - vp2
.dwY
;
1553 vp2
.dvClipY
= -1.75f
;
1554 vp2
.dvClipWidth
= 2.5f
;
1555 vp2
.dvClipHeight
= -1.5f
;
1558 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1559 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1561 memset(&vp
, 0xff, sizeof(vp
));
1562 vp
.dwSize
= sizeof(vp
);
1563 hr
= IDirect3DViewport2_GetViewport(viewport2
, &vp
);
1564 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1565 ok(vp
.dvMaxX
== 4.5f
&& vp
.dvMaxY
== -1.75f
&& vp
.dvScaleX
== 192.0f
1566 && vp
.dvScaleY
== -240.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
1567 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1568 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
1570 vp2
.dvClipX
= -1.5f
;
1571 vp2
.dvClipY
= 1.75f
;
1572 vp2
.dvClipWidth
= -1.5f
;
1573 vp2
.dvClipHeight
= 2.0f
;
1577 hr
= IDirect3DViewport2_SetViewport2(viewport2
, &vp2
);
1578 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1580 memset(&vp
, 0xff, sizeof(vp
));
1581 vp
.dwSize
= sizeof(vp
);
1582 hr
= IDirect3DViewport2_GetViewport(viewport2
, &vp
);
1583 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1584 ok(vp
.dvMaxX
== -3.0f
&& vp
.dvMaxY
== 1.75f
&& vp
.dvScaleX
== -320.0f
1585 && vp
.dvScaleY
== 180.0f
&& vp
.dvMinZ
== 0.0f
&& vp
.dvMaxZ
== 1.0f
,
1586 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1587 vp
.dvMaxX
, vp
.dvMaxY
, vp
.dvScaleX
, vp
.dvScaleY
, vp
.dvMinZ
, vp
.dvMaxZ
);
1589 vp
.dwSize
= sizeof(vp
);
1592 hr
= IDirect3DViewport2_SetViewport(viewport2
, &vp
);
1593 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1595 memset(&vp2
, 0xff, sizeof(vp2
));
1596 vp2
.dwSize
= sizeof(vp2
);
1597 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &vp2
);
1598 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1599 ok(vp2
.dvClipX
== 0.75f
&& vp2
.dvClipY
== 1.0f
&& vp2
.dvClipWidth
== -1.5f
1600 && vp2
.dvClipHeight
== 2.0f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
1601 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1602 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
1606 vp
.dvScaleX
= 192.0f
;
1607 vp
.dvScaleY
= -240.0f
;
1611 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1612 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1614 memset(&vp2
, 0xff, sizeof(vp2
));
1615 vp2
.dwSize
= sizeof(vp2
);
1616 hr
= IDirect3DViewport2_GetViewport2(viewport2
, &vp2
);
1617 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1618 ok(vp2
.dvClipX
== -1.25f
&& vp2
.dvClipY
== -0.75f
&& vp2
.dvClipWidth
== 2.5f
1619 && vp2
.dvClipHeight
== -1.5f
&& vp2
.dvMinZ
== 0.0f
&& vp2
.dvMaxZ
== 1.0f
,
1620 "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
1621 vp2
.dvClipX
, vp2
.dvClipY
, vp2
.dvClipWidth
, vp2
.dvClipHeight
, vp2
.dvMinZ
, vp2
.dvMaxZ
);
1623 IDirect3DViewport2_Release(viewport2
);
1625 hr
= IDirect3DDevice_DeleteViewport(device
, another_vp
);
1626 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1627 ref
= get_refcount((IUnknown
*) another_vp
);
1628 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1630 IDirect3DDevice_Release(device
);
1631 ref
= get_refcount((IUnknown
*) viewport
);
1632 ok(ref
== 1, "Got unexpected refcount %lu.\n", ref
);
1634 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
1635 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
1637 IDirect3DViewport_Release(another_vp
);
1638 IDirect3D_Release(d3d
);
1639 IDirect3DViewport_Release(viewport
);
1640 DestroyWindow(window
);
1641 IDirectDraw_Release(ddraw
);
1644 static void test_zenable(const GUID
*device_guid
)
1646 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1647 static D3DTLVERTEX tquad
[] =
1649 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1650 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1651 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1652 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1654 unsigned int inst_length
, color
, x
, y
, i
, j
;
1655 IDirect3DExecuteBuffer
*execute_buffer
;
1656 D3DEXECUTEBUFFERDESC exec_desc
;
1657 IDirect3DMaterial
*background
;
1658 IDirect3DViewport
*viewport
;
1659 IDirect3DDevice
*device
;
1660 IDirectDrawSurface
*rt
;
1666 window
= create_window();
1667 ddraw
= create_ddraw();
1668 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1669 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1671 skip("Failed to create a 3D device, skipping test.\n");
1672 IDirectDraw_Release(ddraw
);
1673 DestroyWindow(window
);
1677 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1678 viewport
= create_viewport(device
, 0, 0, 640, 480);
1679 viewport_set_background(device
, viewport
, background
);
1681 memset(&exec_desc
, 0, sizeof(exec_desc
));
1682 exec_desc
.dwSize
= sizeof(exec_desc
);
1683 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1684 exec_desc
.dwBufferSize
= 1024;
1685 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1687 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1688 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
1689 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1690 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
1691 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1692 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1693 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1694 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1695 emit_tquad(&ptr
, 0);
1697 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
1698 inst_length
-= sizeof(tquad
);
1699 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1700 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1702 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1703 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1704 hr
= IDirect3DDevice_BeginScene(device
);
1705 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1706 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
1707 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1708 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1709 hr
= IDirect3DDevice_EndScene(device
);
1710 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1712 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1713 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1714 for (i
= 0; i
< 4; ++i
)
1716 for (j
= 0; j
< 4; ++j
)
1718 x
= 80 * ((2 * j
) + 1);
1719 y
= 60 * ((2 * i
) + 1);
1720 color
= get_surface_color(rt
, x
, y
);
1721 ok(compare_color(color
, 0x0000ff00, 1),
1722 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1725 IDirectDrawSurface_Release(rt
);
1727 destroy_viewport(device
, viewport
);
1728 IDirect3DExecuteBuffer_Release(execute_buffer
);
1729 destroy_material(background
);
1730 IDirect3DDevice_Release(device
);
1731 IDirectDraw_Release(ddraw
);
1732 DestroyWindow(window
);
1735 static void test_ck_rgba(const GUID
*device_guid
)
1737 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1738 static D3DTLVERTEX tquad
[] =
1740 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1741 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1742 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1743 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1744 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1745 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1746 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1747 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1749 /* Supposedly there was no D3DRENDERSTATE_COLORKEYENABLE in D3D < 5.
1750 * Maybe the WARP driver on Windows 8 ignores setting it via the older
1751 * device interface but it's buggy in that the internal state is not
1752 * initialized, or possibly toggling D3DRENDERSTATE_COLORKEYENABLE /
1753 * D3DRENDERSTATE_ALPHABLENDENABLE has unintended side effects.
1754 * Checking the W8 test results it seems like test 1 fails most of the time
1755 * and test 0 fails very rarely. */
1758 D3DCOLOR fill_color
;
1761 unsigned int result1
, result1_r200
, result1_warp
;
1762 unsigned int result2
, result2_r200
, result2_warp
;
1766 /* r200 on Windows doesn't check the alpha component when applying the color
1767 * key, so the key matches on every texel. */
1768 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1769 0x000000ff, 0x000000ff, 0x0000ff00},
1770 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x0000ff00,
1771 0x000000ff, 0x000000ff, 0x0000ff00},
1772 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1773 0x0000ff00, 0x0000ff00, 0x0000ff00},
1774 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1775 0x0000ff00, 0x0000ff00, 0x0000ff00},
1776 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00,
1777 0x00807f00, 0x000000ff, 0x00807f00},
1778 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00,
1779 0x0000ff00, 0x000000ff, 0x0000ff00},
1780 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00,
1781 0x00807f00, 0x00807f00, 0x00807f00},
1782 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1783 0x0000ff00, 0x0000ff00, 0x0000ff00},
1786 IDirect3DExecuteBuffer
*execute_buffer
;
1787 D3DTEXTUREHANDLE texture_handle
;
1788 D3DEXECUTEBUFFERDESC exec_desc
;
1789 IDirect3DMaterial
*background
;
1790 IDirectDrawSurface
*surface
;
1791 IDirect3DViewport
*viewport
;
1792 DDSURFACEDESC surface_desc
;
1793 IDirect3DTexture
*texture
;
1794 IDirect3DDevice
*device
;
1795 IDirectDrawSurface
*rt
;
1796 unsigned int color
, i
;
1802 window
= create_window();
1803 ddraw
= create_ddraw();
1804 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1805 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
1807 skip("Failed to create a 3D device, skipping test.\n");
1808 IDirectDraw_Release(ddraw
);
1809 DestroyWindow(window
);
1813 background
= create_diffuse_material(device
, 1.0, 0.0f
, 0.0f
, 1.0f
);
1814 viewport
= create_viewport(device
, 0, 0, 640, 480);
1815 viewport_set_background(device
, viewport
, background
);
1817 memset(&surface_desc
, 0, sizeof(surface_desc
));
1818 surface_desc
.dwSize
= sizeof(surface_desc
);
1819 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1820 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1821 if (is_software_device_type(device_guid
))
1822 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
1823 surface_desc
.dwWidth
= 256;
1824 surface_desc
.dwHeight
= 256;
1825 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1826 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1827 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
1828 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
1829 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
1830 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
1831 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
1832 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1833 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1834 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1835 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1836 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1837 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1838 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1839 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1840 IDirect3DTexture_Release(texture
);
1842 memset(&exec_desc
, 0, sizeof(exec_desc
));
1843 exec_desc
.dwSize
= sizeof(exec_desc
);
1844 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1845 exec_desc
.dwBufferSize
= 1024;
1846 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1847 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1848 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1850 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1851 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1853 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1855 UINT draw1_len
, draw2_len
;
1858 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1859 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1860 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1861 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1862 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
1863 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1864 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1865 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1866 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1868 if (is_software_device_type(device_guid
))
1870 /* It looks like D3DRENDERSTATE_COLORKEYENABLE is ignored with software device
1871 * on Windows and the colour key is always enabled if set on surface. */
1872 IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, tests
[i
].color_key
1873 ? &surface_desc
.ddckCKSrcBlt
: NULL
);
1876 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1877 emit_tquad(&ptr
, 0);
1879 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
1880 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 4, 4);
1881 emit_tquad(&ptr
, 0);
1882 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1884 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_len
;
1885 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1886 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1888 memset(&fx
, 0, sizeof(fx
));
1889 fx
.dwSize
= sizeof(fx
);
1890 fx
.dwFillColor
= tests
[i
].fill_color
;
1891 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1892 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1894 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1895 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1896 /* RT clears are broken on Windows for software render target. */
1897 if (is_software_device_type(device_guid
))
1898 fill_surface(rt
, 0xffff0000);
1900 hr
= IDirect3DDevice_BeginScene(device
);
1901 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1902 set_execute_data(execute_buffer
, 8, sizeof(tquad
), draw1_len
);
1903 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1904 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1905 hr
= IDirect3DDevice_EndScene(device
);
1906 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1908 color
= get_surface_color(rt
, 320, 240);
1909 ok(compare_color(color
, tests
[i
].result1
, 2)
1910 || broken(compare_color(color
, tests
[i
].result1_r200
, 1))
1911 || broken(compare_color(color
, tests
[i
].result1_warp
, 1)),
1912 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1914 fx
.dwFillColor
= 0xff0000ff;
1915 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1916 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
1918 hr
= IDirect3DDevice_BeginScene(device
);
1919 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1920 set_execute_data(execute_buffer
, 8, sizeof(tquad
) + draw1_len
, draw2_len
);
1921 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1922 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1923 hr
= IDirect3DDevice_EndScene(device
);
1924 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1926 /* This tests that fragments that are masked out by the color key are
1927 * discarded, instead of just fully transparent. */
1928 color
= get_surface_color(rt
, 320, 240);
1929 ok(compare_color(color
, tests
[i
].result2
, 2)
1930 || broken(compare_color(color
, tests
[i
].result2_r200
, 1))
1931 || broken(compare_color(color
, tests
[i
].result2_warp
, 1)),
1932 "Got unexpected color 0x%08x for test %u.\n", color
, i
);
1935 IDirectDrawSurface_Release(rt
);
1936 IDirect3DExecuteBuffer_Release(execute_buffer
);
1937 IDirectDrawSurface_Release(surface
);
1938 destroy_viewport(device
, viewport
);
1939 destroy_material(background
);
1940 IDirect3DDevice_Release(device
);
1941 IDirectDraw_Release(ddraw
);
1942 DestroyWindow(window
);
1945 static void test_ck_default(void)
1947 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1948 static D3DTLVERTEX tquad
[] =
1950 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1951 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1952 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1953 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1955 IDirect3DExecuteBuffer
*execute_buffer
;
1956 IDirectDrawSurface
*surface
, *rt
;
1957 D3DTEXTUREHANDLE texture_handle
;
1958 D3DEXECUTEBUFFERDESC exec_desc
;
1959 IDirect3DMaterial
*background
;
1960 UINT draw1_offset
, draw1_len
;
1961 UINT draw2_offset
, draw2_len
;
1962 UINT draw3_offset
, draw3_len
;
1963 UINT draw4_offset
, draw4_len
;
1964 IDirect3DViewport
*viewport
;
1965 DDSURFACEDESC surface_desc
;
1966 IDirect3DTexture
*texture
;
1967 IDirect3DDevice
*device
;
1975 window
= create_window();
1976 ddraw
= create_ddraw();
1977 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1978 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1980 skip("Failed to create a 3D device, skipping test.\n");
1981 IDirectDraw_Release(ddraw
);
1982 DestroyWindow(window
);
1986 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1987 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
1989 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1990 viewport
= create_viewport(device
, 0, 0, 640, 480);
1991 viewport_set_background(device
, viewport
, background
);
1993 memset(&surface_desc
, 0, sizeof(surface_desc
));
1994 surface_desc
.dwSize
= sizeof(surface_desc
);
1995 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1996 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1997 surface_desc
.dwWidth
= 256;
1998 surface_desc
.dwHeight
= 256;
1999 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
2000 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2001 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
2002 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
2003 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
2004 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
2005 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2006 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2007 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2008 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2009 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
2010 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
2011 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
2012 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
2013 IDirect3DTexture_Release(texture
);
2015 memset(&fx
, 0, sizeof(fx
));
2016 fx
.dwSize
= sizeof(fx
);
2017 fx
.dwFillColor
= 0x000000ff;
2018 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2019 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
2021 memset(&exec_desc
, 0, sizeof(exec_desc
));
2022 exec_desc
.dwSize
= sizeof(exec_desc
);
2023 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
2024 exec_desc
.dwBufferSize
= 1024;
2025 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
2026 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
2027 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
2029 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
2030 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
2031 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
2032 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
2033 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2034 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
2035 emit_tquad(&ptr
, 0);
2037 draw1_offset
= sizeof(tquad
);
2038 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_offset
;
2039 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2040 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
2041 emit_tquad(&ptr
, 0);
2043 draw2_offset
= draw1_offset
+ draw1_len
;
2044 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw2_offset
;
2045 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2046 emit_tquad(&ptr
, 0);
2048 draw3_offset
= draw2_offset
+ draw2_len
;
2049 draw3_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw3_offset
;
2050 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
2051 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2052 emit_tquad(&ptr
, 0);
2053 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
2055 draw4_offset
= draw3_offset
+ draw3_len
;
2056 draw4_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw4_offset
;
2057 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
2058 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
2060 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2061 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2062 hr
= IDirect3DDevice_BeginScene(device
);
2063 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2064 set_execute_data(execute_buffer
, 4, draw1_offset
, draw1_len
);
2065 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2066 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2067 hr
= IDirect3DDevice_EndScene(device
);
2068 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2069 color
= get_surface_color(rt
, 320, 240);
2070 /* Color keying is supposed to be on by default in ddraw1, but used only if a ckey is set.
2071 * WARP begs to differ. The default of D3DRENDERSTATE_COLORKEYENABLE is random, and it
2072 * doesn't mind the absence of a color key (the latter part affects other tests, not this one). */
2073 ok(compare_color(color
, 0x0000ff00, 1) || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x000000ff, 1)),
2074 "Got unexpected color 0x%08x.\n", color
);
2076 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2077 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2078 hr
= IDirect3DDevice_BeginScene(device
);
2079 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2080 set_execute_data(execute_buffer
, 4, draw2_offset
, draw2_len
);
2081 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2082 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2083 hr
= IDirect3DDevice_EndScene(device
);
2084 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2085 color
= get_surface_color(rt
, 320, 240);
2086 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2088 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2089 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2090 hr
= IDirect3DDevice_BeginScene(device
);
2091 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2092 set_execute_data(execute_buffer
, 4, draw3_offset
, draw3_len
);
2093 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2094 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2095 hr
= IDirect3DDevice_EndScene(device
);
2096 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2097 color
= get_surface_color(rt
, 320, 240);
2098 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2100 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
2101 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
2102 hr
= IDirect3DDevice_BeginScene(device
);
2103 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2104 set_execute_data(execute_buffer
, 4, draw4_offset
, draw4_len
);
2105 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
2106 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
2107 hr
= IDirect3DDevice_EndScene(device
);
2108 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2109 color
= get_surface_color(rt
, 320, 240);
2110 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2112 IDirect3DExecuteBuffer_Release(execute_buffer
);
2113 IDirectDrawSurface_Release(surface
);
2114 destroy_viewport(device
, viewport
);
2115 destroy_material(background
);
2116 IDirectDrawSurface_Release(rt
);
2117 IDirect3DDevice_Release(device
);
2118 IDirectDraw_Release(ddraw
);
2119 DestroyWindow(window
);
2122 static void test_ck_complex(void)
2124 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
2125 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
2126 DDSURFACEDESC surface_desc
;
2127 IDirect3DDevice
*device
;
2128 DDCOLORKEY color_key
;
2135 window
= create_window();
2136 ddraw
= create_ddraw();
2137 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2138 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2140 skip("Failed to create a 3D device, skipping test.\n");
2141 DestroyWindow(window
);
2142 IDirectDraw_Release(ddraw
);
2145 IDirect3DDevice_Release(device
);
2147 memset(&surface_desc
, 0, sizeof(surface_desc
));
2148 surface_desc
.dwSize
= sizeof(surface_desc
);
2149 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2150 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2151 surface_desc
.dwWidth
= 128;
2152 surface_desc
.dwHeight
= 128;
2153 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2154 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2156 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2157 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2158 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2159 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2160 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2161 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2162 memset(&color_key
, 0, sizeof(color_key
));
2163 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2164 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2165 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2166 color_key
.dwColorSpaceLowValue
);
2167 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2168 color_key
.dwColorSpaceHighValue
);
2171 IDirectDrawSurface_AddRef(mipmap
);
2172 for (i
= 0; i
< 7; ++i
)
2174 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2175 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
2177 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2178 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2179 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2180 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2181 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2182 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx, i %u.\n", hr
, i
);
2183 memset(&color_key
, 0, sizeof(color_key
));
2184 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2185 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx, i %u.\n", hr
, i
);
2186 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2187 color_key
.dwColorSpaceLowValue
, i
);
2188 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08lx, i %u.\n",
2189 color_key
.dwColorSpaceHighValue
, i
);
2191 IDirectDrawSurface_Release(mipmap
);
2195 memset(&color_key
, 0, sizeof(color_key
));
2196 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2197 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2198 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2199 color_key
.dwColorSpaceLowValue
);
2200 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2201 color_key
.dwColorSpaceHighValue
);
2203 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2204 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
2205 IDirectDrawSurface_Release(mipmap
);
2206 refcount
= IDirectDrawSurface_Release(surface
);
2207 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2209 memset(&surface_desc
, 0, sizeof(surface_desc
));
2210 surface_desc
.dwSize
= sizeof(surface_desc
);
2211 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2212 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2213 surface_desc
.dwBackBufferCount
= 1;
2214 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2215 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2217 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2218 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
2219 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2220 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2221 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2222 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2223 memset(&color_key
, 0, sizeof(color_key
));
2224 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2225 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2226 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2227 color_key
.dwColorSpaceLowValue
);
2228 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2229 color_key
.dwColorSpaceHighValue
);
2231 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
2232 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
2234 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2235 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
2236 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2237 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2238 hr
= IDirectDrawSurface_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2239 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
2240 memset(&color_key
, 0, sizeof(color_key
));
2241 hr
= IDirectDrawSurface_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2242 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
2243 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2244 color_key
.dwColorSpaceLowValue
);
2245 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08lx.\n",
2246 color_key
.dwColorSpaceHighValue
);
2248 IDirectDrawSurface_Release(tmp
);
2250 refcount
= IDirectDrawSurface_Release(surface
);
2251 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2252 refcount
= IDirectDraw_Release(ddraw
);
2253 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
2254 DestroyWindow(window
);
2260 REFIID refcount_iid
;
2264 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2265 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2267 ULONG refcount
, expected_refcount
;
2268 IUnknown
*iface1
, *iface2
;
2272 for (i
= 0; i
< entry_count
; ++i
)
2274 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2275 ok(hr
== tests
[i
].hr
, "Got hr %#lx for test \"%s\" %u.\n", hr
, test_name
, i
);
2278 for (j
= 0; j
< entry_count
; ++j
)
2280 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2281 ok(hr
== tests
[j
].hr
, "Got hr %#lx for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2284 expected_refcount
= 0;
2285 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2286 ++expected_refcount
;
2287 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2288 ++expected_refcount
;
2289 refcount
= IUnknown_Release(iface2
);
2290 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, %u, expected %lu.\n",
2291 refcount
, test_name
, i
, j
, expected_refcount
);
2295 expected_refcount
= 0;
2296 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2297 ++expected_refcount
;
2298 refcount
= IUnknown_Release(iface1
);
2299 ok(refcount
== expected_refcount
, "Got refcount %lu for test \"%s\" %u, expected %lu.\n",
2300 refcount
, test_name
, i
, expected_refcount
);
2305 static void test_surface_qi(void)
2307 static const struct qi_test tests
[] =
2309 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2310 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2311 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2312 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2313 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2314 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2315 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2316 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2317 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2318 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2319 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2320 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2321 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2322 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2323 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2324 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2325 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2326 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2327 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2328 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2329 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2330 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2331 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2332 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2333 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2334 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2335 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2336 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2337 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2338 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2339 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2340 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2341 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2342 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2343 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2344 {NULL
, NULL
, E_INVALIDARG
},
2347 IDirectDrawSurface
*surface
;
2348 DDSURFACEDESC surface_desc
;
2349 IDirect3DDevice
*device
;
2354 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2356 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2360 window
= create_window();
2361 ddraw
= create_ddraw();
2362 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2363 /* Try to create a D3D device to see if the ddraw implementation supports
2364 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2365 * doesn't support e.g. the IDirect3DTexture interfaces. */
2366 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2368 skip("Failed to create a 3D device, skipping test.\n");
2369 IDirectDraw_Release(ddraw
);
2370 DestroyWindow(window
);
2373 IDirect3DDevice_Release(device
);
2375 memset(&surface_desc
, 0, sizeof(surface_desc
));
2376 surface_desc
.dwSize
= sizeof(surface_desc
);
2377 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2378 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2379 surface_desc
.dwWidth
= 512;
2380 surface_desc
.dwHeight
= 512;
2381 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface
**)0xdeadbeef, NULL
);
2382 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#lx.\n", hr
);
2383 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2384 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
2386 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2388 IDirectDrawSurface_Release(surface
);
2389 IDirectDraw_Release(ddraw
);
2390 DestroyWindow(window
);
2393 static void test_device_qi(void)
2395 static const struct qi_test tests
[] =
2397 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
2398 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
2399 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2400 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2401 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2402 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2403 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2404 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2405 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2406 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2407 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2408 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2409 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2410 {&IID_IDirect3DHALDevice
, &IID_IDirectDrawSurface
, S_OK
},
2411 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2412 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2413 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2414 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2415 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2416 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2417 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2418 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2419 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2420 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2421 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2422 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2423 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2424 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2425 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2426 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2427 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2428 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2429 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2430 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2431 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2432 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2436 IDirect3DDevice
*device
;
2440 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2442 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2446 window
= create_window();
2447 ddraw
= create_ddraw();
2448 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2449 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
2451 skip("Failed to create a 3D device, skipping test.\n");
2452 IDirectDraw_Release(ddraw
);
2453 DestroyWindow(window
);
2457 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirectDrawSurface
, tests
, ARRAY_SIZE(tests
));
2459 IDirect3DDevice_Release(device
);
2460 IDirectDraw_Release(ddraw
);
2461 DestroyWindow(window
);
2464 static void test_wndproc(void)
2466 LONG_PTR proc
, ddraw_proc
;
2473 static struct message messages
[] =
2475 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2476 {WM_MOVE
, FALSE
, 0},
2477 {WM_SIZE
, FALSE
, 0},
2478 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2479 {WM_ACTIVATE
, FALSE
, 0},
2480 {WM_SETFOCUS
, FALSE
, 0},
2484 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2485 ddraw
= create_ddraw();
2486 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2488 wc
.lpfnWndProc
= test_proc
;
2489 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2490 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2492 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2493 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2495 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2496 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2497 (LONG_PTR
)test_proc
, proc
);
2498 expect_messages
= messages
;
2499 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2500 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2501 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2502 expect_messages
= NULL
;
2503 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2504 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2505 (LONG_PTR
)test_proc
, proc
);
2506 ref
= IDirectDraw_Release(ddraw
);
2507 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
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
);
2512 /* DDSCL_NORMAL doesn't. */
2513 ddraw
= create_ddraw();
2514 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2515 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2516 (LONG_PTR
)test_proc
, proc
);
2517 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2518 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2519 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2520 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2521 (LONG_PTR
)test_proc
, proc
);
2522 ref
= IDirectDraw_Release(ddraw
);
2523 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2524 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2525 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2526 (LONG_PTR
)test_proc
, proc
);
2528 /* The original window proc is only restored by ddraw if the current
2529 * window proc matches the one ddraw set. This also affects switching
2530 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2531 ddraw
= create_ddraw();
2532 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2533 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2534 (LONG_PTR
)test_proc
, proc
);
2535 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
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
);
2541 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2542 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2543 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2544 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2545 (LONG_PTR
)test_proc
, proc
);
2546 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2547 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2548 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2549 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2550 (LONG_PTR
)test_proc
, proc
);
2551 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2552 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2553 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2554 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2555 (LONG_PTR
)DefWindowProcA
, proc
);
2556 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2557 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2558 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2559 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2560 (LONG_PTR
)DefWindowProcA
, proc
);
2561 ref
= IDirectDraw_Release(ddraw
);
2562 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2563 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2564 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2565 (LONG_PTR
)test_proc
, proc
);
2567 ddraw
= create_ddraw();
2568 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2569 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
2570 (LONG_PTR
)test_proc
, proc
);
2571 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2572 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2573 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2574 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix, got %#Ix.\n",
2575 (LONG_PTR
)test_proc
, proc
);
2576 ref
= IDirectDraw_Release(ddraw
);
2577 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2578 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2579 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
2580 (LONG_PTR
)DefWindowProcA
, proc
);
2582 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2583 expect_messages
= NULL
;
2584 DestroyWindow(window
);
2585 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2588 static void test_window_style(void)
2590 LONG style
, exstyle
, tmp
, expected_style
;
2591 RECT fullscreen_rect
, r
;
2592 HWND window
, window2
;
2598 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2599 0, 0, 100, 100, 0, 0, 0, 0);
2600 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
2601 0, 0, 50, 50, 0, 0, 0, 0);
2602 ddraw
= create_ddraw();
2603 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2605 style
= GetWindowLongA(window
, GWL_STYLE
);
2606 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2607 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2609 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2610 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2612 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2613 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2614 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2615 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2617 GetWindowRect(window
, &r
);
2618 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2619 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2620 GetClientRect(window
, &r
);
2621 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2623 ret
= SetForegroundWindow(GetDesktopWindow());
2624 ok(ret
, "Failed to set foreground window.\n");
2626 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2627 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2628 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2629 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2631 ret
= SetForegroundWindow(window
);
2632 ok(ret
, "Failed to set foreground window.\n");
2633 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2634 * the next tests expect this. */
2635 ShowWindow(window
, SW_HIDE
);
2637 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2638 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2640 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2641 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2642 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2643 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2645 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
| DDSCL_NOWINDOWCHANGES
);
2646 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2648 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2649 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2650 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2651 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2653 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2654 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2656 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2657 expected_style
= style
| WS_VISIBLE
;
2658 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2659 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2660 expected_style
= exstyle
| WS_EX_TOPMOST
;
2661 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2663 ShowWindow(window
, SW_HIDE
);
2664 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2665 todo_wine
ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2666 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2667 expected_style
= exstyle
| WS_EX_TOPMOST
;
2668 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2670 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_NOWINDOWCHANGES
);
2671 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2673 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2674 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2675 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2676 expected_style
= exstyle
| WS_EX_TOPMOST
;
2677 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2679 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2680 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2682 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2683 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2684 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2685 expected_style
= exstyle
| WS_EX_TOPMOST
;
2686 ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2688 ret
= SetForegroundWindow(window
);
2689 ok(ret
, "Failed to set foreground window.\n");
2691 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2692 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2694 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2695 expected_style
= style
| WS_VISIBLE
;
2696 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2697 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2698 expected_style
= exstyle
| WS_EX_TOPMOST
;
2699 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2701 ShowWindow(window
, SW_HIDE
);
2702 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2703 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2705 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2706 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2707 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2708 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2710 ShowWindow(window
, SW_SHOW
);
2711 ret
= SetForegroundWindow(GetDesktopWindow());
2712 ok(ret
, "Failed to set foreground window.\n");
2713 SetActiveWindow(window
);
2714 ok(GetActiveWindow() == window
, "Unexpected active window.\n");
2715 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2716 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2718 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2719 expected_style
= style
| WS_VISIBLE
;
2720 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2721 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2722 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2724 GetWindowRect(window
, &r
);
2725 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2726 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2728 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2729 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2731 SetWindowPos(window
, NULL
, 0, 0, 100, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
2732 GetWindowRect(window
, &r
);
2733 ok(!EqualRect(&r
, &fullscreen_rect
), "Window resize failed? got %s.\n",
2734 wine_dbgstr_rect(&r
));
2736 ret
= SetForegroundWindow(window2
);
2737 ok(ret
, "Failed to set foreground window.\n");
2738 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2739 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2741 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2742 expected_style
= style
| WS_VISIBLE
;
2743 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2744 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2745 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2747 GetWindowRect(window
, &r
);
2748 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2749 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2751 ret
= SetForegroundWindow(window
);
2752 ok(ret
, "Failed to set foreground window.\n");
2753 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2754 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2756 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2757 expected_style
= style
| WS_VISIBLE
;
2758 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2759 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2760 expected_style
= exstyle
| WS_EX_TOPMOST
;
2761 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2763 ShowWindow(window
, SW_HIDE
);
2764 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2765 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2767 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2768 ok(tmp
== style
, "Expected window style %#lx, got %#lx.\n", style
, tmp
);
2769 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2770 ok(tmp
== exstyle
, "Expected window extended style %#lx, got %#lx.\n", exstyle
, tmp
);
2772 ShowWindow(window
, SW_SHOW
);
2773 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2774 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2776 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2777 expected_style
= style
| WS_VISIBLE
;
2778 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2779 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2780 expected_style
= exstyle
| WS_EX_TOPMOST
;
2781 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2783 ret
= SetForegroundWindow(GetDesktopWindow());
2784 ok(ret
, "Failed to set foreground window.\n");
2785 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2786 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2787 todo_wine
ok(tmp
== expected_style
, "Expected window style %#lx, got %#lx.\n", expected_style
, tmp
);
2788 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2789 expected_style
= exstyle
| WS_EX_TOPMOST
;
2790 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#lx, got %#lx.\n", expected_style
, tmp
);
2792 /* Test that there is a ~1.5s timer that checks and restores WS_EX_TOPMOST if it's missing */
2793 ret
= ShowWindow(window
, SW_RESTORE
);
2794 ok(ret
, "ShowWindow failed, error %#lx.\n", GetLastError());
2795 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2796 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2799 /* Remove WS_VISIBLE and WS_EX_TOPMOST */
2800 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2801 ok(tmp
& WS_VISIBLE
, "Expected WS_VISIBLE.\n");
2802 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2803 ok(tmp
& WS_EX_TOPMOST
, "Expected WS_EX_TOPMOST.\n");
2804 ret
= ShowWindow(window
, SW_HIDE
);
2805 ok(ret
, "ShowWindow failed, error %#lx.\n", GetLastError());
2806 ret
= SetWindowPos(window
, HWND_NOTOPMOST
, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
);
2807 ok(ret
, "SetWindowPos failed, error %#lx.\n", GetLastError());
2808 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2809 ok(!(tmp
& WS_VISIBLE
), "Got unexpected WS_VISIBLE.\n");
2810 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2811 ok(!(tmp
& WS_EX_TOPMOST
), "Got unexpected WS_EX_TOPMOST.\n");
2816 /* WS_VISIBLE is not restored but WS_EX_TOPMOST is */
2817 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2818 ok(!(tmp
& WS_VISIBLE
), "Got unexpected WS_VISIBLE.\n");
2819 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2820 ok(tmp
& WS_EX_TOPMOST
, "Expected WS_EX_TOPMOST.\n");
2822 ref
= IDirectDraw_Release(ddraw
);
2823 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2825 DestroyWindow(window2
);
2826 DestroyWindow(window
);
2829 static void test_redundant_mode_set(void)
2831 DDSURFACEDESC surface_desc
= {0};
2838 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2839 0, 0, 100, 100, 0, 0, 0, 0);
2840 ddraw
= create_ddraw();
2841 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2843 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2844 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
2846 surface_desc
.dwSize
= sizeof(surface_desc
);
2847 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
2848 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#lx.\n", hr
);
2850 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2851 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
2852 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2854 GetWindowRect(window
, &q
);
2858 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2859 GetWindowRect(window
, &s
);
2860 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2862 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2863 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
2864 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#lx.\n", hr
);
2866 GetWindowRect(window
, &s
);
2867 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2868 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2870 ref
= IDirectDraw_Release(ddraw
);
2871 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
2873 DestroyWindow(window
);
2876 static SIZE screen_size
;
2878 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2880 if (message
== WM_SIZE
)
2882 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2883 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2886 return test_proc(hwnd
, message
, wparam
, lparam
);
2889 struct test_coop_level_mode_set_enum_param
2891 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2894 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC
*surface_desc
, void *context
)
2896 struct test_coop_level_mode_set_enum_param
*param
= context
;
2898 if (surface_desc
->ddpfPixelFormat
.dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2899 return DDENUMRET_OK
;
2900 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2901 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2902 return DDENUMRET_OK
;
2904 if (!param
->ddraw_width
)
2906 param
->ddraw_width
= surface_desc
->dwWidth
;
2907 param
->ddraw_height
= surface_desc
->dwHeight
;
2908 return DDENUMRET_OK
;
2910 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2911 return DDENUMRET_OK
;
2913 /* The docs say the DDENUMRET_CANCEL below cancels the enumeration, so the check should be
2914 * redundant. However, since Windows 10 this no longer works and the enumeration continues
2915 * until all supported modes are enumerated. Win8 and earlier do cancel.
2917 * Unrelatedly, some testbot machines report high res modes like 1920x1080, but suffer from
2918 * some problems when we actually try to set them (w10pro64 and its localization siblings).
2919 * Try to stay below the registry mode if possible. */
2920 if (!param
->user32_width
|| (surface_desc
->dwWidth
< registry_mode
.dmPelsWidth
2921 && surface_desc
->dwHeight
< registry_mode
.dmPelsHeight
))
2923 param
->user32_width
= surface_desc
->dwWidth
;
2924 param
->user32_height
= surface_desc
->dwHeight
;
2926 return DDENUMRET_CANCEL
;
2929 static void test_coop_level_mode_set(void)
2931 DEVMODEW
*original_modes
= NULL
, devmode
, devmode2
;
2932 unsigned int display_count
= 0;
2933 IDirectDrawSurface
*primary
;
2934 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2942 struct test_coop_level_mode_set_enum_param param
;
2946 static const struct message exclusive_messages
[] =
2948 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2949 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2950 {WM_SIZE
, FALSE
, 0},
2951 {WM_DISPLAYCHANGE
, FALSE
, 0},
2954 static const struct message exclusive_focus_loss_messages
[] =
2956 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2957 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window resize due to mode change. */
2958 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2959 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* Generated by DefWindowProc. */
2960 {WM_DISPLAYCHANGE
, FALSE
, 0},
2961 {WM_KILLFOCUS
, FALSE
, 0},
2962 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Window minimized. */
2963 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2964 * SW_MINIMIZED, causing a recursive window activation that does not
2965 * produce the same result in Wine yet. Ignore the difference for now.
2966 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2967 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2968 {WM_MOVE
, FALSE
, 0},
2969 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2970 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2973 static const struct message exclusive_focus_restore_messages
[] =
2975 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2976 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2977 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2978 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2979 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2980 /* Native redundantly sets the window size here. */
2981 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2982 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2983 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2984 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2987 static const struct message sc_restore_messages
[] =
2989 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2990 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2991 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2992 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2995 static const struct message sc_minimize_messages
[] =
2997 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2998 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2999 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3000 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
3003 static const struct message sc_maximize_messages
[] =
3005 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
3006 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
3007 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
3008 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
3012 static const struct message normal_messages
[] =
3014 {WM_DISPLAYCHANGE
, FALSE
, 0},
3018 memset(&devmode
, 0, sizeof(devmode
));
3019 devmode
.dmSize
= sizeof(devmode
);
3020 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3021 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3022 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3023 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3024 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3025 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3027 ret
= save_display_modes(&original_modes
, &display_count
);
3028 ok(ret
, "Failed to save original display modes.\n");
3030 ddraw
= create_ddraw();
3031 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3033 memset(¶m
, 0, sizeof(param
));
3034 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
3035 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3036 ref
= IDirectDraw_Release(ddraw
);
3037 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3039 if (!param
.user32_height
)
3041 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
3042 free(original_modes
);
3046 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3047 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
3048 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
3050 memset(&devmode
, 0, sizeof(devmode
));
3051 devmode
.dmSize
= sizeof(devmode
);
3052 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3053 devmode
.dmPelsWidth
= param
.user32_width
;
3054 devmode
.dmPelsHeight
= param
.user32_height
;
3055 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3056 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3058 ddraw
= create_ddraw();
3059 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3061 wc
.lpfnWndProc
= mode_set_proc
;
3062 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
3063 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3065 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3066 0, 0, 100, 100, 0, 0, 0, 0);
3068 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3069 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3071 GetWindowRect(window
, &r
);
3072 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3073 wine_dbgstr_rect(&r
));
3075 memset(&ddsd
, 0, sizeof(ddsd
));
3076 ddsd
.dwSize
= sizeof(ddsd
);
3077 ddsd
.dwFlags
= DDSD_CAPS
;
3078 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3080 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3081 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3082 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3083 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3084 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3085 param
.user32_width
, ddsd
.dwWidth
);
3086 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3087 param
.user32_height
, ddsd
.dwHeight
);
3089 GetWindowRect(window
, &r
);
3090 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3091 wine_dbgstr_rect(&r
));
3093 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3094 expect_messages
= exclusive_messages
;
3098 hr
= IDirectDrawSurface_IsLost(primary
);
3099 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3100 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3101 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3102 hr
= IDirectDrawSurface_IsLost(primary
);
3103 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3105 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3106 expect_messages
= NULL
;
3107 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
3108 "Expected screen size %lux%lu, got %lux%lu.\n",
3109 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
3111 GetWindowRect(window
, &r
);
3112 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3113 wine_dbgstr_rect(&r
));
3115 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3116 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3117 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %lu, got %lu.\n",
3118 param
.user32_width
, ddsd
.dwWidth
);
3119 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %lu, got %lu.\n",
3120 param
.user32_height
, ddsd
.dwHeight
);
3121 IDirectDrawSurface_Release(primary
);
3123 memset(&ddsd
, 0, sizeof(ddsd
));
3124 ddsd
.dwSize
= sizeof(ddsd
);
3125 ddsd
.dwFlags
= DDSD_CAPS
;
3126 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3128 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3129 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3130 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3131 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3132 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3133 param
.ddraw_width
, ddsd
.dwWidth
);
3134 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3135 param
.ddraw_height
, ddsd
.dwHeight
);
3137 GetWindowRect(window
, &r
);
3138 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3139 wine_dbgstr_rect(&r
));
3141 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3142 expect_messages
= exclusive_messages
;
3146 hr
= IDirectDrawSurface_IsLost(primary
);
3147 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3148 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3149 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3150 hr
= IDirectDrawSurface_IsLost(primary
);
3151 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3153 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3154 expect_messages
= NULL
;
3155 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
3156 "Expected screen size %lux%lu, got %lux%lu.\n",
3157 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
3159 GetWindowRect(window
, &r
);
3160 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
3161 wine_dbgstr_rect(&r
));
3163 expect_messages
= exclusive_focus_loss_messages
;
3164 ret
= SetForegroundWindow(GetDesktopWindow());
3165 ok(ret
, "Failed to set foreground window.\n");
3166 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3167 memset(&devmode
, 0, sizeof(devmode
));
3168 devmode
.dmSize
= sizeof(devmode
);
3169 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3170 ok(ret
, "Failed to get display mode.\n");
3171 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3172 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3173 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3175 expect_messages
= exclusive_focus_restore_messages
;
3176 ShowWindow(window
, SW_RESTORE
);
3177 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3179 GetWindowRect(window
, &r
);
3180 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3181 wine_dbgstr_rect(&r
));
3182 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3183 ok(ret
, "Failed to get display mode.\n");
3184 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3185 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpected screen size %lux%lu.\n",
3186 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3188 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3189 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3190 /* Normally the primary should be restored here. Unfortunately this causes the
3191 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3192 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3193 * the point of the GetSurfaceDesc call. */
3195 expect_messages
= sc_minimize_messages
;
3196 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3197 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3198 expect_messages
= NULL
;
3200 expect_messages
= sc_restore_messages
;
3201 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3202 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3203 expect_messages
= NULL
;
3205 expect_messages
= sc_maximize_messages
;
3206 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3207 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3208 expect_messages
= NULL
;
3210 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3211 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3213 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3214 expect_messages
= exclusive_messages
;
3218 hr
= IDirectDrawSurface_IsLost(primary
);
3219 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3220 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3221 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3222 hr
= IDirectDrawSurface_IsLost(primary
);
3223 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3226 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3227 expect_messages
= NULL
;
3229 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3230 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3231 "Expected screen size %lux%lu, got %lux%lu.\n",
3232 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3234 GetWindowRect(window
, &r
);
3236 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3237 wine_dbgstr_rect(&r
));
3239 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3240 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3241 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3242 param
.ddraw_width
, ddsd
.dwWidth
);
3243 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3244 param
.ddraw_height
, ddsd
.dwHeight
);
3245 IDirectDrawSurface_Release(primary
);
3248 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3249 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3251 memset(&ddsd
, 0, sizeof(ddsd
));
3252 ddsd
.dwSize
= sizeof(ddsd
);
3253 ddsd
.dwFlags
= DDSD_CAPS
;
3254 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3256 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3257 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3258 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3259 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3260 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3261 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3262 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3263 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3265 GetWindowRect(window
, &r
);
3267 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3268 wine_dbgstr_rect(&r
));
3270 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3271 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3273 GetWindowRect(window
, &r
);
3275 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3276 wine_dbgstr_rect(&r
));
3278 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3279 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3280 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3281 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3282 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3283 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3284 IDirectDrawSurface_Release(primary
);
3286 memset(&ddsd
, 0, sizeof(ddsd
));
3287 ddsd
.dwSize
= sizeof(ddsd
);
3288 ddsd
.dwFlags
= DDSD_CAPS
;
3289 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3291 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3292 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3293 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3294 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3295 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3296 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3297 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3298 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3300 GetWindowRect(window
, &r
);
3302 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3303 wine_dbgstr_rect(&r
));
3305 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3306 expect_messages
= normal_messages
;
3310 hr
= IDirectDrawSurface_IsLost(primary
);
3311 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3312 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3313 devmode
.dmPelsWidth
= param
.user32_width
;
3314 devmode
.dmPelsHeight
= param
.user32_height
;
3315 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3316 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3317 hr
= IDirectDrawSurface_IsLost(primary
);
3318 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3320 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3321 expect_messages
= NULL
;
3322 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3324 GetWindowRect(window
, &r
);
3326 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3327 wine_dbgstr_rect(&r
));
3329 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3330 expect_messages
= normal_messages
;
3334 hr
= IDirectDrawSurface_Restore(primary
);
3335 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3336 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3337 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3339 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
3340 IDirectDrawSurface_Release(primary
);
3341 IDirectDraw_Release(ddraw
);
3344 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3345 hr
= IDirectDrawSurface_Restore(primary
);
3346 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3347 hr
= IDirectDrawSurface_IsLost(primary
);
3348 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3350 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3351 expect_messages
= NULL
;
3352 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3354 GetWindowRect(window
, &r
);
3356 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3357 wine_dbgstr_rect(&r
));
3359 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3360 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3361 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3362 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3363 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3364 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3365 IDirectDrawSurface_Release(primary
);
3367 memset(&ddsd
, 0, sizeof(ddsd
));
3368 ddsd
.dwSize
= sizeof(ddsd
);
3369 ddsd
.dwFlags
= DDSD_CAPS
;
3370 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3372 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3373 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3374 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3375 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3376 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3377 param
.ddraw_width
, ddsd
.dwWidth
);
3378 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3379 param
.ddraw_height
, ddsd
.dwHeight
);
3381 GetWindowRect(window
, &r
);
3383 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3384 wine_dbgstr_rect(&r
));
3386 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3387 expect_messages
= normal_messages
;
3391 hr
= IDirectDrawSurface_IsLost(primary
);
3392 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3393 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3394 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3395 hr
= IDirectDrawSurface_IsLost(primary
);
3396 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3398 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3399 expect_messages
= NULL
;
3400 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3402 GetWindowRect(window
, &r
);
3404 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3405 wine_dbgstr_rect(&r
));
3407 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3408 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3409 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3410 param
.ddraw_width
, ddsd
.dwWidth
);
3411 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3412 param
.ddraw_height
, ddsd
.dwHeight
);
3413 IDirectDrawSurface_Release(primary
);
3415 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3416 ok(ret
, "Failed to get display mode.\n");
3417 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3418 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3419 "Expected resolution %lux%lu, got %lux%lu.\n",
3420 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3421 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3422 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3423 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3425 memset(&ddsd
, 0, sizeof(ddsd
));
3426 ddsd
.dwSize
= sizeof(ddsd
);
3427 ddsd
.dwFlags
= DDSD_CAPS
;
3428 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3430 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3431 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3432 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3433 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3434 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3435 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3436 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3437 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3439 GetWindowRect(window
, &r
);
3441 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3442 wine_dbgstr_rect(&r
));
3444 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3445 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3446 * not DDSCL_FULLSCREEN. */
3447 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3448 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3450 GetWindowRect(window
, &r
);
3452 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3453 wine_dbgstr_rect(&r
));
3455 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3456 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3457 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3458 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3459 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3460 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3461 IDirectDrawSurface_Release(primary
);
3463 memset(&ddsd
, 0, sizeof(ddsd
));
3464 ddsd
.dwSize
= sizeof(ddsd
);
3465 ddsd
.dwFlags
= DDSD_CAPS
;
3466 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3468 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3469 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3470 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3471 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3472 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3473 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3474 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3475 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3477 GetWindowRect(window
, &r
);
3479 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3480 wine_dbgstr_rect(&r
));
3482 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3483 expect_messages
= normal_messages
;
3487 hr
= IDirectDrawSurface_IsLost(primary
);
3488 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3489 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3490 devmode
.dmPelsWidth
= param
.user32_width
;
3491 devmode
.dmPelsHeight
= param
.user32_height
;
3492 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3493 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3494 hr
= IDirectDrawSurface_IsLost(primary
);
3495 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3497 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3498 expect_messages
= NULL
;
3499 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3501 GetWindowRect(window
, &r
);
3503 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3504 wine_dbgstr_rect(&r
));
3506 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3507 expect_messages
= normal_messages
;
3511 hr
= IDirectDrawSurface_Restore(primary
);
3512 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3513 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3514 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3515 hr
= IDirectDrawSurface_Restore(primary
);
3516 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
3517 hr
= IDirectDrawSurface_IsLost(primary
);
3518 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3520 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3521 expect_messages
= NULL
;
3522 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3524 GetWindowRect(window
, &r
);
3526 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3527 wine_dbgstr_rect(&r
));
3529 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3530 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3531 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3532 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3533 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3534 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3535 IDirectDrawSurface_Release(primary
);
3537 memset(&ddsd
, 0, sizeof(ddsd
));
3538 ddsd
.dwSize
= sizeof(ddsd
);
3539 ddsd
.dwFlags
= DDSD_CAPS
;
3540 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3542 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3543 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3544 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3545 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3546 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3547 param
.ddraw_width
, ddsd
.dwWidth
);
3548 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3549 param
.ddraw_height
, ddsd
.dwHeight
);
3551 GetWindowRect(window
, &r
);
3553 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3554 wine_dbgstr_rect(&r
));
3556 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3557 expect_messages
= normal_messages
;
3561 hr
= IDirectDrawSurface_IsLost(primary
);
3562 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
3563 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3564 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3565 hr
= IDirectDrawSurface_IsLost(primary
);
3566 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
3568 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3569 expect_messages
= NULL
;
3570 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %lux%lu.\n", screen_size
.cx
, screen_size
.cy
);
3572 GetWindowRect(window
, &r
);
3574 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3575 wine_dbgstr_rect(&r
));
3577 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3578 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3579 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3580 param
.ddraw_width
, ddsd
.dwWidth
);
3581 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3582 param
.ddraw_height
, ddsd
.dwHeight
);
3583 IDirectDrawSurface_Release(primary
);
3585 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3586 ok(ret
, "Failed to get display mode.\n");
3587 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3588 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3589 "Expected resolution %lux%lu, got %lux%lu.\n",
3590 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3591 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3592 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3593 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3595 memset(&ddsd
, 0, sizeof(ddsd
));
3596 ddsd
.dwSize
= sizeof(ddsd
);
3597 ddsd
.dwFlags
= DDSD_CAPS
;
3598 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3600 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3601 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3602 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3603 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3604 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %lu, got %lu.\n",
3605 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3606 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %lu, got %lu.\n",
3607 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3608 IDirectDrawSurface_Release(primary
);
3610 GetWindowRect(window
, &r
);
3612 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3613 wine_dbgstr_rect(&r
));
3615 /* Unlike ddraw2-7, changing from EXCLUSIVE to NORMAL does not restore the resolution */
3616 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3617 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3618 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3619 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3621 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3622 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3624 memset(&ddsd
, 0, sizeof(ddsd
));
3625 ddsd
.dwSize
= sizeof(ddsd
);
3626 ddsd
.dwFlags
= DDSD_CAPS
;
3627 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3629 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3630 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
3631 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
3632 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
3633 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %lu, got %lu.\n",
3634 param
.ddraw_width
, ddsd
.dwWidth
);
3635 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %lu, got %lu.\n",
3636 param
.ddraw_height
, ddsd
.dwHeight
);
3637 IDirectDrawSurface_Release(primary
);
3638 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3639 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3641 ref
= IDirectDraw_Release(ddraw
);
3642 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3644 GetWindowRect(window
, &r
);
3645 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3646 wine_dbgstr_rect(&r
));
3648 ret
= restore_display_modes(original_modes
, display_count
);
3649 ok(ret
, "Failed to restore display modes.\n");
3651 /* Test that no mode restorations if no mode changes happened */
3652 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3653 devmode
.dmPelsWidth
= param
.user32_width
;
3654 devmode
.dmPelsHeight
= param
.user32_height
;
3655 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3656 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3658 ddraw
= create_ddraw();
3659 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3660 ref
= IDirectDraw_Release(ddraw
);
3661 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3663 memset(&devmode2
, 0, sizeof(devmode2
));
3664 devmode2
.dmSize
= sizeof(devmode2
);
3665 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3666 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3667 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3668 ret
= restore_display_modes(original_modes
, display_count
);
3669 ok(ret
, "Failed to restore display modes.\n");
3671 /* Test that no mode restorations if no mode changes happened with fullscreen ddraw objects */
3672 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3673 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3675 ddraw
= create_ddraw();
3676 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3677 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3678 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3679 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3680 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3681 ref
= IDirectDraw_Release(ddraw
);
3682 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3684 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3685 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3686 ok(compare_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
3687 ret
= restore_display_modes(original_modes
, display_count
);
3688 ok(ret
, "Failed to restore display modes.\n");
3690 /* Test that mode restorations use display settings in the registry after ddraw object releases
3691 * if SetDisplayMode() was called */
3692 ddraw
= create_ddraw();
3693 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3694 hr
= set_display_mode(ddraw
, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
3695 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3697 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3698 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3700 ref
= IDirectDraw_Release(ddraw
);
3701 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3703 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3704 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3705 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3706 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3707 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3708 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3709 ret
= restore_display_modes(original_modes
, display_count
);
3710 ok(ret
, "Failed to restore display modes.\n");
3712 /* Test that mode restorations use display settings in the registry after RestoreDisplayMode() */
3713 ddraw
= create_ddraw();
3714 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3715 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3716 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
3718 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
3719 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
3721 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
3722 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
3724 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3725 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3726 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3727 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
3728 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3729 ok(compare_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
3731 ref
= IDirectDraw_Release(ddraw
);
3732 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3735 expect_messages
= NULL
;
3736 DestroyWindow(window
);
3737 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3738 ret
= restore_display_modes(original_modes
, display_count
);
3739 ok(ret
, "Failed to restore display modes.\n");
3740 free(original_modes
);
3743 static void test_coop_level_mode_set_multi(void)
3745 DEVMODEW old_devmode
, devmode
, devmode2
, devmode3
, *original_modes
= NULL
;
3746 unsigned int mode_idx
= 0, display_idx
, display_count
= 0;
3747 WCHAR second_monitor_name
[CCHDEVICENAME
];
3748 IDirectDraw
*ddraw1
, *ddraw2
;
3756 memset(&devmode
, 0, sizeof(devmode
));
3757 devmode
.dmSize
= sizeof(devmode
);
3758 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3759 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3760 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3761 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
3762 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3763 ok(compare_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
3765 ret
= save_display_modes(&original_modes
, &display_count
);
3766 ok(ret
, "Failed to save original display modes.\n");
3768 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3769 0, 0, 100, 100, 0, 0, 0, 0);
3770 ddraw1
= create_ddraw();
3771 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3773 /* With just a single ddraw object, the display mode is restored on
3775 hr
= set_display_mode(ddraw1
, 800, 600);
3776 if (hr
== DDERR_NOEXCLUSIVEMODE
/* NT4 testbot */)
3778 win_skip("Broken SetDisplayMode(), skipping test.\n");
3779 IDirectDraw_Release(ddraw1
);
3780 DestroyWindow(window
);
3783 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3784 w
= GetSystemMetrics(SM_CXSCREEN
);
3785 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3786 h
= GetSystemMetrics(SM_CYSCREEN
);
3787 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3789 ref
= IDirectDraw_Release(ddraw1
);
3790 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3791 w
= GetSystemMetrics(SM_CXSCREEN
);
3792 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3793 h
= GetSystemMetrics(SM_CYSCREEN
);
3794 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3796 /* When there are multiple ddraw objects, the display mode is restored to
3797 * the initial mode, before the first SetDisplayMode() call. */
3798 ddraw1
= create_ddraw();
3799 hr
= set_display_mode(ddraw1
, 800, 600);
3800 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3801 w
= GetSystemMetrics(SM_CXSCREEN
);
3802 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3803 h
= GetSystemMetrics(SM_CYSCREEN
);
3804 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3806 ddraw2
= create_ddraw();
3807 hr
= set_display_mode(ddraw2
, 640, 480);
3808 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3809 w
= GetSystemMetrics(SM_CXSCREEN
);
3810 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3811 h
= GetSystemMetrics(SM_CYSCREEN
);
3812 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3814 ref
= IDirectDraw_Release(ddraw2
);
3815 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3816 w
= GetSystemMetrics(SM_CXSCREEN
);
3817 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3818 h
= GetSystemMetrics(SM_CYSCREEN
);
3819 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3821 ref
= IDirectDraw_Release(ddraw1
);
3822 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3823 w
= GetSystemMetrics(SM_CXSCREEN
);
3824 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3825 h
= GetSystemMetrics(SM_CYSCREEN
);
3826 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3828 /* Regardless of release ordering. */
3829 ddraw1
= create_ddraw();
3830 hr
= set_display_mode(ddraw1
, 800, 600);
3831 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3832 w
= GetSystemMetrics(SM_CXSCREEN
);
3833 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3834 h
= GetSystemMetrics(SM_CYSCREEN
);
3835 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3837 ddraw2
= create_ddraw();
3838 hr
= set_display_mode(ddraw2
, 640, 480);
3839 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3840 w
= GetSystemMetrics(SM_CXSCREEN
);
3841 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3842 h
= GetSystemMetrics(SM_CYSCREEN
);
3843 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3845 ref
= IDirectDraw_Release(ddraw1
);
3846 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3847 w
= GetSystemMetrics(SM_CXSCREEN
);
3848 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3849 h
= GetSystemMetrics(SM_CYSCREEN
);
3850 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3852 ref
= IDirectDraw_Release(ddraw2
);
3853 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3854 w
= GetSystemMetrics(SM_CXSCREEN
);
3855 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3856 h
= GetSystemMetrics(SM_CYSCREEN
);
3857 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3859 /* But only for ddraw objects that called SetDisplayMode(). */
3860 ddraw1
= create_ddraw();
3861 ddraw2
= create_ddraw();
3862 hr
= set_display_mode(ddraw2
, 640, 480);
3863 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3864 w
= GetSystemMetrics(SM_CXSCREEN
);
3865 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3866 h
= GetSystemMetrics(SM_CYSCREEN
);
3867 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3869 ref
= IDirectDraw_Release(ddraw1
);
3870 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3871 w
= GetSystemMetrics(SM_CXSCREEN
);
3872 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3873 h
= GetSystemMetrics(SM_CYSCREEN
);
3874 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3876 ref
= IDirectDraw_Release(ddraw2
);
3877 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3878 w
= GetSystemMetrics(SM_CXSCREEN
);
3879 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3880 h
= GetSystemMetrics(SM_CYSCREEN
);
3881 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3883 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3884 * restoring the display mode. */
3885 ddraw1
= create_ddraw();
3886 hr
= set_display_mode(ddraw1
, 800, 600);
3887 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3888 w
= GetSystemMetrics(SM_CXSCREEN
);
3889 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3890 h
= GetSystemMetrics(SM_CYSCREEN
);
3891 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3893 ddraw2
= create_ddraw();
3894 hr
= set_display_mode(ddraw2
, 640, 480);
3895 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3896 w
= GetSystemMetrics(SM_CXSCREEN
);
3897 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3898 h
= GetSystemMetrics(SM_CYSCREEN
);
3899 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3901 hr
= IDirectDraw_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3902 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3904 ref
= IDirectDraw_Release(ddraw1
);
3905 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3906 w
= GetSystemMetrics(SM_CXSCREEN
);
3907 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3908 h
= GetSystemMetrics(SM_CYSCREEN
);
3909 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3911 ref
= IDirectDraw_Release(ddraw2
);
3912 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3913 w
= GetSystemMetrics(SM_CXSCREEN
);
3914 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3915 h
= GetSystemMetrics(SM_CYSCREEN
);
3916 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3918 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3919 ddraw1
= create_ddraw();
3920 hr
= set_display_mode(ddraw1
, 800, 600);
3921 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
3922 w
= GetSystemMetrics(SM_CXSCREEN
);
3923 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3924 h
= GetSystemMetrics(SM_CYSCREEN
);
3925 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3927 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3928 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3930 ddraw2
= create_ddraw();
3931 hr
= set_display_mode(ddraw2
, 640, 480);
3932 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
3934 ref
= IDirectDraw_Release(ddraw1
);
3935 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3936 w
= GetSystemMetrics(SM_CXSCREEN
);
3937 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3938 h
= GetSystemMetrics(SM_CYSCREEN
);
3939 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3941 ref
= IDirectDraw_Release(ddraw2
);
3942 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
3943 w
= GetSystemMetrics(SM_CXSCREEN
);
3944 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3945 h
= GetSystemMetrics(SM_CYSCREEN
);
3946 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3948 if (display_count
< 2)
3950 skip("Following tests require two monitors.\n");
3954 ret
= restore_display_modes(original_modes
, display_count
);
3955 ok(ret
, "Failed to restore display modes.\n");
3957 second_monitor_name
[0] = '\0';
3958 for (display_idx
= 0; display_idx
< display_count
; ++display_idx
)
3960 if (original_modes
[display_idx
].dmPosition
.x
|| original_modes
[display_idx
].dmPosition
.y
)
3962 lstrcpyW(second_monitor_name
, original_modes
[display_idx
].dmDeviceName
);
3966 ok(lstrlenW(second_monitor_name
), "Got an empty second monitor name.\n");
3967 memset(&old_devmode
, 0, sizeof(old_devmode
));
3968 old_devmode
.dmSize
= sizeof(old_devmode
);
3969 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
3970 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3972 devmode
= old_devmode
;
3973 while (EnumDisplaySettingsW(second_monitor_name
, mode_idx
++, &devmode
))
3975 if (devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3976 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
)
3979 ok(devmode
.dmPelsWidth
!= old_devmode
.dmPelsWidth
3980 || devmode
.dmPelsHeight
!= old_devmode
.dmPelsHeight
,
3981 "Failed to find a different mode for the second monitor.\n");
3983 /* Test that no mode restorations for non-primary monitors if SetDisplayMode() was not called */
3984 ddraw1
= create_ddraw();
3985 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3986 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3987 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
3989 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
3990 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
3992 memset(&devmode2
, 0, sizeof(devmode2
));
3993 devmode2
.dmSize
= sizeof(devmode2
);
3994 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
3995 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
3996 if (compare_mode_rect(&devmode2
, &old_devmode
))
3998 skip("Failed to change display settings of the second monitor.\n");
3999 ref
= IDirectDraw_Release(ddraw1
);
4000 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4004 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_NORMAL
);
4005 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
4006 ref
= IDirectDraw_Release(ddraw1
);
4007 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4009 memset(&devmode3
, 0, sizeof(devmode3
));
4010 devmode3
.dmSize
= sizeof(devmode3
);
4011 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode3
);
4012 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4013 ok(compare_mode_rect(&devmode3
, &devmode2
), "Got a different mode.\n");
4014 ret
= restore_display_modes(original_modes
, display_count
);
4015 ok(ret
, "Failed to restore display modes.\n");
4017 /* Test that mode restorations happen for non-primary monitors on ddraw releases if
4018 * SetDisplayMode() was called */
4019 ddraw1
= create_ddraw();
4020 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4021 hr
= set_display_mode(ddraw1
, 800, 600);
4022 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4024 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4025 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4027 ref
= IDirectDraw_Release(ddraw1
);
4028 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4030 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4031 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4032 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4033 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4034 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4035 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4036 ret
= restore_display_modes(original_modes
, display_count
);
4037 ok(ret
, "Failed to restore display modes.\n");
4039 /* Test that mode restorations happen for non-primary monitors as well */
4040 ddraw1
= create_ddraw();
4041 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4042 hr
= set_display_mode(ddraw1
, 800, 600);
4043 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4045 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4046 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4048 hr
= IDirectDraw_RestoreDisplayMode(ddraw1
);
4049 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4051 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4052 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4053 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4054 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4055 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4056 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4058 ref
= IDirectDraw_Release(ddraw1
);
4059 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4060 ret
= restore_display_modes(original_modes
, display_count
);
4061 ok(ret
, "Failed to restore display modes.\n");
4063 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4064 ddraw1
= create_ddraw();
4065 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4066 hr
= set_display_mode(ddraw1
, 800, 600);
4067 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4069 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4070 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4071 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4073 ref
= IDirectDraw_Release(ddraw1
);
4074 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4076 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4077 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4078 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4079 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4080 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4081 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4082 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4083 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4084 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4085 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4086 ret
= restore_display_modes(original_modes
, display_count
);
4087 ok(ret
, "Failed to restore display modes.\n");
4089 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4090 * objects and one of them restores display mode */
4091 ddraw1
= create_ddraw();
4092 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4093 ddraw2
= create_ddraw();
4094 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4095 hr
= set_display_mode(ddraw1
, 800, 600);
4096 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4097 hr
= set_display_mode(ddraw2
, 640, 480);
4098 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4100 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4101 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4103 hr
= IDirectDraw_RestoreDisplayMode(ddraw2
);
4104 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
4106 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4107 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4108 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4109 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4110 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4111 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4113 ref
= IDirectDraw_Release(ddraw2
);
4114 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4115 ref
= IDirectDraw_Release(ddraw1
);
4116 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4117 ret
= restore_display_modes(original_modes
, display_count
);
4118 ok(ret
, "Failed to restore display modes.\n");
4120 /* Test mode restorations for non-primary monitors when there are multiple fullscreen ddraw
4121 * objects and one of them got released */
4122 ddraw1
= create_ddraw();
4123 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
4124 ddraw2
= create_ddraw();
4125 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
4126 hr
= set_display_mode(ddraw1
, 800, 600);
4127 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4128 hr
= set_display_mode(ddraw2
, 640, 480);
4129 ok(hr
== DD_OK
, "Failed to set display mode, hr %#lx.\n", hr
);
4131 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4132 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4134 ref
= IDirectDraw_Release(ddraw2
);
4135 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4137 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4138 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4139 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4140 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4141 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
4142 ok(compare_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4144 ref
= IDirectDraw_Release(ddraw1
);
4145 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
4148 DestroyWindow(window
);
4149 ret
= restore_display_modes(original_modes
, display_count
);
4150 ok(ret
, "Failed to restore display modes.\n");
4151 free(original_modes
);
4154 static void test_initialize(void)
4160 ddraw
= create_ddraw();
4161 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4163 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4164 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx.\n", hr
);
4165 IDirectDraw_Release(ddraw
);
4168 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw
, (void **)&ddraw
);
4169 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw instance, hr %#lx.\n", hr
);
4170 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
4173 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
4174 hr
= IDirect3D_Initialize(d3d
, NULL
);
4175 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4176 IDirect3D_Release(d3d
);
4179 skip("D3D interface is not available, skipping test.\n");
4180 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4181 ok(hr
== DD_OK
, "Initialize returned hr %#lx, expected DD_OK.\n", hr
);
4182 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
4183 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#lx, expected DDERR_ALREADYINITIALIZED.\n", hr
);
4184 IDirectDraw_Release(ddraw
);
4187 if (0) /* This crashes on the W2KPROSP4 testbot. */
4190 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirect3D
, (void **)&d3d
);
4191 ok(hr
== E_NOINTERFACE
, "CoCreateInstance returned hr %#lx, expected E_NOINTERFACE.\n", hr
);
4196 static void test_coop_level_surf_create(void)
4198 IDirectDrawSurface
*surface
;
4203 ddraw
= create_ddraw();
4204 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4206 memset(&ddsd
, 0, sizeof(ddsd
));
4207 ddsd
.dwSize
= sizeof(ddsd
);
4208 ddsd
.dwFlags
= DDSD_CAPS
;
4209 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
4210 surface
= (void *)0xdeadbeef;
4211 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4212 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4213 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4215 surface
= (void *)0xdeadbeef;
4216 hr
= IDirectDraw_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4217 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#lx.\n", hr
);
4218 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4220 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4221 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4223 surface
= (void *)0xdeadbeef;
4224 hr
= IDirectDraw_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
4225 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#lx.\n", hr
);
4226 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
4228 IDirectDraw_Release(ddraw
);
4231 static void test_coop_level_multi_window(void)
4233 HWND window1
, window2
;
4237 window1
= create_window();
4238 window2
= create_window();
4239 ddraw
= create_ddraw();
4240 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4242 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
4243 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4244 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
4245 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4246 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
4247 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
4249 IDirectDraw_Release(ddraw
);
4250 DestroyWindow(window2
);
4251 DestroyWindow(window1
);
4254 static void test_clear_rect_count(void)
4256 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4257 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
4258 IDirect3DViewport
*viewport
;
4259 IDirect3DDevice
*device
;
4260 IDirectDrawSurface
*rt
;
4266 window
= create_window();
4267 ddraw
= create_ddraw();
4268 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4269 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4271 skip("Failed to create a 3D device, skipping test.\n");
4272 IDirectDraw_Release(ddraw
);
4273 DestroyWindow(window
);
4277 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
4278 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
4280 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
4281 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
4282 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
4283 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
4284 viewport
= create_viewport(device
, 0, 0, 640, 480);
4286 viewport_set_background(device
, viewport
, white
);
4287 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
4288 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4289 viewport_set_background(device
, viewport
, red
);
4290 hr
= IDirect3DViewport_Clear(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
);
4291 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4292 viewport_set_background(device
, viewport
, green
);
4293 hr
= IDirect3DViewport_Clear(viewport
, 0, NULL
, D3DCLEAR_TARGET
);
4294 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4295 viewport_set_background(device
, viewport
, blue
);
4296 hr
= IDirect3DViewport_Clear(viewport
, 1, NULL
, D3DCLEAR_TARGET
);
4297 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
4299 color
= get_surface_color(rt
, 320, 240);
4300 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4301 "Got unexpected color 0x%08x.\n", color
);
4303 IDirectDrawSurface_Release(rt
);
4304 destroy_viewport(device
, viewport
);
4305 destroy_material(white
);
4306 destroy_material(red
);
4307 destroy_material(green
);
4308 destroy_material(blue
);
4309 IDirect3DDevice_Release(device
);
4310 IDirectDraw_Release(ddraw
);
4311 DestroyWindow(window
);
4320 } activateapp_testdata
;
4322 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4324 if (message
== WM_ACTIVATEAPP
)
4326 if (activateapp_testdata
.ddraw
)
4329 activateapp_testdata
.received
= FALSE
;
4330 hr
= IDirectDraw_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4331 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4332 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#lx.\n", hr
);
4333 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4335 activateapp_testdata
.received
= TRUE
;
4338 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4341 static void test_coop_level_activateapp(void)
4348 IDirectDrawSurface
*surface
;
4350 ddraw
= create_ddraw();
4351 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4353 wc
.lpfnWndProc
= activateapp_test_proc
;
4354 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4355 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4357 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4358 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4360 /* Exclusive with window already active. */
4361 SetForegroundWindow(window
);
4362 activateapp_testdata
.received
= FALSE
;
4363 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4364 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4365 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4366 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4367 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4369 /* Exclusive with window not active. */
4370 SetForegroundWindow(GetDesktopWindow());
4371 activateapp_testdata
.received
= FALSE
;
4372 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4373 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4374 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4375 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4376 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4378 /* Normal with window not active, then exclusive with the same window. */
4379 SetForegroundWindow(GetDesktopWindow());
4380 activateapp_testdata
.received
= FALSE
;
4381 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4382 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4383 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4384 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4385 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4386 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4387 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4388 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4390 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4391 SetForegroundWindow(GetDesktopWindow());
4392 activateapp_testdata
.received
= FALSE
;
4393 activateapp_testdata
.ddraw
= ddraw
;
4394 activateapp_testdata
.window
= window
;
4395 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4396 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4397 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4398 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4399 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4400 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4402 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4403 * succeeding. Another switch to exclusive and back to normal is needed to release the
4404 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4405 * WM_ACTIVATEAPP messages. */
4406 activateapp_testdata
.ddraw
= NULL
;
4407 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4408 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4409 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4410 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4412 /* Setting DDSCL_NORMAL with recursive invocation. */
4413 SetForegroundWindow(GetDesktopWindow());
4414 activateapp_testdata
.received
= FALSE
;
4415 activateapp_testdata
.ddraw
= ddraw
;
4416 activateapp_testdata
.window
= window
;
4417 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4418 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4419 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4420 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4422 /* DDraw is in exclusive mode now. */
4423 memset(&ddsd
, 0, sizeof(ddsd
));
4424 ddsd
.dwSize
= sizeof(ddsd
);
4425 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4426 ddsd
.dwBackBufferCount
= 1;
4427 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4428 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4429 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
4430 IDirectDrawSurface_Release(surface
);
4432 /* Recover again, just to be sure. */
4433 activateapp_testdata
.ddraw
= NULL
;
4434 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4435 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4436 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4437 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4439 DestroyWindow(window
);
4440 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4441 IDirectDraw_Release(ddraw
);
4444 struct format_support_check
4446 const DDPIXELFORMAT
*format
;
4450 static HRESULT WINAPI
test_unsupported_formats_cb(DDSURFACEDESC
*desc
, void *ctx
)
4452 struct format_support_check
*format
= ctx
;
4454 if (!memcmp(format
->format
, &desc
->ddpfPixelFormat
, sizeof(*format
->format
)))
4456 format
->supported
= TRUE
;
4457 return DDENUMRET_CANCEL
;
4460 return DDENUMRET_OK
;
4463 static void test_unsupported_formats(void)
4466 BOOL expect_success
;
4469 IDirect3DDevice
*device
;
4470 IDirectDrawSurface
*surface
;
4473 DWORD expected_caps
;
4484 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
4485 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
4491 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4492 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
4496 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
4498 window
= create_window();
4499 ddraw
= create_ddraw();
4500 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4501 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
4503 skip("Failed to create a 3D device, skipping test.\n");
4504 IDirectDraw_Release(ddraw
);
4505 DestroyWindow(window
);
4509 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
4511 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
4512 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
4513 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
4515 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
4517 memset(&ddsd
, 0, sizeof(ddsd
));
4518 ddsd
.dwSize
= sizeof(ddsd
);
4519 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
4520 ddsd
.ddpfPixelFormat
= formats
[i
].fmt
;
4523 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
4525 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
4526 expect_success
= FALSE
;
4528 expect_success
= TRUE
;
4530 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4531 ok(SUCCEEDED(hr
) == expect_success
,
4532 "Got unexpected hr %#lx for format %s, caps %#lx, expected %s.\n",
4533 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
4537 memset(&ddsd
, 0, sizeof(ddsd
));
4538 ddsd
.dwSize
= sizeof(ddsd
);
4539 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &ddsd
);
4540 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
4542 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
4543 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4544 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
4545 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4546 else if (check
.supported
)
4547 expected_caps
= DDSCAPS_VIDEOMEMORY
;
4549 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
4551 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
4552 "Expected caps %#lx, format %s, input caps %#lx.\n",
4553 expected_caps
, formats
[i
].name
, caps
[j
]);
4555 IDirectDrawSurface_Release(surface
);
4559 IDirect3DDevice_Release(device
);
4560 IDirectDraw_Release(ddraw
);
4561 DestroyWindow(window
);
4564 static void test_rt_caps(const GUID
*device_guid
)
4566 DWORD fourcc_codes
[64], fourcc_code_count
;
4567 PALETTEENTRY palette_entries
[256];
4568 IDirectDrawPalette
*palette
;
4569 IDirect3DDevice
*device
;
4570 BOOL software_device
;
4579 static const DDPIXELFORMAT p8_fmt
=
4581 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
4582 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
4584 static const DDPIXELFORMAT fourcc_fmt
=
4586 .dwSize
= sizeof(DDPIXELFORMAT
),
4587 .dwFlags
= DDPF_FOURCC
,
4588 .dwFourCC
= MAKEFOURCC('Y','U','Y','2'),
4593 const DDPIXELFORMAT
*pf
;
4595 HRESULT create_device_hr
;
4596 BOOL create_may_fail
;
4602 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4608 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4614 DDSCAPS_OFFSCREENPLAIN
,
4620 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4621 D3DERR_SURFACENOTINVIDMEM
,
4626 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4632 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
4650 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4651 D3DERR_SURFACENOTINVIDMEM
,
4656 DDSCAPS_SYSTEMMEMORY
,
4668 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
4669 DDERR_NOPALETTEATTACHED
,
4674 DDSCAPS_OFFSCREENPLAIN
,
4680 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
4681 DDERR_NOPALETTEATTACHED
,
4686 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
4692 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
4694 TRUE
/* AMD Evergreen */,
4698 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4710 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
4712 TRUE
/* Nvidia Kepler */,
4716 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
4718 TRUE
/* Nvidia Kepler */,
4722 DDSCAPS_FLIP
| DDSCAPS_COMPLEX
| DDSCAPS_OFFSCREENPLAIN
,
4728 software_device
= is_software_device_type(device_guid
);
4730 window
= create_window();
4731 ddraw
= create_ddraw();
4732 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4733 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
4735 skip("Failed to create a 3D device, skipping test.\n");
4736 IDirectDraw_Release(ddraw
);
4737 DestroyWindow(window
);
4740 z_depth
= get_device_z_depth(device
);
4741 ok(!!z_depth
, "Failed to get device z depth.\n");
4742 IDirect3DDevice_Release(device
);
4744 memset(palette_entries
, 0, sizeof(palette_entries
));
4745 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
4746 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
4748 memset(&hal_caps
, 0, sizeof(hal_caps
));
4749 hal_caps
.dwSize
= sizeof(hal_caps
);
4750 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
4751 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
4753 fourcc_code_count
= ARRAY_SIZE(fourcc_codes
);
4754 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &fourcc_code_count
, fourcc_codes
);
4755 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
4757 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4759 DWORD caps_in
, expected_caps
;
4760 IDirectDrawSurface
*surface
;
4761 DDSURFACEDESC surface_desc
;
4762 IDirect3DDevice
*device
;
4763 HRESULT expected_hr
;
4765 caps_in
= test_data
[i
].caps_in
;
4767 memset(&surface_desc
, 0, sizeof(surface_desc
));
4768 surface_desc
.dwSize
= sizeof(surface_desc
);
4769 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
4770 surface_desc
.ddsCaps
.dwCaps
= caps_in
;
4771 if (test_data
[i
].pf
)
4773 if (test_data
[i
].pf
->dwFlags
& DDPF_FOURCC
)
4777 for (j
= 0; j
< fourcc_code_count
; ++j
)
4779 if (test_data
[i
].pf
->dwFourCC
== fourcc_codes
[j
])
4782 if (j
== fourcc_code_count
)
4784 skip("Fourcc format %#lx is not supported, skipping test.\n", test_data
[i
].pf
->dwFourCC
);
4788 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
4789 surface_desc
.ddpfPixelFormat
= *test_data
[i
].pf
;
4791 if (caps_in
& DDSCAPS_ZBUFFER
)
4793 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
4794 surface_desc
.dwZBufferBitDepth
= z_depth
;
4796 if (caps_in
& DDSCAPS_FLIP
)
4798 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4799 surface_desc
.dwBackBufferCount
= 1;
4801 surface_desc
.dwWidth
= 640;
4802 surface_desc
.dwHeight
= 480;
4803 if ((caps_in
& DDSCAPS_VIDEOMEMORY
) && !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
4804 expected_hr
= DDERR_NODIRECTDRAWHW
;
4806 expected_hr
= DD_OK
;
4807 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
4808 ok(hr
== expected_hr
|| broken(test_data
[i
].create_may_fail
4809 || (software_device
&& test_data
[i
].pf
== &p8_fmt
&& hr
== DDERR_INVALIDPIXELFORMAT
)),
4810 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4814 memset(&surface_desc
, 0, sizeof(surface_desc
));
4815 surface_desc
.dwSize
= sizeof(surface_desc
);
4816 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
4817 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4819 if ((caps_in
& DDSCAPS_SYSTEMMEMORY
) || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
4820 expected_caps
= caps_in
| DDSCAPS_SYSTEMMEMORY
;
4822 expected_caps
= caps_in
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
;
4824 if (caps_in
& DDSCAPS_FLIP
)
4825 expected_caps
|= DDSCAPS_FRONTBUFFER
;
4827 ok(surface_desc
.ddsCaps
.dwCaps
== expected_caps
|| (test_data
[i
].pf
== &p8_fmt
4828 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
))
4829 || (software_device
&& caps_in
& DDSCAPS_ZBUFFER
4830 && surface_desc
.ddsCaps
.dwCaps
== (caps_in
| DDSCAPS_SYSTEMMEMORY
)),
4831 "Got unexpected caps %#lx, expected %#lx, test %u, software_device %u.\n",
4832 surface_desc
.ddsCaps
.dwCaps
, expected_caps
, i
, software_device
);
4834 hr
= IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
);
4835 ok((!software_device
&& hr
== test_data
[i
].create_device_hr
)
4836 || (software_device
&& (hr
== (test_data
[i
].create_device_hr
== D3DERR_SURFACENOTINVIDMEM
4837 ? DD_OK
: test_data
[i
].create_device_hr
))),
4838 "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4839 if (hr
== DDERR_NOPALETTEATTACHED
)
4841 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
4842 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n", hr
, i
, software_device
);
4843 hr
= IDirectDrawSurface_QueryInterface(surface
, device_guid
, (void **)&device
);
4844 if (software_device
)
4846 ok(hr
== DD_OK
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4847 hr
, i
, software_device
);
4848 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
4849 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4850 hr
, i
, software_device
);
4852 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Got unexpected hr %#lx, test %u, software_device %u.\n",
4853 hr
, i
, software_device
);
4857 refcount
= IDirect3DDevice_Release(device
);
4858 ok(refcount
== 1, "Test %u: Got unexpected refcount %lu.\n", i
, refcount
);
4861 refcount
= IDirectDrawSurface_Release(surface
);
4862 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
4865 IDirectDrawPalette_Release(palette
);
4866 refcount
= IDirectDraw_Release(ddraw
);
4867 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
4868 DestroyWindow(window
);
4871 static void test_primary_caps(void)
4873 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
4874 IDirectDrawSurface
*surface
;
4875 DDSURFACEDESC surface_desc
;
4886 DWORD back_buffer_count
;
4894 DDSCAPS_PRIMARYSURFACE
,
4897 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
4901 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
4908 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4911 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
4915 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
4922 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
4929 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
4936 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4943 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4950 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4952 DDERR_NOEXCLUSIVEMODE
,
4956 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4957 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4963 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4964 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
4967 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
4970 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4971 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
4977 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
4978 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
4985 window
= create_window();
4986 ddraw
= create_ddraw();
4987 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4989 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
4991 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
4992 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
4994 memset(&surface_desc
, 0, sizeof(surface_desc
));
4995 surface_desc
.dwSize
= sizeof(surface_desc
);
4996 surface_desc
.dwFlags
= DDSD_CAPS
;
4997 if (test_data
[i
].back_buffer_count
!= ~0u)
4998 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
4999 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5000 surface_desc
.dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5001 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5002 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
5006 memset(&surface_desc
, 0, sizeof(surface_desc
));
5007 surface_desc
.dwSize
= sizeof(surface_desc
);
5008 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
5009 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
5010 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5011 "Test %u: Got unexpected caps %#lx, expected %#lx.\n",
5012 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5014 IDirectDrawSurface_Release(surface
);
5017 refcount
= IDirectDraw_Release(ddraw
);
5018 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5019 DestroyWindow(window
);
5022 static void test_surface_lock(void)
5025 IDirectDrawSurface
*surface
;
5026 IDirect3DDevice
*device
;
5041 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5042 "videomemory offscreenplain"
5045 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5046 "systemmemory offscreenplain"
5049 DDSCAPS_PRIMARYSURFACE
,
5053 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5054 "videomemory texture"
5057 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5058 "systemmemory texture"
5061 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5070 window
= create_window();
5071 ddraw
= create_ddraw();
5072 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5073 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5075 skip("Failed to create a 3D device, skipping test.\n");
5076 IDirectDraw_Release(ddraw
);
5077 DestroyWindow(window
);
5080 z_depth
= get_device_z_depth(device
);
5081 ok(!!z_depth
, "Failed to get device z depth.\n");
5082 IDirect3DDevice_Release(device
);
5084 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5086 memset(&ddsd
, 0, sizeof(ddsd
));
5087 ddsd
.dwSize
= sizeof(ddsd
);
5088 ddsd
.dwFlags
= DDSD_CAPS
;
5089 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5091 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5095 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
5097 ddsd
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
5098 ddsd
.dwZBufferBitDepth
= z_depth
;
5100 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5102 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5103 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5105 memset(&ddsd
, 0, sizeof(ddsd
));
5106 ddsd
.dwSize
= sizeof(ddsd
);
5107 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5108 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5111 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5112 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#lx.\n", tests
[i
].name
, hr
);
5115 memset(&ddsd
, 0, sizeof(ddsd
));
5116 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5117 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, tests
[i
].name
);
5119 IDirectDrawSurface_Release(surface
);
5122 refcount
= IDirectDraw_Release(ddraw
);
5123 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5124 DestroyWindow(window
);
5127 static void test_surface_discard(void)
5130 IDirect3DDevice
*device
;
5134 IDirectDrawSurface
*surface
, *target
;
5143 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5144 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5145 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, TRUE
},
5146 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, FALSE
},
5150 window
= create_window();
5152 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5156 /* Sigh. Anything other than the first run of the loop randomly fails with
5157 * DDERR_SURFACELOST on my Radeon Pro 560 on Win10 19.09. Most of the time
5158 * the blit fails, but with sleeps added between surface creation and lock
5159 * the lock can fail too. Interestingly ddraw claims the render target has
5160 * been lost, not the test surface.
5162 * Recreating ddraw every iteration seems to fix this. */
5163 ddraw
= create_ddraw();
5164 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5165 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
5167 skip("Failed to create a 3D device, skipping test.\n");
5168 IDirectDraw_Release(ddraw
);
5169 DestroyWindow(window
);
5173 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void**)&target
);
5174 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
5176 memset(&ddsd
, 0, sizeof(ddsd
));
5177 ddsd
.dwSize
= sizeof(ddsd
);
5178 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5179 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
5182 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5185 skip("Failed to create surface, skipping.\n");
5189 memset(&ddsd
, 0, sizeof(ddsd
));
5190 ddsd
.dwSize
= sizeof(ddsd
);
5191 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
5192 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5193 addr
= ddsd
.lpSurface
;
5194 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5195 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5197 memset(&ddsd
, 0, sizeof(ddsd
));
5198 ddsd
.dwSize
= sizeof(ddsd
);
5199 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5200 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5201 discarded
= ddsd
.lpSurface
!= addr
;
5202 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5203 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5205 hr
= IDirectDrawSurface_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
5206 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
5208 memset(&ddsd
, 0, sizeof(ddsd
));
5209 ddsd
.dwSize
= sizeof(ddsd
);
5210 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
| DDLOCK_WAIT
, NULL
);
5211 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
5212 discarded
|= ddsd
.lpSurface
!= addr
;
5213 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
5214 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
5216 IDirectDrawSurface_Release(surface
);
5218 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
5219 * AMD r500, evergreen). Windows XP, at least on AMD r200, never changes the pointer. */
5220 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
5222 IDirectDrawSurface_Release(target
);
5223 IDirect3DDevice_Release(device
);
5224 IDirectDraw_Release(ddraw
);
5227 DestroyWindow(window
);
5230 static void test_flip(void)
5232 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5233 IDirectDrawSurface
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
5234 DDSCAPS caps
= {DDSCAPS_FLIP
};
5235 DDSURFACEDESC surface_desc
;
5236 unsigned int color
, i
;
5237 BOOL sysmem_primary
;
5239 DWORD expected_caps
;
5251 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
5252 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
5253 {"TEXTURE", DDSCAPS_TEXTURE
},
5256 window
= create_window();
5257 ddraw
= create_ddraw();
5258 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5260 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5261 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5263 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5265 /* Creating a flippable texture induces a BSoD on some versions of the
5266 * Intel graphics driver. At least Intel GMA 950 with driver version
5267 * 6.14.10.4926 on Windows XP SP3 is affected. */
5268 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
5270 win_skip("Skipping flippable texture test.\n");
5274 memset(&surface_desc
, 0, sizeof(surface_desc
));
5275 surface_desc
.dwSize
= sizeof(surface_desc
);
5276 surface_desc
.dwFlags
= DDSD_CAPS
;
5277 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
5278 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5279 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5280 surface_desc
.dwWidth
= 512;
5281 surface_desc
.dwHeight
= 512;
5282 surface_desc
.dwBackBufferCount
= 3;
5283 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5284 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5286 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
5287 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5288 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5289 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5291 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
5292 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
5293 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5294 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5296 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
5297 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
5298 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
5299 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5303 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
5304 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5305 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5306 ok(hr
== DD_OK
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5307 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5308 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5309 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5311 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5312 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5313 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#lx.\n", test_data
[i
].name
, hr
);
5314 hr
= IDirectDrawSurface_IsLost(frontbuffer
);
5315 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5316 hr
= restore_surfaces(ddraw
);
5317 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#lx.\n", test_data
[i
].name
, hr
);
5319 memset(&surface_desc
, 0, sizeof(surface_desc
));
5320 surface_desc
.dwSize
= sizeof(surface_desc
);
5321 hr
= IDirectDrawSurface_GetSurfaceDesc(frontbuffer
, &surface_desc
);
5322 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5323 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
5324 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
5325 expected_caps
|= DDSCAPS_VISIBLE
;
5326 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5327 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5328 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
5330 hr
= IDirectDrawSurface_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
5331 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5332 memset(&surface_desc
, 0, sizeof(surface_desc
));
5333 surface_desc
.dwSize
= sizeof(surface_desc
);
5334 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer1
, &surface_desc
);
5335 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5336 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5337 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5338 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
5339 expected_caps
|= DDSCAPS_BACKBUFFER
;
5340 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5341 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5343 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
5344 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5345 memset(&surface_desc
, 0, sizeof(surface_desc
));
5346 surface_desc
.dwSize
= sizeof(surface_desc
);
5347 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer2
, &surface_desc
);
5348 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5349 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5350 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5351 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
5352 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5353 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5355 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
5356 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5357 memset(&surface_desc
, 0, sizeof(surface_desc
));
5358 surface_desc
.dwSize
= sizeof(surface_desc
);
5359 hr
= IDirectDrawSurface_GetSurfaceDesc(backbuffer3
, &surface_desc
);
5360 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#lx.\n", test_data
[i
].name
, hr
);
5361 ok(!surface_desc
.dwBackBufferCount
, "%s: Got unexpected back buffer count %lu.\n",
5362 test_data
[i
].name
, surface_desc
.dwBackBufferCount
);
5363 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
5364 "%s: Got unexpected caps %#lx.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
5366 hr
= IDirectDrawSurface_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
5367 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5368 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
5369 test_data
[i
].name
, surface
, frontbuffer
);
5370 IDirectDrawSurface_Release(surface
);
5372 memset(&surface_desc
, 0, sizeof(surface_desc
));
5373 surface_desc
.dwSize
= sizeof(surface_desc
);
5374 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5375 surface_desc
.ddsCaps
.dwCaps
= 0;
5376 surface_desc
.dwWidth
= 640;
5377 surface_desc
.dwHeight
= 480;
5378 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5379 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#lx.\n", test_data
[i
].name
, hr
);
5380 hr
= IDirectDrawSurface_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
5381 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5382 IDirectDrawSurface_Release(surface
);
5384 hr
= IDirectDrawSurface_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
5385 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5386 hr
= IDirectDrawSurface_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
5387 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5388 hr
= IDirectDrawSurface_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
5389 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5390 hr
= IDirectDrawSurface_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
5391 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#lx.\n", test_data
[i
].name
, hr
);
5393 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
5394 * the backbuffer has been locked or GetSurfaceDesc has been called. Do it ourselves
5395 * as a workaround. */
5396 fill_surface(backbuffer1
, 0xffff0000);
5397 fill_surface(backbuffer2
, 0xff00ff00);
5398 fill_surface(backbuffer3
, 0xff0000ff);
5400 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5401 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5402 color
= get_surface_color(backbuffer1
, 320, 240);
5403 /* The testbot seems to just copy the contents of one surface to all the
5404 * others, instead of properly flipping. */
5405 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5406 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5407 color
= get_surface_color(backbuffer2
, 320, 240);
5408 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5409 fill_surface(backbuffer3
, 0xffff0000);
5411 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5412 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5413 color
= get_surface_color(backbuffer1
, 320, 240);
5414 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5415 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5416 color
= get_surface_color(backbuffer2
, 320, 240);
5417 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5418 fill_surface(backbuffer3
, 0xff00ff00);
5420 hr
= IDirectDrawSurface_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
5421 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5422 color
= get_surface_color(backbuffer1
, 320, 240);
5423 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5424 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5425 color
= get_surface_color(backbuffer2
, 320, 240);
5426 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5427 fill_surface(backbuffer3
, 0xff0000ff);
5429 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
5430 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5431 color
= get_surface_color(backbuffer2
, 320, 240);
5432 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
5433 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5434 color
= get_surface_color(backbuffer3
, 320, 240);
5435 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5436 fill_surface(backbuffer1
, 0xffff0000);
5438 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
5439 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5440 color
= get_surface_color(backbuffer1
, 320, 240);
5441 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5442 color
= get_surface_color(backbuffer3
, 320, 240);
5443 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
5444 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5445 fill_surface(backbuffer2
, 0xff00ff00);
5447 hr
= IDirectDrawSurface_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
5448 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#lx.\n", test_data
[i
].name
, hr
);
5449 color
= get_surface_color(backbuffer1
, 320, 240);
5450 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
5451 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5452 color
= get_surface_color(backbuffer2
, 320, 240);
5453 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
5455 IDirectDrawSurface_Release(backbuffer3
);
5456 IDirectDrawSurface_Release(backbuffer2
);
5457 IDirectDrawSurface_Release(backbuffer1
);
5458 IDirectDrawSurface_Release(frontbuffer
);
5461 refcount
= IDirectDraw_Release(ddraw
);
5462 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
5463 DestroyWindow(window
);
5466 static void test_sysmem_overlay(void)
5472 IDirectDrawSurface
*surface
;
5475 window
= create_window();
5476 ddraw
= create_ddraw();
5477 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5479 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5480 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5482 memset(&ddsd
, 0, sizeof(ddsd
));
5483 ddsd
.dwSize
= sizeof(ddsd
);
5484 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5487 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
5488 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
5489 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
5490 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
5491 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
5492 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
5493 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
5494 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5495 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#lx.\n", hr
);
5497 ref
= IDirectDraw_Release(ddraw
);
5498 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
5499 DestroyWindow(window
);
5502 static void test_primary_palette(void)
5504 DDSCAPS surface_caps
= {DDSCAPS_FLIP
};
5505 IDirectDrawSurface
*primary
, *backbuffer
;
5506 PALETTEENTRY palette_entries
[256];
5507 IDirectDrawPalette
*palette
, *tmp
;
5508 DDSURFACEDESC surface_desc
;
5515 window
= create_window();
5516 ddraw
= create_ddraw();
5517 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5518 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
5520 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
5521 IDirectDraw_Release(ddraw
);
5522 DestroyWindow(window
);
5525 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5526 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5528 memset(&surface_desc
, 0, sizeof(surface_desc
));
5529 surface_desc
.dwSize
= sizeof(surface_desc
);
5530 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5531 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5532 surface_desc
.dwBackBufferCount
= 1;
5533 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
5534 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5535 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
5536 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
5538 memset(palette_entries
, 0, sizeof(palette_entries
));
5539 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
5540 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
5541 refcount
= get_refcount((IUnknown
*)palette
);
5542 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5544 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5545 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5546 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
5548 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5549 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5551 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
5552 * and is generally somewhat broken with respect to 8 bpp / palette
5554 if (SUCCEEDED(IDirectDrawSurface_GetPalette(backbuffer
, &tmp
)))
5556 win_skip("Broken palette handling detected, skipping tests.\n");
5557 IDirectDrawPalette_Release(tmp
);
5558 IDirectDrawPalette_Release(palette
);
5559 /* The Windows 8 testbot keeps extra references to the primary and
5560 * backbuffer while in 8 bpp mode. */
5561 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
5562 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
5566 refcount
= get_refcount((IUnknown
*)palette
);
5567 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5569 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5570 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5571 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
5572 "Got unexpected palette caps %#lx.\n", palette_caps
);
5574 hr
= IDirectDrawSurface_SetPalette(primary
, NULL
);
5575 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5576 refcount
= get_refcount((IUnknown
*)palette
);
5577 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5579 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
5580 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#lx.\n", hr
);
5581 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#lx.\n", palette_caps
);
5583 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
5584 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
5585 refcount
= get_refcount((IUnknown
*)palette
);
5586 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5588 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5589 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
5590 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
5591 IDirectDrawPalette_Release(tmp
);
5592 hr
= IDirectDrawSurface_GetPalette(backbuffer
, &tmp
);
5593 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5595 refcount
= IDirectDrawPalette_Release(palette
);
5596 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5597 refcount
= IDirectDrawPalette_Release(palette
);
5598 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5600 /* Note that this only seems to work when the palette is attached to the
5601 * primary surface. When attached to a regular surface, attempting to get
5602 * the palette here will cause an access violation. */
5603 hr
= IDirectDrawSurface_GetPalette(primary
, &tmp
);
5604 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5606 hr
= IDirectDrawSurface_IsLost(primary
);
5607 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
5609 memset(&surface_desc
, 0, sizeof(surface_desc
));
5610 surface_desc
.dwSize
= sizeof(surface_desc
);
5611 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5612 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5613 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5614 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5615 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 8, "Got unexpected bit count %lu.\n",
5616 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
5618 hr
= set_display_mode(ddraw
, 640, 480);
5619 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
5621 memset(&surface_desc
, 0, sizeof(surface_desc
));
5622 surface_desc
.dwSize
= sizeof(surface_desc
);
5623 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5624 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5625 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5626 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5627 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 32
5628 || surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 24,
5629 "Got unexpected bit count %lu.\n", surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
5631 hr
= IDirectDrawSurface_IsLost(primary
);
5632 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
5633 hr
= IDirectDrawSurface_Restore(primary
);
5634 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
5635 hr
= IDirectDrawSurface_IsLost(primary
);
5636 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
5638 memset(&surface_desc
, 0, sizeof(surface_desc
));
5639 surface_desc
.dwSize
= sizeof(surface_desc
);
5640 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &surface_desc
);
5641 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5642 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %lu.\n", surface_desc
.dwWidth
);
5643 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %lu.\n", surface_desc
.dwHeight
);
5644 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 32
5645 || surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== 24,
5646 "Got unexpected bit count %lu.\n", surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
5649 refcount
= IDirectDrawSurface_Release(backbuffer
);
5650 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5651 refcount
= IDirectDrawSurface_Release(primary
);
5652 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5653 refcount
= IDirectDraw_Release(ddraw
);
5654 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5655 DestroyWindow(window
);
5658 static HRESULT WINAPI
surface_counter(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
5660 UINT
*surface_count
= context
;
5663 IDirectDrawSurface_Release(surface
);
5665 return DDENUMRET_OK
;
5668 static void test_surface_attachment(void)
5670 IDirectDrawSurface
*surface1
, *surface2
, *surface3
, *surface4
;
5671 DDSCAPS caps
= {DDSCAPS_TEXTURE
};
5672 DDSURFACEDESC surface_desc
;
5679 window
= create_window();
5680 ddraw
= create_ddraw();
5681 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5682 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5683 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5685 memset(&surface_desc
, 0, sizeof(surface_desc
));
5686 surface_desc
.dwSize
= sizeof(surface_desc
);
5687 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
5688 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
5689 surface_desc
.dwMipMapCount
= 3;
5690 surface_desc
.dwWidth
= 128;
5691 surface_desc
.dwHeight
= 128;
5692 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5693 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5695 hr
= IDirectDrawSurface_GetAttachedSurface(surface1
, &caps
, &surface2
);
5696 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
5697 hr
= IDirectDrawSurface_GetAttachedSurface(surface2
, &caps
, &surface3
);
5698 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#lx.\n", hr
);
5699 hr
= IDirectDrawSurface_GetAttachedSurface(surface3
, &caps
, &surface4
);
5700 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
5703 IDirectDrawSurface_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
5704 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5706 IDirectDrawSurface_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
5707 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
5709 IDirectDrawSurface_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
5710 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
5712 memset(&surface_desc
, 0, sizeof(surface_desc
));
5713 surface_desc
.dwSize
= sizeof(surface_desc
);
5714 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5715 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5716 surface_desc
.dwWidth
= 16;
5717 surface_desc
.dwHeight
= 16;
5718 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5719 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5721 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5722 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5723 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5724 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5725 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5726 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5727 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5728 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5729 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5730 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5731 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5732 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5734 IDirectDrawSurface_Release(surface4
);
5736 memset(&surface_desc
, 0, sizeof(surface_desc
));
5737 surface_desc
.dwSize
= sizeof(surface_desc
);
5738 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5739 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
5740 surface_desc
.dwWidth
= 16;
5741 surface_desc
.dwHeight
= 16;
5742 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5743 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5745 if (SUCCEEDED(hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
)))
5747 skip("Running on refrast, skipping some tests.\n");
5748 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface4
);
5749 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5753 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5754 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5755 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5756 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface4
);
5757 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5758 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface3
);
5759 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5760 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface4
);
5761 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5762 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface2
);
5763 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5766 IDirectDrawSurface_Release(surface4
);
5767 IDirectDrawSurface_Release(surface3
);
5768 IDirectDrawSurface_Release(surface2
);
5769 IDirectDrawSurface_Release(surface1
);
5771 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5772 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
5774 /* Try a single primary and two offscreen plain surfaces. */
5775 memset(&surface_desc
, 0, sizeof(surface_desc
));
5776 surface_desc
.dwSize
= sizeof(surface_desc
);
5777 surface_desc
.dwFlags
= DDSD_CAPS
;
5778 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
5779 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5780 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5782 memset(&surface_desc
, 0, sizeof(surface_desc
));
5783 surface_desc
.dwSize
= sizeof(surface_desc
);
5784 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5785 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5786 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5787 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5788 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5789 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5791 memset(&surface_desc
, 0, sizeof(surface_desc
));
5792 surface_desc
.dwSize
= sizeof(surface_desc
);
5793 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5794 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5795 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
5796 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
5797 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5798 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5800 /* This one has a different size. */
5801 memset(&surface_desc
, 0, sizeof(surface_desc
));
5802 surface_desc
.dwSize
= sizeof(surface_desc
);
5803 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5804 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
5805 surface_desc
.dwWidth
= 128;
5806 surface_desc
.dwHeight
= 128;
5807 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5808 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5810 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5811 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5812 /* Try the reverse without detaching first. */
5813 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5814 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5815 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5816 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5818 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface1
);
5819 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5820 /* Try to detach reversed. */
5821 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5822 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5823 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface1
);
5824 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5826 hr
= IDirectDrawSurface_AddAttachedSurface(surface2
, surface3
);
5827 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5828 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface2
, 0, surface3
);
5829 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5831 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5832 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5833 hr
= IDirectDrawSurface_AddAttachedSurface(surface4
, surface1
);
5834 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5836 IDirectDrawSurface_Release(surface4
);
5837 IDirectDrawSurface_Release(surface3
);
5838 IDirectDrawSurface_Release(surface2
);
5839 IDirectDrawSurface_Release(surface1
);
5841 /* Test depth surfaces of different sizes. */
5842 memset(&surface_desc
, 0, sizeof(surface_desc
));
5843 surface_desc
.dwSize
= sizeof(surface_desc
);
5844 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5845 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5846 surface_desc
.dwWidth
= 64;
5847 surface_desc
.dwHeight
= 64;
5848 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5849 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5851 memset(&surface_desc
, 0, sizeof(surface_desc
));
5852 surface_desc
.dwSize
= sizeof(surface_desc
);
5853 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
5854 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5855 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5856 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5857 surface_desc
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
5858 surface_desc
.ddpfPixelFormat
.dwZBitMask
= 0x0000ffff;
5859 surface_desc
.dwWidth
= 32;
5860 surface_desc
.dwHeight
= 32;
5861 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5862 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5863 surface_desc
.dwWidth
= 64;
5864 surface_desc
.dwHeight
= 64;
5865 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5866 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5867 surface_desc
.dwWidth
= 128;
5868 surface_desc
.dwHeight
= 128;
5869 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
5870 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
5872 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5873 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5875 IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5876 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
5877 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#lx.\n", hr
);
5878 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface3
);
5879 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#lx.\n", hr
);
5880 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
5881 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#lx.\n", hr
);
5883 IDirectDrawSurface_Release(surface4
);
5884 IDirectDrawSurface_Release(surface3
);
5885 IDirectDrawSurface_Release(surface2
);
5886 IDirectDrawSurface_Release(surface1
);
5888 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
5889 memset(&surface_desc
, 0, sizeof(surface_desc
));
5890 surface_desc
.dwSize
= sizeof(surface_desc
);
5891 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5892 surface_desc
.dwWidth
= 64;
5893 surface_desc
.dwHeight
= 64;
5894 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5895 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
5896 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
5897 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
5898 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
5899 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
5900 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
5901 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
5902 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5903 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
5904 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5906 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
5907 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
5908 surface_desc
.ddpfPixelFormat
.dwZBufferBitDepth
= 16;
5909 surface_desc
.ddpfPixelFormat
.dwZBitMask
= 0x0000ffff;
5910 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
5911 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5913 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5914 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5915 refcount
= get_refcount((IUnknown
*)surface2
);
5916 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5917 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5918 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#lx.\n", hr
);
5920 /* Attaching while already attached to other surface. */
5921 hr
= IDirectDrawSurface_AddAttachedSurface(surface3
, surface2
);
5922 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5923 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface3
, 0, surface2
);
5924 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5925 IDirectDrawSurface_Release(surface3
);
5927 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1
, 0, surface2
);
5928 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#lx.\n", hr
);
5929 refcount
= get_refcount((IUnknown
*)surface2
);
5930 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
5932 /* Automatic detachment on release. */
5933 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
5934 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#lx.\n", hr
);
5935 refcount
= get_refcount((IUnknown
*)surface2
);
5936 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
5937 refcount
= IDirectDrawSurface_Release(surface1
);
5938 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5939 refcount
= IDirectDrawSurface_Release(surface2
);
5940 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5941 refcount
= IDirectDraw_Release(ddraw
);
5942 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
5943 DestroyWindow(window
);
5946 static void test_pixel_format(void)
5948 HWND window
, window2
, window3
;
5950 int format
, test_format
;
5951 PIXELFORMATDESCRIPTOR pfd
;
5952 IDirectDraw
*ddraw
= NULL
;
5953 IDirectDrawClipper
*clipper
= NULL
;
5954 HDC hdc
, hdc2
, hdc3
;
5956 IDirectDrawSurface
*primary
= NULL
, *offscreen
;
5962 window
= create_window();
5963 ok(!!window
, "Failed to create window.\n");
5964 window2
= create_window();
5965 ok(!!window2
, "Failed to create window.\n");
5967 hdc
= GetDC(window
);
5968 ok(!!hdc
, "Failed to get DC.\n");
5969 hdc2
= GetDC(window2
);
5970 ok(!!hdc2
, "Failed to get DC.\n");
5972 gl
= LoadLibraryA("opengl32.dll");
5973 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
5975 format
= GetPixelFormat(hdc
);
5976 ok(format
== 0, "new window has pixel format %d\n", format
);
5978 ZeroMemory(&pfd
, sizeof(pfd
));
5979 pfd
.nSize
= sizeof(pfd
);
5981 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
5982 pfd
.iPixelType
= PFD_TYPE_RGBA
;
5983 pfd
.iLayerType
= PFD_MAIN_PLANE
;
5984 format
= ChoosePixelFormat(hdc
, &pfd
);
5987 skip("no pixel format available\n");
5991 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
5993 skip("failed to set pixel format\n");
5997 if (!SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
5999 skip("failed to set pixel format on second window\n");
6003 ddraw
= create_ddraw();
6004 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6006 test_format
= GetPixelFormat(hdc
);
6007 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6009 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6010 ok(hr
== S_OK
, "Got 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
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
6016 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
6017 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
6018 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#lx.\n", hr
);
6020 test_format
= GetPixelFormat(hdc
);
6021 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6022 test_format
= GetPixelFormat(hdc2
);
6023 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6025 memset(&ddsd
, 0, sizeof(ddsd
));
6026 ddsd
.dwSize
= sizeof(ddsd
);
6027 ddsd
.dwFlags
= DDSD_CAPS
;
6028 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6030 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
6031 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
6033 test_format
= GetPixelFormat(hdc
);
6034 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6035 test_format
= GetPixelFormat(hdc2
);
6036 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6038 hr
= IDirectDrawSurface_SetClipper(primary
, clipper
);
6039 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
6041 test_format
= GetPixelFormat(hdc
);
6042 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6043 test_format
= GetPixelFormat(hdc2
);
6044 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6046 memset(&ddsd
, 0, sizeof(ddsd
));
6047 ddsd
.dwSize
= sizeof(ddsd
);
6048 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6049 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6050 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
6051 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
6052 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
6054 memset(&fx
, 0, sizeof(fx
));
6055 fx
.dwSize
= sizeof(fx
);
6056 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6057 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
6059 test_format
= GetPixelFormat(hdc
);
6060 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6062 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
6063 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
6065 test_format
= GetPixelFormat(hdc
);
6066 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
6067 test_format
= GetPixelFormat(hdc2
);
6068 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
6070 IDirectDrawSurface_Release(offscreen
);
6071 IDirectDrawSurface_Release(primary
);
6072 refcount
= IDirectDrawClipper_Release(clipper
);
6073 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6074 refcount
= IDirectDraw_Release(ddraw
);
6075 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6077 /* Test that creating a device doesn't set a pixel format on a window which
6080 window3
= create_window();
6081 hdc3
= GetDC(window3
);
6083 test_format
= GetPixelFormat(hdc3
);
6084 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
6086 ddraw
= create_ddraw();
6087 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6088 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window3
, DDSCL_NORMAL
);
6089 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6091 test_format
= GetPixelFormat(hdc3
);
6092 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
6094 memset(&ddsd
, 0, sizeof(ddsd
));
6095 ddsd
.dwSize
= sizeof(ddsd
);
6096 ddsd
.dwFlags
= DDSD_CAPS
;
6097 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6098 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
6099 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6101 memset(&ddsd
, 0, sizeof(ddsd
));
6102 ddsd
.dwSize
= sizeof(ddsd
);
6103 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6104 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6105 ddsd
.dwWidth
= ddsd
.dwHeight
= 64;
6106 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &offscreen
, NULL
);
6107 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
6109 memset(&fx
, 0, sizeof(fx
));
6110 fx
.dwSize
= sizeof(fx
);
6111 hr
= IDirectDrawSurface_Blt(offscreen
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6112 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#lx.\n", hr
);
6114 hr
= IDirectDrawSurface_Blt(primary
, NULL
, offscreen
, NULL
, DDBLT_WAIT
, NULL
);
6115 ok(SUCCEEDED(hr
), "Failed to blit to primary surface, hr %#lx.\n", hr
);
6117 test_format
= GetPixelFormat(hdc3
);
6118 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
6120 IDirectDrawSurface_Release(offscreen
);
6121 IDirectDrawSurface_Release(primary
);
6122 refcount
= IDirectDraw_Release(ddraw
);
6123 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6125 test_format
= GetPixelFormat(hdc3
);
6126 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
6128 ret
= SetPixelFormat(hdc3
, format
, &pfd
);
6129 ok(ret
, "Failed to set pixel format %d.\n", format
);
6131 test_format
= GetPixelFormat(hdc3
);
6132 ok(test_format
== format
, "Expected pixel format %d, got %d.\n", format
, test_format
);
6134 ReleaseDC(window3
, hdc3
);
6135 DestroyWindow(window3
);
6139 ReleaseDC(window2
, hdc2
);
6140 ReleaseDC(window
, hdc
);
6141 DestroyWindow(window2
);
6142 DestroyWindow(window
);
6145 static void test_create_surface_pitch(void)
6147 IDirectDrawSurface
*surface
, *primary
;
6148 DDSURFACEDESC surface_desc
;
6149 DDCAPS caps1
, caps2
;
6170 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6172 DDSD_PITCH
, 0x100, 0x100},
6173 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6174 DDSD_PITCH
, 0x104, DD_OK
,
6175 DDSD_PITCH
, 0x100, 0x100},
6176 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6177 DDSD_PITCH
, 0x0f8, DD_OK
,
6178 DDSD_PITCH
, 0x100, 0x100},
6179 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6180 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6182 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6184 DDSD_PITCH
, 0x100, 0x0fc},
6186 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6187 DDSD_PITCH
, 0x104, DD_OK
,
6188 DDSD_PITCH
, 0x100, 0x0fc},
6189 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6190 DDSD_PITCH
, 0x0f8, DD_OK
,
6191 DDSD_PITCH
, 0x100, 0x0fc},
6192 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6193 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
6194 DDSD_PITCH
, 0x100, 0x0fc},
6195 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6196 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
6198 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
6199 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6202 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6203 0, 0, DDERR_INVALIDCAPS
,
6205 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6207 DDSD_PITCH
, 0x100, 0 },
6208 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
,
6210 DDSD_PITCH
, 0x100, 0 },
6211 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6212 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
6214 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
6215 0, 0, DDERR_INVALIDCAPS
,
6218 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6220 DDSD_PITCH
, 0x100, 0 },
6221 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
6222 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDPARAMS
,
6224 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6226 DDSD_PITCH
, 0x100, 0x0fc},
6227 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6229 DDSD_PITCH
, 0x100, 0x100},
6231 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
6233 window
= create_window();
6234 ddraw
= create_ddraw();
6235 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6236 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
6237 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6239 mem
= calloc((63 * 4) + 8, 63);
6241 /* We need a primary surface and exclusive mode for video memory accounting to work
6242 * right on Windows. Otherwise it gives us junk data, like creating a video memory
6243 * surface freeing up memory. */
6244 memset(&surface_desc
, 0, sizeof(surface_desc
));
6245 surface_desc
.dwSize
= sizeof(surface_desc
);
6246 surface_desc
.dwFlags
= DDSD_CAPS
;
6247 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
6248 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6249 ok(SUCCEEDED(hr
), "Failed to create a primary surface, hr %#lx.\n", hr
);
6251 memset(&caps1
, 0, sizeof(caps1
));
6252 caps1
.dwSize
= sizeof(caps1
);
6253 hr
= IDirectDraw_GetCaps(ddraw
, &caps1
, NULL
);
6254 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6256 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6258 memset(&surface_desc
, 0, sizeof(surface_desc
));
6259 surface_desc
.dwSize
= sizeof(surface_desc
);
6260 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
6261 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
6262 surface_desc
.dwWidth
= 63;
6263 surface_desc
.dwHeight
= 63;
6264 surface_desc
.lPitch
= test_data
[i
].pitch_in
;
6265 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6266 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6267 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6268 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6269 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6270 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6271 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6272 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
6274 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
6275 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, expected_hr
);
6276 surface_desc
.lpSurface
= mem
;
6277 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6279 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
6281 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
6285 memset(&surface_desc
, 0, sizeof(surface_desc
));
6286 surface_desc
.dwSize
= sizeof(surface_desc
);
6287 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6288 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
6289 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
6290 "Test %u: Got unexpected flags %#lx, expected %#lx.\n",
6291 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
6292 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
6294 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
6295 todo_wine
ok(surface_desc
.lPitch
== test_data
[i
].pitch_out64
,
6296 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
6297 i
, surface_desc
.lPitch
, test_data
[i
].pitch_out64
);
6299 ok(surface_desc
.lPitch
== test_data
[i
].pitch_out32
,
6300 "Test %u: Got unexpected pitch %#lx, expected %#lx.\n",
6301 i
, surface_desc
.lPitch
, test_data
[i
].pitch_out32
);
6303 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
6305 memset(&caps2
, 0, sizeof(caps2
));
6306 caps2
.dwSize
= sizeof(caps2
);
6307 hr
= IDirectDraw_GetCaps(ddraw
, &caps2
, NULL
);
6308 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6309 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
6311 /* Star Trek Starfleet Academy cares about this bit here: That creating a system memory
6312 * resource does not influence available video memory. */
6313 ok(caps2
.dwVidMemFree
== caps1
.dwVidMemFree
, "Free video memory changed from %#lx to %#lx, test %u.\n",
6314 caps1
.dwVidMemFree
, caps2
.dwVidMemFree
, i
);
6316 else if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6318 /* DDSCAPS_ALLOCONLOAD does not seem to delay video memory allocation, at least not on
6321 * The amount of video memory consumed is different from what dwHeight * lPitch would
6322 * suggest, although not by much. */
6323 ok(caps2
.dwVidMemFree
< caps1
.dwVidMemFree
,
6324 "Expected free video memory to change, but it did not, test %u.\n", i
);
6327 IDirectDrawSurface_Release(surface
);
6329 hr
= IDirectDraw_GetCaps(ddraw
, &caps2
, NULL
);
6330 ok(SUCCEEDED(hr
), "Failed to get ddraw caps, hr %#lx.\n", hr
);
6331 ok(caps2
.dwVidMemFree
== caps1
.dwVidMemFree
, "Free video memory changed from %#lx to %#lx, test %u.\n",
6332 caps1
.dwVidMemFree
, caps2
.dwVidMemFree
, i
);
6336 refcount
= IDirectDraw_Release(ddraw
);
6337 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6338 DestroyWindow(window
);
6341 static void test_mipmap(void)
6343 IDirectDrawSurface
*surface
, *surface_base
, *surface_mip
;
6344 unsigned int i
, mipmap_count
;
6345 DDSURFACEDESC surface_desc
;
6350 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6359 DWORD mipmap_count_in
;
6361 DWORD mipmap_count_out
;
6365 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
},
6366 {0, DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
6367 {0, DDSCAPS_MIPMAP
| DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
6368 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
6369 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
, 128, 32, 0, DDERR_INVALIDCAPS
},
6370 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
6371 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
6373 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 1, DDERR_INVALIDCAPS
},
6374 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 3, DDERR_INVALIDCAPS
},
6375 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
6376 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
},
6379 window
= create_window();
6380 ddraw
= create_ddraw();
6381 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6382 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6383 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6385 memset(&hal_caps
, 0, sizeof(hal_caps
));
6386 hal_caps
.dwSize
= sizeof(hal_caps
);
6387 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
6388 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6389 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6391 skip("Mipmapped textures not supported, skipping tests.\n");
6392 IDirectDraw_Release(ddraw
);
6393 DestroyWindow(window
);
6397 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
6399 memset(&surface_desc
, 0, sizeof(surface_desc
));
6400 surface_desc
.dwSize
= sizeof(surface_desc
);
6401 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
6402 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6403 surface_desc
.dwWidth
= tests
[i
].width
;
6404 surface_desc
.dwHeight
= tests
[i
].height
;
6405 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
6406 surface_desc
.dwMipMapCount
= tests
[i
].mipmap_count_in
;
6407 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6408 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
6412 memset(&surface_desc
, 0, sizeof(surface_desc
));
6413 surface_desc
.dwSize
= sizeof(surface_desc
);
6414 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
6415 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#lx.\n", i
, hr
);
6416 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6417 "Test %u: Got unexpected flags %#lx.\n", i
, surface_desc
.dwFlags
);
6418 ok(surface_desc
.dwMipMapCount
== tests
[i
].mipmap_count_out
,
6419 "Test %u: Got unexpected mipmap count %lu.\n", i
, surface_desc
.dwMipMapCount
);
6421 surface_base
= surface
;
6422 IDirectDrawSurface2_AddRef(surface_base
);
6423 mipmap_count
= surface_desc
.dwMipMapCount
;
6424 while (mipmap_count
> 1)
6426 hr
= IDirectDrawSurface_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
6427 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6429 memset(&surface_desc
, 0, sizeof(surface_desc
));
6430 surface_desc
.dwSize
= sizeof(surface_desc
);
6431 hr
= IDirectDrawSurface_GetSurfaceDesc(surface_base
, &surface_desc
);
6432 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#lx.\n", i
, mipmap_count
, hr
);
6433 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
6434 "Test %u, %u: Got unexpected flags %#lx.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
6435 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
6436 "Test %u, %u: Got unexpected mipmap count %lu.\n",
6437 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6439 memset(&surface_desc
, 0, sizeof(surface_desc
));
6440 surface_desc
.dwSize
= sizeof(surface_desc
);
6441 hr
= IDirectDrawSurface_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
6442 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6443 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
6444 "Test %u, %u: unexpected change of mipmap count %lu.\n",
6445 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6446 memset(&surface_desc
, 0, sizeof(surface_desc
));
6447 surface_desc
.dwSize
= sizeof(surface_desc
);
6448 hr
= IDirectDrawSurface_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
6449 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#lx.\n", i
, mipmap_count
, hr
);
6450 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
6451 "Test %u, %u: Got unexpected child mipmap count %lu.\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
6452 IDirectDrawSurface_Unlock(surface_mip
, NULL
);
6453 IDirectDrawSurface_Unlock(surface_base
, NULL
);
6455 IDirectDrawSurface_Release(surface_base
);
6456 surface_base
= surface_mip
;
6459 IDirectDrawSurface_Release(surface_base
);
6461 IDirectDrawSurface_Release(surface
);
6464 refcount
= IDirectDraw_Release(ddraw
);
6465 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6466 DestroyWindow(window
);
6469 static void test_palette_complex(void)
6471 IDirectDrawSurface
*surface
, *mipmap
, *tmp
;
6472 DDSURFACEDESC surface_desc
;
6474 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
6478 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
6480 PALETTEENTRY palette_entries
[256];
6486 window
= create_window();
6487 ddraw
= create_ddraw();
6488 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6489 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6490 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6492 memset(&hal_caps
, 0, sizeof(hal_caps
));
6493 hal_caps
.dwSize
= sizeof(hal_caps
);
6494 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
6495 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6496 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
6498 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
6499 IDirectDraw_Release(ddraw
);
6500 DestroyWindow(window
);
6504 memset(&surface_desc
, 0, sizeof(surface_desc
));
6505 surface_desc
.dwSize
= sizeof(surface_desc
);
6506 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6507 surface_desc
.dwWidth
= 128;
6508 surface_desc
.dwHeight
= 128;
6509 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
6510 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6511 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6512 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
6513 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6514 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6516 memset(palette_entries
, 0, sizeof(palette_entries
));
6517 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6518 palette_entries
, &palette
, NULL
);
6519 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6521 memset(palette_entries
, 0, sizeof(palette_entries
));
6522 palette_entries
[1].peRed
= 0xff;
6523 palette_entries
[1].peGreen
= 0x80;
6524 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6525 palette_entries
, &palette_mipmap
, NULL
);
6526 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6528 palette2
= (void *)0xdeadbeef;
6529 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
6530 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx.\n", hr
);
6531 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
6532 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
6533 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6534 hr
= IDirectDrawSurface_GetPalette(surface
, &palette2
);
6535 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#lx.\n", hr
);
6536 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
6537 IDirectDrawPalette_Release(palette2
);
6540 IDirectDrawSurface_AddRef(mipmap
);
6541 for (i
= 0; i
< 7; ++i
)
6543 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6544 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#lx.\n", i
, hr
);
6545 palette2
= (void *)0xdeadbeef;
6546 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
6547 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#lx, i %u.\n", hr
, i
);
6548 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
6550 hr
= IDirectDrawSurface_SetPalette(tmp
, palette_mipmap
);
6551 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#lx.\n", i
, hr
);
6553 hr
= IDirectDrawSurface_GetPalette(tmp
, &palette2
);
6554 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#lx.\n", i
, hr
);
6555 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
6556 IDirectDrawPalette_Release(palette2
);
6558 hr
= IDirectDrawSurface_GetDC(tmp
, &dc
);
6559 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#lx.\n", i
, hr
);
6560 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
6561 ok(count
== 1, "Expected count 1, got %u.\n", count
);
6562 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
6563 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
6564 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
6565 hr
= IDirectDrawSurface_ReleaseDC(tmp
, dc
);
6566 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#lx.\n", i
, hr
);
6568 IDirectDrawSurface_Release(mipmap
);
6572 hr
= IDirectDrawSurface_GetAttachedSurface(mipmap
, &caps
, &tmp
);
6573 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6574 IDirectDrawSurface_Release(mipmap
);
6575 refcount
= IDirectDrawSurface_Release(surface
);
6576 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6577 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
6578 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6579 refcount
= IDirectDrawPalette_Release(palette
);
6580 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6582 refcount
= IDirectDraw_Release(ddraw
);
6583 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6584 DestroyWindow(window
);
6587 static void test_p8_blit(void)
6589 IDirectDrawSurface
*src
, *dst
, *dst_p8
;
6590 DDSURFACEDESC surface_desc
;
6591 unsigned int color
, x
;
6593 IDirectDrawPalette
*palette
, *palette2
;
6597 PALETTEENTRY palette_entries
[256];
6600 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
6601 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
6602 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
6603 static const unsigned int expected
[] =
6605 0x00101010, 0x00010101, 0x00020202, 0x00030303,
6606 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
6609 window
= create_window();
6610 ddraw
= create_ddraw();
6611 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6612 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6613 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
6614 is_warp
= ddraw_is_warp(ddraw
);
6616 memset(palette_entries
, 0, sizeof(palette_entries
));
6617 palette_entries
[1].peGreen
= 0xff;
6618 palette_entries
[2].peBlue
= 0xff;
6619 palette_entries
[3].peFlags
= 0xff;
6620 palette_entries
[4].peRed
= 0xff;
6621 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6622 palette_entries
, &palette
, NULL
);
6623 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6624 palette_entries
[1].peBlue
= 0xff;
6625 palette_entries
[2].peGreen
= 0xff;
6626 palette_entries
[3].peRed
= 0xff;
6627 palette_entries
[4].peFlags
= 0x0;
6628 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
6629 palette_entries
, &palette2
, NULL
);
6630 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
6632 memset(&surface_desc
, 0, sizeof(surface_desc
));
6633 surface_desc
.dwSize
= sizeof(surface_desc
);
6634 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6635 surface_desc
.dwWidth
= 8;
6636 surface_desc
.dwHeight
= 1;
6637 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6638 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6639 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
6640 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
6641 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
6642 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6643 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
6644 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6645 hr
= IDirectDrawSurface_SetPalette(dst_p8
, palette2
);
6646 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6648 memset(&surface_desc
, 0, sizeof(surface_desc
));
6649 surface_desc
.dwSize
= sizeof(surface_desc
);
6650 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6651 surface_desc
.dwWidth
= 8;
6652 surface_desc
.dwHeight
= 1;
6653 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
6654 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
6655 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
6656 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
6657 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
6658 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
6659 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
6660 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
6661 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
6662 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6664 memset(&surface_desc
, 0, sizeof(surface_desc
));
6665 surface_desc
.dwSize
= sizeof(surface_desc
);
6666 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6667 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#lx.\n", hr
);
6668 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
6669 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
6670 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#lx.\n", hr
);
6672 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6673 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
6674 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
6675 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6676 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
6678 fx
.dwSize
= sizeof(fx
);
6679 fx
.dwFillColor
= 0xdeadbeef;
6680 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_WAIT
| DDBLT_COLORFILL
, &fx
);
6681 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
6683 hr
= IDirectDrawSurface_SetPalette(src
, palette
);
6684 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
6685 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
6686 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
6687 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
6688 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
6689 "Failed to blit, hr %#lx.\n", hr
);
6693 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
6695 color
= get_surface_color(dst
, x
, 0);
6696 /* WARP on 1709 and newer write zeroes on non-colorkeyed P8 -> RGB blits. For ckey
6697 * blits see below. */
6698 todo_wine
ok(compare_color(color
, expected
[x
], 0)
6699 || broken(is_warp
&& compare_color(color
, 0x00000000, 0)),
6700 "Pixel %u: Got color %#x, expected %#x.\n",
6701 x
, color
, expected
[x
]);
6705 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
6706 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
6707 hr
= IDirectDrawSurface_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
6708 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
6710 hr
= IDirectDrawSurface_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
6711 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#lx.\n", hr
);
6712 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
6713 * surface untouched. Error checking (DDBLT_KEYSRC without a key
6714 * for example) also works as expected.
6716 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
6717 * the display mode set to P8 doesn't help either. */
6718 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
6719 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
6720 "Got unexpected P8 color key blit result.\n");
6721 hr
= IDirectDrawSurface_Unlock(dst_p8
, NULL
);
6722 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#lx.\n", hr
);
6724 IDirectDrawSurface_Release(src
);
6725 IDirectDrawSurface_Release(dst
);
6726 IDirectDrawSurface_Release(dst_p8
);
6727 IDirectDrawPalette_Release(palette
);
6728 IDirectDrawPalette_Release(palette2
);
6730 refcount
= IDirectDraw_Release(ddraw
);
6731 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
6732 DestroyWindow(window
);
6735 static void test_material(void)
6737 IDirect3DMaterial
*background
, *material
;
6738 IDirect3DExecuteBuffer
*execute_buffer
;
6739 D3DMATERIALHANDLE mat_handle
, tmp
;
6740 D3DEXECUTEBUFFERDESC exec_desc
;
6741 IDirect3DViewport
*viewport
;
6742 IDirect3DDevice
*device
;
6743 IDirectDrawSurface
*rt
;
6744 unsigned int color
, i
;
6753 static D3DVERTEX quad
[] =
6755 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6756 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6757 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6758 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6763 D3DCOLOR expected_color
;
6768 {FALSE
, 0x00ffffff},
6770 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6772 window
= create_window();
6773 ddraw
= create_ddraw();
6774 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6775 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
6777 skip("Failed to create a 3D device, skipping test.\n");
6778 DestroyWindow(window
);
6782 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
6783 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
6785 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
6786 viewport
= create_viewport(device
, 0, 0, 640, 480);
6787 viewport_set_background(device
, viewport
, background
);
6789 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
6790 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
6791 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
6793 memset(&exec_desc
, 0, sizeof(exec_desc
));
6794 exec_desc
.dwSize
= sizeof(exec_desc
);
6795 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
6796 exec_desc
.dwBufferSize
= 1024;
6797 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
6799 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
6800 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
6802 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6804 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
6805 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
6807 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
6808 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
6809 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
6810 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
6811 emit_tquad(&ptr
, 0);
6813 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
6814 inst_length
-= sizeof(quad
);
6816 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
6817 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
6819 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
6820 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6822 hr
= IDirect3DDevice_BeginScene(device
);
6823 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
6824 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
6825 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
6826 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
6827 hr
= IDirect3DDevice_EndScene(device
);
6828 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
6829 color
= get_surface_color(rt
, 320, 240);
6830 if (test_data
[i
].material
)
6831 ok(compare_color(color
, test_data
[i
].expected_color
, 1)
6832 /* The Windows 8 testbot appears to return undefined results. */
6834 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6836 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
6837 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
6840 destroy_material(material
);
6841 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
6842 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
6843 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#lx.\n", hr
);
6845 hr
= IDirect3DViewport_SetBackground(viewport
, mat_handle
);
6846 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#lx.\n", hr
);
6847 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6848 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6849 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
6850 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6851 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6852 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6853 color
= get_surface_color(rt
, 320, 240);
6854 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6856 hr
= IDirect3DViewport_SetBackground(viewport
, 0);
6857 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
6858 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6859 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6860 ok(tmp
== mat_handle
, "Got unexpected material handle %#lx, expected %#lx.\n", tmp
, mat_handle
);
6861 ok(valid
, "Got unexpected valid %#x.\n", valid
);
6862 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6863 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6864 color
= get_surface_color(rt
, 320, 240);
6865 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
6867 destroy_viewport(device
, viewport
);
6868 viewport
= create_viewport(device
, 0, 0, 640, 480);
6870 hr
= IDirect3DViewport_GetBackground(viewport
, &tmp
, &valid
);
6871 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#lx.\n", hr
);
6872 ok(!tmp
, "Got unexpected material handle %#lx.\n", tmp
);
6873 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
6874 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
6875 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
6876 color
= get_surface_color(rt
, 320, 240);
6877 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
6879 IDirect3DExecuteBuffer_Release(execute_buffer
);
6880 destroy_viewport(device
, viewport
);
6881 destroy_material(background
);
6882 destroy_material(material
);
6883 IDirectDrawSurface_Release(rt
);
6884 refcount
= IDirect3DDevice_Release(device
);
6885 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6886 refcount
= IDirectDraw_Release(ddraw
);
6887 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
6888 DestroyWindow(window
);
6891 static void test_lighting(void)
6893 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
6894 static D3DMATRIX mat
=
6896 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6897 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6898 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6899 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6903 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6904 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6905 1.0f
, 0.0f
, 1.0f
, 0.0f
,
6906 0.0f
, 0.0f
, 0.5f
, 1.0f
,
6910 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6911 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6912 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
6913 10.f
, 10.0f
, 10.0f
, 1.0f
,
6917 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6918 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6919 0.0f
, 0.0f
, 1.0f
, -1.0f
,
6920 10.f
, 10.0f
, 10.0f
, 0.0f
,
6922 static D3DLVERTEX unlitquad
[] =
6924 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6925 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6926 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6927 {{ 0.0f
}, {-1.0f
}, {0.1f
}, 0, {0xffff0000}, {0}, {0.0f
}, {0.0f
}},
6931 {{-1.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6932 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6933 {{ 0.0f
}, { 1.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6934 {{ 0.0f
}, { 0.0f
}, {0.1f
}, 0, {0xff00ff00}, {0}, {0.0f
}, {0.0f
}},
6936 static D3DVERTEX unlitnquad
[] =
6938 {{0.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6939 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6940 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6941 {{1.0f
}, {-1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6945 {{0.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6946 {{0.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6947 {{1.0f
}, { 1.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6948 {{1.0f
}, { 0.0f
}, {0.1f
}, {1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
6952 {{-1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6953 {{-1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6954 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6955 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6959 {{-10.0f
}, {-11.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6960 {{-10.0f
}, { -9.0f
}, {11.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6961 {{-10.0f
}, { -9.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6962 {{-10.0f
}, {-11.0f
}, { 9.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}, {0.0f
}, {0.0f
}},
6966 {{-11.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6967 {{-11.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6968 {{ -9.0f
}, { -9.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6969 {{ -9.0f
}, {-11.0f
}, {-10.0f
}, {0.0f
}, {0.0f
}, {-1.0f
}, {0.0f
}, {0.0f
}},
6973 D3DMATRIX
*world_matrix
;
6976 const char *message
;
6980 {&mat
, nquad
, 0x000060ff, "Lit quad with light"},
6981 {&mat_singular
, nquad
, 0x00004db4, "Lit quad with singular world matrix"},
6982 {&mat_transf
, rotatedquad
, 0x000060ff, "Lit quad with transformation matrix"},
6983 {&mat_nonaffine
, translatedquad
, 0x000060ff, "Lit quad with non-affine matrix"},
6986 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
6987 IDirect3DViewport
*viewport
, *viewport2
;
6988 IDirect3DExecuteBuffer
*execute_buffer
;
6989 unsigned int inst_length
, color
, i
;
6990 D3DEXECUTEBUFFERDESC exec_desc
;
6991 D3DMATERIALHANDLE mat_handle
;
6992 IDirect3DMaterial
*material
;
6993 IDirect3DDevice
*device
;
6994 IDirectDrawSurface
*rt
;
6995 IDirect3DLight
*light
;
6996 D3DLIGHT light_desc
;
7004 window
= create_window();
7005 ddraw
= create_ddraw();
7006 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7007 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7009 skip("Failed to create a 3D device, skipping test.\n");
7010 IDirectDraw_Release(ddraw
);
7011 DestroyWindow(window
);
7015 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
7016 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7018 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
7019 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7021 viewport
= create_viewport(device
, 0, 0, 640, 480);
7022 material
= create_diffuse_and_ambient_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
7023 viewport_set_background(device
, viewport
, material
);
7025 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7026 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7028 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
7029 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7030 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
7031 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7032 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
7033 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7034 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
7035 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7036 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
7037 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7038 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
7039 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7041 memset(&exec_desc
, 0, sizeof(exec_desc
));
7042 exec_desc
.dwSize
= sizeof(exec_desc
);
7043 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
7044 exec_desc
.dwBufferSize
= 1024;
7045 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
7047 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
7048 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7050 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7051 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7053 memcpy(exec_desc
.lpData
, unlitquad
, sizeof(unlitquad
));
7054 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitquad
);
7055 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
7056 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
7057 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
7058 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7059 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
7060 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
7061 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
7062 emit_tquad_tlist(&ptr
, 0);
7064 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7065 inst_length
-= sizeof(unlitquad
);
7067 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7068 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7070 hr
= IDirect3DDevice_BeginScene(device
);
7071 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7073 set_execute_data(execute_buffer
, 4, sizeof(unlitquad
), inst_length
);
7074 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7075 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7077 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7078 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7080 memcpy(exec_desc
.lpData
, litquad
, sizeof(litquad
));
7081 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litquad
);
7082 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
7083 emit_tquad_tlist(&ptr
, 0);
7085 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7086 inst_length
-= sizeof(litquad
);
7088 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7089 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7091 set_execute_data(execute_buffer
, 4, sizeof(litquad
), inst_length
);
7092 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7093 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7095 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7096 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7098 memcpy(exec_desc
.lpData
, unlitnquad
, sizeof(unlitnquad
));
7099 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(unlitnquad
);
7100 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
7101 emit_tquad_tlist(&ptr
, 0);
7103 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7104 inst_length
-= sizeof(unlitnquad
);
7106 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7107 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7109 set_execute_data(execute_buffer
, 4, sizeof(unlitnquad
), inst_length
);
7110 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7111 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7113 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7114 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7116 memcpy(exec_desc
.lpData
, litnquad
, sizeof(litnquad
));
7117 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(litnquad
);
7118 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
7119 emit_tquad_tlist(&ptr
, 0);
7121 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7122 inst_length
-= sizeof(litnquad
);
7124 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7125 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7127 set_execute_data(execute_buffer
, 4, sizeof(litnquad
), inst_length
);
7128 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7129 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7131 hr
= IDirect3DDevice_EndScene(device
);
7132 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7134 color
= get_surface_color(rt
, 160, 360);
7135 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
7136 color
= get_surface_color(rt
, 160, 120);
7137 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
7138 color
= get_surface_color(rt
, 480, 360);
7139 ok(color
== 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color
);
7140 color
= get_surface_color(rt
, 480, 120);
7141 ok(color
== 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color
);
7143 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
7144 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7146 hr
= IDirect3D_CreateLight(d3d
, &light
, NULL
);
7147 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#lx.\n", hr
);
7148 memset(&light_desc
, 0, sizeof(light_desc
));
7149 light_desc
.dwSize
= sizeof(light_desc
);
7150 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
7151 light_desc
.dcvColor
.r
= 0.0f
;
7152 light_desc
.dcvColor
.g
= 0.25f
;
7153 light_desc
.dcvColor
.b
= 1.0f
;
7154 light_desc
.dcvColor
.a
= 1.0f
;
7155 light_desc
.dvDirection
.z
= 1.0f
;
7156 hr
= IDirect3DLight_SetLight(light
, &light_desc
);
7157 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7158 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7159 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7160 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7161 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
7163 viewport2
= create_viewport(device
, 0, 0, 640, 480);
7164 hr
= IDirect3DViewport_AddLight(viewport2
, light
);
7165 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#lx.\n", hr
);
7166 destroy_viewport(device
, viewport2
);
7168 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7169 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7170 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7171 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7173 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7175 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, tests
[i
].world_matrix
);
7176 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7178 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7179 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7181 hr
= IDirect3DDevice_BeginScene(device
);
7182 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7184 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7185 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7187 memcpy(exec_desc
.lpData
, tests
[i
].quad
, sizeof(nquad
));
7188 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(nquad
);
7189 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7190 emit_set_ls(&ptr
, D3DLIGHTSTATE_AMBIENT
, 0xff002000);
7191 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, 4);
7192 emit_tquad_tlist(&ptr
, 0);
7194 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7195 inst_length
-= sizeof(nquad
);
7197 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7198 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7200 set_execute_data(execute_buffer
, 4, sizeof(nquad
), inst_length
);
7201 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7202 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7204 hr
= IDirect3DDevice_EndScene(device
);
7205 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7207 color
= get_surface_color(rt
, 320, 240);
7208 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
7211 IDirect3DExecuteBuffer_Release(execute_buffer
);
7212 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
7213 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
7214 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
7215 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7216 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7217 IDirect3DLight_Release(light
);
7218 destroy_material(material
);
7219 destroy_viewport(device
, viewport
);
7220 IDirectDrawSurface_Release(rt
);
7221 refcount
= IDirect3DDevice_Release(device
);
7222 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7223 IDirect3D_Release(d3d
);
7224 refcount
= IDirectDraw_Release(ddraw
);
7225 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
7226 DestroyWindow(window
);
7229 static void test_specular_lighting(void)
7231 static const unsigned int vertices_side
= 5;
7232 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
7233 const unsigned int vertex_count
= vertices_side
* vertices_side
;
7234 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
7235 static D3DMATRIX mat
=
7237 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7238 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7239 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7240 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7242 /* Use of D3DLIGHT2 instead of D3DLIGHT is intentional. Using D3DLIGHT
7243 * without dwFlags looks broken on Windows 7: directional light behaves as
7244 * if _LOCALVIEWER state is off, point and spot lights do not work at all
7245 * and always output zero colours. */
7246 static D3DLIGHT2 directional
=
7249 D3DLIGHT_DIRECTIONAL
,
7250 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7251 {{0.0f
}, {0.0f
}, {0.0f
}},
7252 {{0.0f
}, {0.0f
}, {1.0f
}},
7258 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7259 {{0.0f
}, {0.0f
}, {0.0f
}},
7260 {{0.0f
}, {0.0f
}, {0.0f
}},
7269 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7270 {{0.0f
}, {0.0f
}, {0.0f
}},
7271 {{0.0f
}, {0.0f
}, {1.0f
}},
7275 M_PI
/ 12.0f
, M_PI
/ 3.0f
7280 D3DLIGHT_PARALLELPOINT
,
7281 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7282 {{0.5f
}, {0.0f
}, {-1.0f
}},
7283 {{0.0f
}, {0.0f
}, {0.0f
}},
7289 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7290 {{-1.1f
}, {0.0f
}, {1.1f
}},
7291 {{0.0f
}, {0.0f
}, {0.0f
}},
7300 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
7301 {{0.0f
}, {0.0f
}, {0.1f
}},
7302 {{0.0f
}, {0.0f
}, {0.0f
}},
7307 static const struct expected_color
7309 unsigned int x
, y
, colour
;
7311 expected_directional_local
[] =
7313 {160, 120, 0x003c3c3c},
7314 {320, 120, 0x00717171},
7315 {480, 120, 0x003c3c3c},
7316 {160, 240, 0x00717171},
7317 {320, 240, 0x00ffffff},
7318 {480, 240, 0x00717171},
7319 {160, 360, 0x003c3c3c},
7320 {320, 360, 0x00717171},
7321 {480, 360, 0x003c3c3c},
7323 expected_point_local
[] =
7325 {160, 120, 0x00000000},
7326 {320, 120, 0x00090909},
7327 {480, 120, 0x00000000},
7328 {160, 240, 0x00090909},
7329 {320, 240, 0x00fafafa},
7330 {480, 240, 0x00090909},
7331 {160, 360, 0x00000000},
7332 {320, 360, 0x00090909},
7333 {480, 360, 0x00000000},
7335 expected_spot_local
[] =
7337 {160, 120, 0x00000000},
7338 {320, 120, 0x00020202},
7339 {480, 120, 0x00000000},
7340 {160, 240, 0x00020202},
7341 {320, 240, 0x00fafafa},
7342 {480, 240, 0x00020202},
7343 {160, 360, 0x00000000},
7344 {320, 360, 0x00020202},
7345 {480, 360, 0x00000000},
7347 expected_parallelpoint
[] =
7349 {160, 120, 0x00050505},
7350 {320, 120, 0x002c2c2c},
7351 {480, 120, 0x006e6e6e},
7352 {160, 240, 0x00090909},
7353 {320, 240, 0x00717171},
7354 {480, 240, 0x00ffffff},
7355 {160, 360, 0x00050505},
7356 {320, 360, 0x002c2c2c},
7357 {480, 360, 0x006e6e6e},
7359 expected_point_far
[] =
7361 {160, 120, 0x00000000},
7362 {320, 120, 0x00000000},
7363 {480, 120, 0x00000000},
7364 {160, 240, 0x00000000},
7365 {320, 240, 0x00ffffff},
7366 {480, 240, 0x00000000},
7367 {160, 360, 0x00000000},
7368 {320, 360, 0x00000000},
7369 {480, 360, 0x00000000},
7373 {160, 120, 0x00000000},
7374 {320, 120, 0x00000000},
7375 {480, 120, 0x00000000},
7376 {160, 240, 0x00000000},
7377 {320, 240, 0x00000000},
7378 {480, 240, 0x00000000},
7379 {160, 360, 0x00000000},
7380 {320, 360, 0x00000000},
7381 {480, 360, 0x00000000},
7386 float specular_power
;
7387 const struct expected_color
*expected
;
7388 unsigned int expected_count
;
7392 {&directional
, 30.0f
, expected_directional_local
, ARRAY_SIZE(expected_directional_local
)},
7393 {&point
, 30.0f
, expected_point_local
, ARRAY_SIZE(expected_point_local
)},
7394 {&spot
, 30.0f
, expected_spot_local
, ARRAY_SIZE(expected_spot_local
)},
7395 {¶llelpoint
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
7396 {&point_side
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7397 {&point_far
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
7398 {&directional
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7399 {&point
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7400 {&spot
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7401 {¶llelpoint
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7402 {&point_far
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
7405 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
7406 IDirect3DMaterial
*material
, *background_material
;
7407 unsigned int inst_length
, colour
, i
, j
, x
, y
;
7408 IDirect3DExecuteBuffer
*execute_buffer
;
7409 D3DEXECUTEBUFFERDESC exec_desc
;
7410 D3DMATERIALHANDLE mat_handle
;
7411 IDirect3DViewport
*viewport
;
7412 IDirect3DDevice
*device
;
7413 IDirectDrawSurface
*rt
;
7414 IDirect3DLight
*light
;
7425 window
= create_window();
7426 ddraw
= create_ddraw();
7427 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7428 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
7430 skip("Failed to create a 3D device, skipping test.\n");
7431 IDirectDraw_Release(ddraw
);
7432 DestroyWindow(window
);
7435 is_warp
= ddraw_is_warp(ddraw
);
7437 quad
= malloc(vertex_count
* sizeof(*quad
));
7438 indices
= malloc(indices_count
* sizeof(*indices
));
7439 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
7441 for (x
= 0; x
< vertices_side
; ++x
)
7443 quad
[i
].x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7444 quad
[i
].y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
7450 quad
[i
++].tv
= 0.0f
;
7453 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
7455 for (x
= 0; x
< (vertices_side
- 1); ++x
)
7457 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7458 indices
[i
++] = y
* vertices_side
+ x
;
7459 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7460 indices
[i
++] = y
* vertices_side
+ x
+ 1;
7461 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
7462 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
7466 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
7467 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7469 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
7470 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7472 viewport
= create_viewport(device
, 0, 0, 640, 480);
7473 background_material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
7474 viewport_set_background(device
, viewport
, background_material
);
7476 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7477 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7479 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
7480 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7481 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
7482 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7483 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
7484 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7485 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
7486 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7487 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
7488 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7489 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
7490 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7493 hr
= IDirect3D_CreateLight(d3d
, &light
, NULL
);
7494 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7495 hr
= IDirect3DViewport_AddLight(viewport
, light
);
7496 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7498 memset(&exec_desc
, 0, sizeof(exec_desc
));
7499 exec_desc
.dwSize
= sizeof(exec_desc
);
7500 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
7501 exec_desc
.dwBufferSize
= 10240;
7502 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
7504 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
7505 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7507 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7509 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
7510 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
7511 hr
= IDirect3DMaterial_GetHandle(material
, device
, &mat_handle
);
7512 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7514 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
7515 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7517 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
7518 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7520 hr
= IDirect3DDevice_BeginScene(device
);
7521 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7523 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
7524 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7526 memcpy(exec_desc
.lpData
, quad
, sizeof(*quad
) * vertex_count
);
7527 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(*quad
) * vertex_count
;
7529 emit_set_ls(&ptr
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
7530 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
7531 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
7532 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
7533 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
7534 emit_set_rs(&ptr
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
7536 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORMLIGHT
, 0, vertex_count
);
7537 emit_tri_indices(&ptr
, indices
, indices_count
/ 3);
7539 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
7540 ok(inst_length
<= exec_desc
.dwBufferSize
, "Execute buffer overflow, size %u.\n", inst_length
);
7541 inst_length
-= sizeof(*quad
) * vertex_count
;
7543 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
7544 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7546 set_execute_data(execute_buffer
, vertex_count
, sizeof(*quad
) * vertex_count
, inst_length
);
7547 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
7548 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7550 hr
= IDirect3DDevice_EndScene(device
);
7551 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7553 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
7555 colour
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
7556 ok(compare_color(colour
, tests
[i
].expected
[j
].colour
, 1)
7557 || broken(is_warp
&& compare_color(colour
, 0x00ff0000, 1)),
7558 "Expected colour 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
7559 tests
[i
].expected
[j
].colour
, tests
[i
].expected
[j
].x
,
7560 tests
[i
].expected
[j
].y
, colour
, i
);
7562 destroy_material(material
);
7565 IDirect3DExecuteBuffer_Release(execute_buffer
);
7566 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
7567 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
7568 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
7570 hr
= IDirect3DViewport_DeleteLight(viewport
, light
);
7571 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
7572 IDirect3DLight_Release(light
);
7573 destroy_material(background_material
);
7574 destroy_viewport(device
, viewport
);
7575 IDirectDrawSurface_Release(rt
);
7576 refcount
= IDirect3DDevice_Release(device
);
7577 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7578 IDirect3D_Release(d3d
);
7579 refcount
= IDirectDraw_Release(ddraw
);
7580 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
7581 DestroyWindow(window
);
7586 static void test_palette_gdi(void)
7588 IDirectDrawSurface
*surface
, *primary
;
7589 DDSURFACEDESC surface_desc
;
7590 unsigned int color
, i
;
7592 IDirectDrawPalette
*palette
, *palette2
;
7596 PALETTEENTRY palette_entries
[256];
7601 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
7602 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
7603 * not the point of this test. */
7604 static const RGBQUAD expected1
[] =
7606 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7607 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
7609 static const RGBQUAD expected2
[] =
7611 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
7612 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
7614 static const RGBQUAD expected3
[] =
7616 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
7617 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
7619 HPALETTE ddraw_palette_handle
;
7620 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
7621 RGBQUAD rgbquad
[255];
7622 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
7624 window
= create_window();
7625 ddraw
= create_ddraw();
7626 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7627 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7628 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7630 memset(&surface_desc
, 0, sizeof(surface_desc
));
7631 surface_desc
.dwSize
= sizeof(surface_desc
);
7632 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7633 surface_desc
.dwWidth
= 16;
7634 surface_desc
.dwHeight
= 16;
7635 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7636 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
7637 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7638 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 8;
7639 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7640 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7642 /* Avoid colors from the Windows default palette. */
7643 memset(palette_entries
, 0, sizeof(palette_entries
));
7644 palette_entries
[1].peRed
= 0x01;
7645 palette_entries
[2].peGreen
= 0x02;
7646 palette_entries
[3].peBlue
= 0x03;
7647 palette_entries
[4].peRed
= 0x13;
7648 palette_entries
[4].peGreen
= 0x14;
7649 palette_entries
[4].peBlue
= 0x15;
7650 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7651 palette_entries
, &palette
, NULL
);
7652 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7654 /* If there is no palette assigned and the display mode is not 8 bpp, some
7655 * drivers refuse to create a DC while others allow it. If a DC is created,
7656 * the DIB color table is uninitialized and contains random colors. No error
7657 * is generated when trying to read pixels and random garbage is returned.
7659 * The most likely explanation is that if the driver creates a DC, it (or
7660 * the higher-level runtime) uses GetSystemPaletteEntries to find the
7661 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
7662 * contains uninitialized garbage. See comments below for the P8 case. */
7664 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7665 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7666 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7667 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7668 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7669 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7670 "Got unexpected palette %p, expected %p.\n",
7671 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7673 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7674 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7675 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
7677 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
7678 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7679 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7680 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
7682 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7684 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7685 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7686 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7689 /* Update the palette while the DC is in use. This does not modify the DC. */
7690 palette_entries
[4].peRed
= 0x23;
7691 palette_entries
[4].peGreen
= 0x24;
7692 palette_entries
[4].peBlue
= 0x25;
7693 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
7694 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
7696 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7697 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7698 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7699 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7700 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7701 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7703 /* Neither does re-setting the palette. */
7704 hr
= IDirectDrawSurface_SetPalette(surface
, NULL
);
7705 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7706 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7707 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7709 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
7710 ok(i
== 1, "Expected count 1, got %u.\n", i
);
7711 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
7712 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7713 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
7714 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
7716 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7717 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7719 /* Refresh the DC. This updates the palette. */
7720 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7721 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7722 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7723 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7724 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7726 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7727 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7728 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7729 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7731 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7733 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7734 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7735 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7737 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7738 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7740 refcount
= IDirectDrawSurface_Release(surface
);
7741 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7743 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
7744 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7745 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
7747 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7748 IDirectDrawPalette_Release(palette
);
7749 IDirectDraw_Release(ddraw
);
7750 DestroyWindow(window
);
7753 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#lx.\n", hr
);
7755 memset(&surface_desc
, 0, sizeof(surface_desc
));
7756 surface_desc
.dwSize
= sizeof(surface_desc
);
7757 surface_desc
.dwFlags
= DDSD_CAPS
;
7758 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7759 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7760 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7762 memset(&fx
, 0, sizeof(fx
));
7763 fx
.dwSize
= sizeof(fx
);
7765 SetRect(&r
, 0, 0, 319, 479);
7766 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7767 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
7768 SetRect(&r
, 320, 0, 639, 479);
7770 hr
= IDirectDrawSurface_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7771 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#lx.\n", hr
);
7773 hr
= IDirectDrawSurface_SetPalette(primary
, palette
);
7774 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7775 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
7776 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7778 color
= GetPixel(dc
, 160, 240);
7779 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
7780 color
= GetPixel(dc
, 480, 240);
7781 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
7783 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
7784 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
7785 "Got unexpected palette %p, expected %p.\n",
7786 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
7787 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
7789 /* The primary uses the system palette. In exclusive mode, the system palette matches
7790 * the ddraw palette attached to the primary, so the result is what you would expect
7791 * from a regular surface. Tests for the interaction between the ddraw palette and
7792 * the system palette are not included pending an application that depends on this.
7793 * The relation between those causes problems on Windows Vista and newer for games
7794 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
7795 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7796 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7797 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7799 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7800 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7801 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7802 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7804 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7806 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7807 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7808 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7810 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
7811 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7813 memset(&surface_desc
, 0, sizeof(surface_desc
));
7814 surface_desc
.dwSize
= sizeof(surface_desc
);
7815 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7816 surface_desc
.dwWidth
= 16;
7817 surface_desc
.dwHeight
= 16;
7818 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7819 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7820 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
7822 /* Here the offscreen surface appears to use the primary's palette,
7823 * but in all likelihood it is actually the system palette. */
7824 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7825 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7826 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7827 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7828 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
7830 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
7831 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7832 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7833 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
7835 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7837 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7838 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7839 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7841 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7842 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7844 /* On real hardware a change to the primary surface's palette applies immediately,
7845 * even on device contexts from offscreen surfaces that do not have their own
7846 * palette. On the testbot VMs this is not the case. Don't test this until we
7847 * know of an application that depends on this. */
7849 memset(palette_entries
, 0, sizeof(palette_entries
));
7850 palette_entries
[1].peBlue
= 0x40;
7851 palette_entries
[2].peRed
= 0x40;
7852 palette_entries
[3].peGreen
= 0x40;
7853 palette_entries
[4].peRed
= 0x12;
7854 palette_entries
[4].peGreen
= 0x34;
7855 palette_entries
[4].peBlue
= 0x56;
7856 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7857 palette_entries
, &palette2
, NULL
);
7858 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7859 hr
= IDirectDrawSurface_SetPalette(surface
, palette2
);
7860 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#lx.\n", hr
);
7862 /* A palette assigned to the offscreen surface overrides the primary / system
7864 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
7865 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
7866 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
7867 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
7868 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
7870 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
7871 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
7872 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
7873 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
7875 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
7877 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
7878 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
7879 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
7881 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
7882 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
7884 refcount
= IDirectDrawSurface_Release(surface
);
7885 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7887 /* The Windows 8 testbot keeps extra references to the primary and
7888 * backbuffer while in 8 bpp mode. */
7889 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
7890 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
7892 refcount
= IDirectDrawSurface_Release(primary
);
7893 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7894 refcount
= IDirectDrawPalette_Release(palette2
);
7895 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7896 refcount
= IDirectDrawPalette_Release(palette
);
7897 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7898 refcount
= IDirectDraw_Release(ddraw
);
7899 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
7900 DestroyWindow(window
);
7903 static void test_palette_alpha(void)
7905 IDirectDrawSurface
*surface
;
7906 DDSURFACEDESC surface_desc
;
7908 IDirectDrawPalette
*palette
;
7912 PALETTEENTRY palette_entries
[256];
7917 BOOL attach_allowed
;
7922 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
7923 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
7924 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
7927 window
= create_window();
7928 ddraw
= create_ddraw();
7929 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7930 if (FAILED(IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 8)))
7932 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7933 IDirectDraw_Release(ddraw
);
7934 DestroyWindow(window
);
7937 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7938 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
7940 memset(palette_entries
, 0, sizeof(palette_entries
));
7941 palette_entries
[1].peFlags
= 0x42;
7942 palette_entries
[2].peFlags
= 0xff;
7943 palette_entries
[3].peFlags
= 0x80;
7944 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
7945 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7947 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7948 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7949 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
7950 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7951 palette_entries
[0].peFlags
);
7952 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7953 palette_entries
[1].peFlags
);
7954 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7955 palette_entries
[2].peFlags
);
7956 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7957 palette_entries
[3].peFlags
);
7959 IDirectDrawPalette_Release(palette
);
7961 memset(palette_entries
, 0, sizeof(palette_entries
));
7962 palette_entries
[1].peFlags
= 0x42;
7963 palette_entries
[1].peRed
= 0xff;
7964 palette_entries
[2].peFlags
= 0xff;
7965 palette_entries
[3].peFlags
= 0x80;
7966 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
7967 palette_entries
, &palette
, NULL
);
7968 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#lx.\n", hr
);
7970 memset(palette_entries
, 0x66, sizeof(palette_entries
));
7971 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
7972 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#lx.\n", hr
);
7973 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7974 palette_entries
[0].peFlags
);
7975 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
7976 palette_entries
[1].peFlags
);
7977 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
7978 palette_entries
[2].peFlags
);
7979 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
7980 palette_entries
[3].peFlags
);
7982 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
7984 memset(&surface_desc
, 0, sizeof(surface_desc
));
7985 surface_desc
.dwSize
= sizeof(surface_desc
);
7986 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
7987 surface_desc
.dwWidth
= 128;
7988 surface_desc
.dwHeight
= 128;
7989 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7990 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7991 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7993 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
7994 if (test_data
[i
].attach_allowed
)
7995 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#lx.\n", test_data
[i
].name
, hr
);
7997 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
8005 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
8006 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_CANTCREATEDC
) /* Win2k testbot */,
8007 "Failed to get DC, hr %#lx, %s surface.\n", hr
, test_data
[i
].name
);
8010 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8011 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
8012 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
8013 rgbquad
.rgbRed
, test_data
[i
].name
);
8014 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
8015 rgbquad
.rgbGreen
, test_data
[i
].name
);
8016 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
8017 rgbquad
.rgbBlue
, test_data
[i
].name
);
8018 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
8019 rgbquad
.rgbReserved
, test_data
[i
].name
);
8020 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
8021 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
8024 IDirectDrawSurface_Release(surface
);
8027 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8028 memset(&surface_desc
, 0, sizeof(surface_desc
));
8029 surface_desc
.dwSize
= sizeof(surface_desc
);
8030 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8031 surface_desc
.dwWidth
= 128;
8032 surface_desc
.dwHeight
= 128;
8033 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8034 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8035 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8036 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
8037 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
8038 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
8039 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
8040 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8041 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8042 hr
= IDirectDrawSurface_SetPalette(surface
, palette
);
8043 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#lx.\n", hr
);
8044 IDirectDrawSurface_Release(surface
);
8046 /* The Windows 8 testbot keeps extra references to the primary
8047 * while in 8 bpp mode. */
8048 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
8049 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#lx.\n", hr
);
8051 refcount
= IDirectDrawPalette_Release(palette
);
8052 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8053 refcount
= IDirectDraw_Release(ddraw
);
8054 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8055 DestroyWindow(window
);
8058 static void test_lost_device(void)
8060 IDirectDrawSurface
*surface
, *back_buffer
, *back_buffer2
, *ds
;
8061 IDirectDrawSurface
*sysmem_surface
, *vidmem_surface
;
8062 DDSURFACEDESC surface_desc
;
8063 HWND window1
, window2
;
8070 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8071 0, 0, 640, 480, 0, 0, 0, 0);
8072 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8073 0, 0, 640, 480, 0, 0, 0, 0);
8074 ddraw
= create_ddraw();
8075 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8076 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8077 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8079 memset(&surface_desc
, 0, sizeof(surface_desc
));
8080 surface_desc
.dwSize
= sizeof(surface_desc
);
8081 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8082 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8083 surface_desc
.dwBackBufferCount
= 1;
8084 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8085 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8087 memset(&surface_desc
, 0, sizeof(surface_desc
));
8088 surface_desc
.dwSize
= sizeof(surface_desc
);
8089 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8090 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
8091 surface_desc
.dwWidth
= 100;
8092 surface_desc
.dwHeight
= 100;
8093 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
8094 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8096 memset(&surface_desc
, 0, sizeof(surface_desc
));
8097 surface_desc
.dwSize
= sizeof(surface_desc
);
8098 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8099 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
8100 surface_desc
.dwWidth
= 64;
8101 surface_desc
.dwHeight
= 64;
8102 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
8103 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8104 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
8105 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
8106 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
8107 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
8108 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &vidmem_surface
, NULL
)))
8110 skip("Failed to create video memory surface, skipping related tests.\n");
8111 vidmem_surface
= NULL
;
8114 hr
= IDirectDrawSurface_IsLost(surface
);
8115 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8116 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8117 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8118 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8119 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8122 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8123 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8126 ret
= SetForegroundWindow(GetDesktopWindow());
8127 ok(ret
, "Failed to set foreground window.\n");
8128 hr
= IDirectDrawSurface_IsLost(surface
);
8129 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8130 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8131 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8132 hr
= IDirectDrawSurface_Restore(surface
);
8133 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8134 hr
= IDirectDrawSurface_IsLost(surface
);
8135 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8136 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8137 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8138 hr
= IDirectDrawSurface_Restore(sysmem_surface
);
8139 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8140 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8141 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8144 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8145 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8146 hr
= IDirectDrawSurface_Restore(vidmem_surface
);
8147 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#lx.\n", hr
);
8148 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8149 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8152 ret
= SetForegroundWindow(window1
);
8153 ok(ret
, "Failed to set foreground window.\n");
8154 hr
= IDirectDrawSurface_IsLost(surface
);
8155 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8156 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8157 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8158 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8159 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8162 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8163 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8166 hr
= restore_surfaces(ddraw
);
8167 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8168 hr
= IDirectDrawSurface_IsLost(surface
);
8169 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8170 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8171 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8172 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8173 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8176 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8177 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8180 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8181 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8182 hr
= IDirectDrawSurface_IsLost(surface
);
8183 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8184 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8185 ok(hr
== DDERR_NOEXCLUSIVEMODE
|| broken(ddraw_is_warp(ddraw
) && hr
== DDERR_SURFACELOST
),
8186 "Got unexpected hr %#lx.\n", hr
);
8187 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8188 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8191 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8192 ok(hr
== DD_OK
|| broken(ddraw_is_warp(ddraw
) && hr
== DDERR_SURFACELOST
), "Got unexpected hr %#lx.\n", hr
);
8195 /* Trying to restore the primary will crash, probably because flippable
8196 * surfaces can't exist in DDSCL_NORMAL. */
8197 IDirectDrawSurface_Release(surface
);
8198 memset(&surface_desc
, 0, sizeof(surface_desc
));
8199 surface_desc
.dwSize
= sizeof(surface_desc
);
8200 surface_desc
.dwFlags
= DDSD_CAPS
;
8201 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8202 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8203 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8204 hr
= restore_surfaces(ddraw
);
8205 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8207 hr
= IDirectDrawSurface_IsLost(surface
);
8208 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8210 ret
= SetForegroundWindow(GetDesktopWindow());
8211 ok(ret
, "Failed to set foreground window.\n");
8212 hr
= IDirectDrawSurface_IsLost(surface
);
8213 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8214 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8215 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8218 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8219 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8222 ret
= SetForegroundWindow(window1
);
8223 ok(ret
, "Failed to set foreground window.\n");
8224 hr
= IDirectDrawSurface_IsLost(surface
);
8225 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8226 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8227 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8230 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8231 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8234 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8235 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8236 hr
= IDirectDrawSurface_IsLost(surface
);
8237 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8238 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8239 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8242 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8243 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8246 hr
= restore_surfaces(ddraw
);
8247 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8248 hr
= IDirectDrawSurface_IsLost(surface
);
8249 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8250 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8251 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8254 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8255 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8258 IDirectDrawSurface_Release(surface
);
8259 memset(&surface_desc
, 0, sizeof(surface_desc
));
8260 surface_desc
.dwSize
= sizeof(surface_desc
);
8261 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8262 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8263 surface_desc
.dwBackBufferCount
= 2;
8264 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8265 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8268 memset(&surface_desc
, 0, sizeof(surface_desc
));
8269 surface_desc
.dwSize
= sizeof(surface_desc
);
8270 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8271 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8273 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
8274 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
8275 surface_desc
.dwZBufferBitDepth
= 16;
8276 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
8279 skip("Could not create Z buffer, skipping Z buffer restore test.\n");
8283 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
8284 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8287 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8288 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8289 hr
= IDirectDrawSurface_IsLost(surface
);
8290 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8291 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8292 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8293 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8294 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8297 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8298 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8301 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8302 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8303 hr
= IDirectDrawSurface_IsLost(surface
);
8304 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8305 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8306 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8307 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8308 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8311 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8312 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8315 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8316 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8317 hr
= IDirectDrawSurface_IsLost(surface
);
8318 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8319 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8320 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8321 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8322 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8325 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8326 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8329 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
8330 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8331 hr
= IDirectDrawSurface_IsLost(surface
);
8332 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8333 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8334 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8335 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8336 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8339 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8340 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8343 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8344 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8345 hr
= IDirectDrawSurface_IsLost(surface
);
8346 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8347 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8348 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#lx.\n", hr
);
8349 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8350 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8353 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8354 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8357 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8358 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8359 hr
= IDirectDrawSurface_IsLost(surface
);
8360 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8361 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
8362 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8363 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
8364 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8367 hr
= IDirectDrawSurface_IsLost(vidmem_surface
);
8368 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8371 memset(&caps
, 0, sizeof(caps
));
8372 caps
.dwCaps
= DDSCAPS_FLIP
;
8374 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
8375 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8376 ok(back_buffer
!= surface
, "Got the same surface.\n");
8377 hr
= IDirectDrawSurface_Restore(surface
);
8378 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8379 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &back_buffer
);
8380 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8381 hr
= IDirectDrawSurface_IsLost(back_buffer
);
8382 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8383 IDirectDrawSurface_Release(back_buffer
);
8385 hr
= IDirectDrawSurface_GetAttachedSurface(back_buffer
, &caps
, &back_buffer2
);
8386 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8387 ok(back_buffer2
!= back_buffer
, "Got the same surface.\n");
8388 ok(back_buffer2
!= surface
, "Got the same surface.\n");
8389 hr
= IDirectDrawSurface_IsLost(back_buffer2
);
8390 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8391 IDirectDrawSurface_Release(back_buffer2
);
8395 hr
= IDirectDrawSurface_IsLost(ds
);
8396 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#lx.\n", hr
);
8397 hr
= IDirectDrawSurface_Restore(ds
);
8398 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8399 hr
= IDirectDrawSurface_IsLost(ds
);
8400 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
8401 IDirectDrawSurface_Release(ds
);
8405 IDirectDrawSurface_Release(vidmem_surface
);
8406 IDirectDrawSurface_Release(sysmem_surface
);
8407 IDirectDrawSurface_Release(surface
);
8408 refcount
= IDirectDraw_Release(ddraw
);
8409 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8410 DestroyWindow(window2
);
8411 DestroyWindow(window1
);
8414 static void test_surface_desc_lock(void)
8416 IDirectDrawSurface
*surface
;
8417 DDSURFACEDESC surface_desc
;
8423 window
= create_window();
8424 ddraw
= create_ddraw();
8425 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8426 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8427 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
8429 memset(&surface_desc
, 0, sizeof(surface_desc
));
8430 surface_desc
.dwSize
= sizeof(surface_desc
);
8431 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8432 surface_desc
.dwWidth
= 16;
8433 surface_desc
.dwHeight
= 16;
8434 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8435 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8436 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8438 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8439 surface_desc
.dwSize
= sizeof(surface_desc
);
8440 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8441 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8442 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8444 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8445 surface_desc
.dwSize
= sizeof(surface_desc
);
8446 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
8447 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
8448 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8449 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8450 surface_desc
.dwSize
= sizeof(surface_desc
);
8451 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8452 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8453 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8454 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
8455 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
8457 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
8458 surface_desc
.dwSize
= sizeof(surface_desc
);
8459 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
8460 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
8461 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
8463 IDirectDrawSurface_Release(surface
);
8464 refcount
= IDirectDraw_Release(ddraw
);
8465 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
8466 DestroyWindow(window
);
8469 static void test_texturemapblend(void)
8473 D3DEXECUTEBUFFERDESC exec_desc
;
8475 static RECT rect
= {0, 0, 64, 128};
8476 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8478 IDirectDrawSurface
*surface
, *rt
;
8479 unsigned int inst_length
, color
;
8480 IDirect3DTexture
*texture
;
8481 D3DTEXTUREHANDLE texture_handle
;
8484 IDirect3DDevice
*device
;
8485 IDirect3DMaterial
*material
;
8486 IDirect3DViewport
*viewport
;
8487 IDirect3DExecuteBuffer
*execute_buffer
;
8491 static const D3DTLVERTEX test1_quads
[] =
8493 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {0.0f
}},
8494 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {0.0f
}, {1.0f
}},
8495 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {0.0f
}},
8496 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0}, {1.0f
}, {1.0f
}},
8497 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {0.0f
}},
8498 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {0.0f
}, {1.0f
}},
8499 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {0.0f
}},
8500 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x80ffffff}, {0}, {1.0f
}, {1.0f
}},
8504 {{0.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {0.0f
}},
8505 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {0.0f
}, {1.0f
}},
8506 {{640.0f
}, {0.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {0.0f
}},
8507 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x00ff0080}, {0}, {1.0f
}, {1.0f
}},
8508 {{0.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {0.0f
}},
8509 {{0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {0.0f
}, {1.0f
}},
8510 {{640.0f
}, {240.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {0.0f
}},
8511 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x008000ff}, {0}, {1.0f
}, {1.0f
}},
8514 window
= create_window();
8515 ddraw
= create_ddraw();
8516 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8517 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8519 skip("Failed to create a 3D device, skipping test.\n");
8520 DestroyWindow(window
);
8521 IDirectDraw_Release(ddraw
);
8525 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8526 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8528 material
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
8529 viewport
= create_viewport(device
, 0, 0, 640, 480);
8530 viewport_set_background(device
, viewport
, material
);
8532 memset(&exec_desc
, 0, sizeof(exec_desc
));
8533 exec_desc
.dwSize
= sizeof(exec_desc
);
8534 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
8535 exec_desc
.dwBufferSize
= 1024;
8536 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
8537 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
8538 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
8540 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture alpha channel.
8542 * The vertex alpha is completely ignored in this case, so case 1 and 2 combined are not
8543 * a D3DTOP_MODULATE with texture alpha = 0xff in case 2 (no alpha in texture). */
8544 memset(&ddsd
, 0, sizeof(ddsd
));
8545 ddsd
.dwSize
= sizeof(ddsd
);
8546 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8547 ddsd
.dwHeight
= 128;
8549 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8550 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8551 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8552 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
8553 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
8554 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
8555 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
8556 ddsd
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
8557 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8558 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8560 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8561 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8562 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8563 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8565 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8566 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8568 memset(&fx
, 0, sizeof(fx
));
8569 fx
.dwSize
= sizeof(fx
);
8570 fx
.dwFillColor
= 0xff0000ff;
8571 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8572 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8573 fx
.dwFillColor
= 0x800000ff;
8574 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8575 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8577 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8578 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8580 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
8582 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8583 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8584 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
8585 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
8586 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
8587 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
8588 /* The history of D3DRENDERSTATE_ALPHABLENDENABLE is quite a mess. In the
8589 * first D3D release there was a D3DRENDERSTATE_BLENDENABLE (enum value 27).
8590 * D3D5 introduced a new and separate D3DRENDERSTATE_ALPHABLENDENABLE (42)
8591 * together with D3DRENDERSTATE_COLORKEYENABLE (41). The docs aren't all
8592 * that clear but they mention that D3DRENDERSTATE_BLENDENABLE overrides the
8594 * Then D3D6 came and got rid of the new D3DRENDERSTATE_ALPHABLENDENABLE
8595 * state (42), renaming the older D3DRENDERSTATE_BLENDENABLE enum (27)
8596 * as D3DRENDERSTATE_ALPHABLENDENABLE.
8597 * There is a comment in the D3D6 docs which mentions that hardware
8598 * rasterizers always used D3DRENDERSTATE_BLENDENABLE to just toggle alpha
8599 * blending while prior to D3D5 software rasterizers toggled both color
8600 * keying and alpha blending according to it. What I gather is that, from
8601 * D3D6 onwards, D3DRENDERSTATE_ALPHABLENDENABLE always only toggles the
8602 * alpha blending state.
8603 * These tests seem to show that actual, current hardware follows the D3D6
8604 * behavior even when using the original D3D interfaces, for the HAL device
8606 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8607 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
8608 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8610 /* SPECULARENABLE shouldn't matter in this test, but WARP begs to
8611 * differ. In the event that color keying is randomly on (see comments
8612 * in test_ck_default for reference), WARP will randomly discard
8613 * fragments based on something, even though texture and diffuse color
8614 * alpha components are non-zero. Setting SPECULARENABLE to FALSE
8615 * prevents this in some cases - presumably WARP multiplies the
8616 * specular color "alpha" channel into the final result and then
8617 * alpha tests the result. Since the specular property normally does
8618 * not have an alpha component the actual specular color we set in
8619 * the vertex data above does not matter. Setting FOGENABLE = FALSE
8620 * does not help either (specular alpha can contain a per-vertex fog
8621 * factor. Doesn't seem to matter here). */
8622 emit_set_rs(&ptr
, D3DRENDERSTATE_SPECULARENABLE
, FALSE
);
8624 emit_tquad(&ptr
, 0);
8625 emit_tquad(&ptr
, 4);
8628 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8629 inst_length
-= sizeof(test1_quads
);
8630 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8631 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8632 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8634 hr
= IDirect3DDevice_BeginScene(device
);
8635 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8636 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8637 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8638 hr
= IDirect3DDevice_EndScene(device
);
8639 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8641 /* The above SPECULARENABLE = FALSE on WARP matters here.*/
8642 color
= get_surface_color(rt
, 5, 5);
8643 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8644 color
= get_surface_color(rt
, 400, 5);
8645 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8646 color
= get_surface_color(rt
, 5, 245);
8647 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
8648 color
= get_surface_color(rt
, 400, 245);
8649 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
8651 IDirect3DTexture_Release(texture
);
8652 ref
= IDirectDrawSurface_Release(surface
);
8653 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8655 /* Test alpha with texture that has no alpha channel - alpha should be taken from diffuse vertex color. */
8656 memset(&ddsd
, 0, sizeof(ddsd
));
8657 ddsd
.dwSize
= sizeof(ddsd
);
8658 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8659 ddsd
.dwHeight
= 128;
8661 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8662 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8663 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8664 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
8665 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
8666 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
8667 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
8669 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8670 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8672 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8673 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8674 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8675 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8677 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8678 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8680 fx
.dwFillColor
= 0xff0000ff;
8681 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8682 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8683 fx
.dwFillColor
= 0x800000ff;
8684 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8685 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8687 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8688 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8690 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8691 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8692 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8694 emit_tquad(&ptr
, 0);
8695 emit_tquad(&ptr
, 4);
8698 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8699 inst_length
-= sizeof(test1_quads
);
8700 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8701 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8702 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8704 hr
= IDirect3DDevice_BeginScene(device
);
8705 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8706 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8707 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8708 hr
= IDirect3DDevice_EndScene(device
);
8709 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8711 /* Despite our best efforts at not making color keying randomly triggering, those
8712 * four broken() results occur every now and then on WARP. Presumably the non-
8713 * existent alpha channel sometimes samples 0.0 instead of the expected 1.0. */
8714 color
= get_surface_color(rt
, 5, 5);
8715 ok(compare_color(color
, 0x000000ff, 2)
8716 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8717 "Got unexpected color 0x%08x.\n", color
);
8718 color
= get_surface_color(rt
, 400, 5);
8719 ok(compare_color(color
, 0x000000ff, 2)
8720 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8721 "Got unexpected color 0x%08x.\n", color
);
8722 color
= get_surface_color(rt
, 5, 245);
8723 ok(compare_color(color
, 0x00000080, 2)
8724 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8725 "Got unexpected color 0x%08x.\n", color
);
8726 color
= get_surface_color(rt
, 400, 245);
8727 ok(compare_color(color
, 0x00000080, 2)
8728 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x00000000, 2)),
8729 "Got unexpected color 0x%08x.\n", color
);
8731 IDirect3DTexture_Release(texture
);
8732 ref
= IDirectDrawSurface_Release(surface
);
8733 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8735 /* Test RGB - should multiply color components from diffuse vertex color and texture. */
8736 memset(&ddsd
, 0, sizeof(ddsd
));
8737 ddsd
.dwSize
= sizeof(ddsd
);
8738 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8739 ddsd
.dwHeight
= 128;
8741 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8742 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8743 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8744 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 32;
8745 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
8746 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
8747 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
8748 ddsd
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
8749 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8750 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8752 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8753 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8754 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8755 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8757 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8758 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8760 fx
.dwFillColor
= 0x00ffffff;
8761 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8762 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8763 fx
.dwFillColor
= 0x00ffff80;
8764 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8765 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8767 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8768 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8770 memcpy(exec_desc
.lpData
, test2_quads
, sizeof(test2_quads
));
8772 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test2_quads
);
8773 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8774 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
8775 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8777 emit_tquad(&ptr
, 0);
8778 emit_tquad(&ptr
, 4);
8781 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8782 inst_length
-= sizeof(test2_quads
);
8783 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8784 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8785 set_execute_data(execute_buffer
, 8, sizeof(test2_quads
), inst_length
);
8787 hr
= IDirect3DDevice_BeginScene(device
);
8788 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8789 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8790 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8791 hr
= IDirect3DDevice_EndScene(device
);
8792 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8794 /* WARP (Win8 testbot) emulates color keying with the alpha channel like Wine does,
8795 * but even applies it when there's no color key assigned. The surface alpha is zero
8796 * here, so nothing gets drawn.
8798 * The ddraw2 version of this test draws these quads with color keying off due to
8799 * different defaults in ddraw1 and ddraw2. */
8800 color
= get_surface_color(rt
, 5, 5);
8801 ok(compare_color(color
, 0x00ff0040, 2) || broken(compare_color(color
, 0x00000000, 1)),
8802 "Got unexpected color 0x%08x.\n", color
);
8803 color
= get_surface_color(rt
, 400, 5);
8804 ok(compare_color(color
, 0x00ff0080, 2) || broken(compare_color(color
, 0x00000000, 1)),
8805 "Got unexpected color 0x%08x.\n", color
);
8806 color
= get_surface_color(rt
, 5, 245);
8807 ok(compare_color(color
, 0x00800080, 2) || broken(compare_color(color
, 0x00000000, 1)),
8808 "Got unexpected color 0x%08x.\n", color
);
8809 color
= get_surface_color(rt
, 400, 245);
8810 ok(compare_color(color
, 0x008000ff, 2) || broken(compare_color(color
, 0x00000000, 1)),
8811 "Got unexpected color 0x%08x.\n", color
);
8813 IDirect3DTexture_Release(texture
);
8814 ref
= IDirectDrawSurface_Release(surface
);
8815 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8817 /* Test alpha again, now with color keyed texture (colorkey emulation in wine can interfere). */
8818 memset(&ddsd
, 0, sizeof(ddsd
));
8819 ddsd
.dwSize
= sizeof(ddsd
);
8820 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
8821 ddsd
.dwHeight
= 128;
8823 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
8824 ddsd
.ddpfPixelFormat
.dwSize
= sizeof(ddsd
.ddpfPixelFormat
);
8825 ddsd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8826 ddsd
.ddpfPixelFormat
.dwRGBBitCount
= 16;
8827 ddsd
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
8828 ddsd
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
8829 ddsd
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
8831 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
8832 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8834 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
8835 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
8836 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
8837 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
8839 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8840 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#lx.\n", hr
);
8842 fx
.dwFillColor
= 0xf800;
8843 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8844 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8845 fx
.dwFillColor
= 0x001f;
8846 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8847 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#lx.\n", hr
);
8849 ckey
.dwColorSpaceLowValue
= 0x001f;
8850 ckey
.dwColorSpaceHighValue
= 0x001f;
8851 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
8852 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
8854 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
8855 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
8857 memcpy(exec_desc
.lpData
, test1_quads
, sizeof(test1_quads
));
8859 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(test1_quads
);
8860 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
8861 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
8862 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
8863 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
8864 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
8865 * testbot. This is either the fault of Windows 8 or the WARP driver.
8866 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
8867 * devices only, which might imply this doesn't actually do anything on
8869 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
8871 emit_tquad(&ptr
, 0);
8872 emit_tquad(&ptr
, 4);
8875 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
8876 inst_length
-= sizeof(test1_quads
);
8877 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
8878 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
8879 set_execute_data(execute_buffer
, 8, sizeof(test1_quads
), inst_length
);
8881 hr
= IDirect3DDevice_BeginScene(device
);
8882 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
8883 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
8884 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
8885 hr
= IDirect3DDevice_EndScene(device
);
8886 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
8888 /* Allow broken WARP results (colorkey disabled). */
8889 color
= get_surface_color(rt
, 5, 5);
8890 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x000000ff, 2)),
8891 "Got unexpected color 0x%08x.\n", color
);
8892 color
= get_surface_color(rt
, 400, 5);
8893 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
8894 color
= get_surface_color(rt
, 5, 245);
8895 ok(compare_color(color
, 0x00000000, 2) || broken(compare_color(color
, 0x00000080, 2)),
8896 "Got unexpected color 0x%08x.\n", color
);
8897 color
= get_surface_color(rt
, 400, 245);
8898 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
8900 IDirect3DTexture_Release(texture
);
8901 ref
= IDirectDrawSurface_Release(surface
);
8902 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8904 ref
= IDirect3DExecuteBuffer_Release(execute_buffer
);
8905 ok(ref
== 0, "Execute buffer not properly released, refcount %lu.\n", ref
);
8906 destroy_viewport(device
, viewport
);
8907 ref
= IDirect3DMaterial_Release(material
);
8908 ok(ref
== 0, "Material not properly released, refcount %lu.\n", ref
);
8909 IDirectDrawSurface_Release(rt
);
8910 IDirect3DDevice_Release(device
);
8911 ref
= IDirectDraw_Release(ddraw
);
8912 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8913 DestroyWindow(window
);
8916 static void test_viewport_clear_rect(void)
8919 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8920 static D3DRECT clear_rect2
= {{90}, {90}, {110}, {110}};
8921 IDirectDrawSurface
*rt
;
8925 IDirect3DDevice
*device
;
8926 IDirect3DMaterial
*red
, *green
;
8927 IDirect3DViewport
*viewport
, *viewport2
;
8930 window
= create_window();
8931 ddraw
= create_ddraw();
8932 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8933 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
8935 skip("Failed to create a 3D device, skipping test.\n");
8936 DestroyWindow(window
);
8937 IDirectDraw_Release(ddraw
);
8941 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
8942 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
8944 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8945 viewport
= create_viewport(device
, 0, 0, 640, 480);
8946 viewport_set_background(device
, viewport
, red
);
8947 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8948 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8950 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
8951 viewport2
= create_viewport(device
, 100, 100, 20, 20);
8952 viewport_set_background(device
, viewport2
, green
);
8953 hr
= IDirect3DViewport_Clear(viewport2
, 1, &clear_rect2
, D3DCLEAR_TARGET
);
8954 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
8956 color
= get_surface_color(rt
, 85, 85); /* Outside both. */
8957 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8958 color
= get_surface_color(rt
, 95, 95); /* Outside vp, inside rect. */
8959 /* AMD GPUs ignore the viewport dimensions and only care about the rectangle. */
8960 ok(compare_color(color
, 0x00ff0000, 1) || broken(compare_color(color
, 0x0000ff00, 1)),
8961 "Got unexpected color 0x%08x.\n", color
);
8962 color
= get_surface_color(rt
, 105, 105); /* Inside both. */
8963 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
8964 color
= get_surface_color(rt
, 115, 115); /* Inside vp, outside rect. */
8965 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8966 color
= get_surface_color(rt
, 125, 125); /* Outside both. */
8967 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8969 destroy_viewport(device
, viewport2
);
8970 destroy_material(green
);
8971 destroy_viewport(device
, viewport
);
8972 destroy_material(red
);
8973 IDirectDrawSurface_Release(rt
);
8974 IDirect3DDevice_Release(device
);
8975 ref
= IDirectDraw_Release(ddraw
);
8976 ok(!ref
, "Unexpected refcount %lu.\n", ref
);
8977 DestroyWindow(window
);
8980 static void test_color_fill(void)
8983 IDirect3DDevice
*device
;
8985 IDirectDrawSurface
*surface
, *surface2
;
8986 DDSURFACEDESC surface_desc
;
8987 unsigned int i
, *color
;
8992 RECT rect
= {5, 5, 7, 7};
8993 DWORD num_fourcc_codes
, *fourcc_codes
;
8995 BOOL support_uyvy
= FALSE
, support_yuy2
= FALSE
;
8999 HRESULT colorfill_hr
, depthfill_hr
;
9002 unsigned int result
;
9004 DDPIXELFORMAT format
;
9009 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9010 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9012 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9013 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9017 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9018 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9020 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9021 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9025 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9026 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9028 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9029 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9033 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9034 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9036 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9037 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9041 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
,
9042 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9043 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9046 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9047 * different afterwards. DX9+ GPUs set one of the two luminance values
9048 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9049 * value they set. r200 (dx8) just sets the entire block to the clear
9051 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9052 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9054 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9055 {0}, {0}, {0}, {0}, {0}
9059 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9060 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9062 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9063 {0}, {0}, {0}, {0}, {0}
9067 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9068 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9070 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9071 {0}, {0}, {0}, {0}, {0}
9075 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
,
9076 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9078 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9079 {0}, {0}, {0}, {0}, {0}
9083 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
9084 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
9086 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9087 {0}, {0}, {0}, {0}, {0}
9091 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
9092 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
9094 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9095 {0}, {0}, {0}, {0}, {0}
9099 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
9100 * surface works, presumably because it is handled by the runtime instead of
9102 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
9103 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
9105 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9106 {8}, {0}, {0}, {0}, {0}
9110 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
9111 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
9113 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9114 {8}, {0}, {0}, {0}, {0}
9126 {SRCCOPY
, "SRCCOPY", DD_OK
},
9127 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9128 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9129 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9130 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9131 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9132 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9133 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9134 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9135 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9136 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9137 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9138 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9139 {BLACKNESS
, "BLACKNESS", DD_OK
},
9140 {WHITENESS
, "WHITENESS", DD_OK
},
9141 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9144 window
= create_window();
9145 ddraw
= create_ddraw();
9146 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9147 is_warp
= ddraw_is_warp(ddraw
);
9148 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9150 skip("Failed to create a 3D device, skipping test.\n");
9151 DestroyWindow(window
);
9152 IDirectDraw_Release(ddraw
);
9156 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9157 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9158 fourcc_codes
= calloc(num_fourcc_codes
, sizeof(*fourcc_codes
));
9161 hr
= IDirectDraw_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9162 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9163 for (i
= 0; i
< num_fourcc_codes
; i
++)
9165 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9166 support_yuy2
= TRUE
;
9167 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9168 support_uyvy
= TRUE
;
9172 memset(&hal_caps
, 0, sizeof(hal_caps
));
9173 hal_caps
.dwSize
= sizeof(hal_caps
);
9174 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
9175 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9177 if ((!support_yuy2
&& !support_uyvy
) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9178 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9180 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9182 DWORD expected_broken
= tests
[i
].result
;
9183 unsigned int mask
= 0xffffffffu
;
9185 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9186 memset(&fx
, 0, sizeof(fx
));
9187 fx
.dwSize
= sizeof(fx
);
9188 fx
.dwFillColor
= 0xdeadbeef;
9190 memset(&surface_desc
, 0, sizeof(surface_desc
));
9191 surface_desc
.dwSize
= sizeof(surface_desc
);
9192 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9193 surface_desc
.dwWidth
= 64;
9194 surface_desc
.dwHeight
= 64;
9195 surface_desc
.ddpfPixelFormat
= tests
[i
].format
;
9196 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9198 if (tests
[i
].caps
& DDSCAPS_TEXTURE
)
9200 struct format_support_check check
= {&tests
[i
].format
, FALSE
};
9201 hr
= IDirect3DDevice_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
9202 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
9203 if (!check
.supported
)
9207 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !support_yuy2
)
9209 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !support_uyvy
)
9211 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9214 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9216 surface_desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
9217 surface_desc
.dwFlags
|= DDSD_ZBUFFERBITDEPTH
;
9218 surface_desc
.dwZBufferBitDepth
= get_device_z_depth(device
);
9219 mask
>>= (32 - surface_desc
.dwZBufferBitDepth
);
9220 /* Some drivers seem to convert depth values incorrectly or not at
9221 * all. Affects at least AMD PALM, 8.17.10.1247. */
9222 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9227 expected
= tests
[i
].result
& mask
;
9228 f
= ceilf(logf(expected
+ 1.0f
) / logf(2.0f
));
9229 g
= (f
+ 1.0f
) / 2.0f
;
9231 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9232 expected_broken
*= 0x01010101;
9236 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9237 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9239 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9240 todo_wine_if (tests
[i
].format
.dwFourCC
)
9241 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9242 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9244 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9245 todo_wine_if (tests
[i
].format
.dwFourCC
)
9246 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9247 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9249 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9251 memset(&surface_desc
, 0, sizeof(surface_desc
));
9252 surface_desc
.dwSize
= sizeof(surface_desc
);
9253 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9254 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9255 color
= surface_desc
.lpSurface
;
9256 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9257 *color
, tests
[i
].result
, tests
[i
].name
);
9258 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9259 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9262 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9263 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9264 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9265 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9266 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#lx, expected %#lx, surface %s.\n",
9267 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9269 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9271 memset(&surface_desc
, 0, sizeof(surface_desc
));
9272 surface_desc
.dwSize
= sizeof(surface_desc
);
9273 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9274 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9275 color
= surface_desc
.lpSurface
;
9276 todo_wine_if(tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
&& surface_desc
.dwZBufferBitDepth
!= 16)
9277 ok((*color
& mask
) == (tests
[i
].result
& mask
) || broken((*color
& mask
) == (expected_broken
& mask
))
9278 || broken(is_warp
&& (*color
& mask
) == (~0u & mask
)) /* Windows 8+ testbot. */,
9279 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9280 *color
& mask
, tests
[i
].result
& mask
, tests
[i
].name
);
9281 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9282 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9285 fx
.dwFillColor
= 0xdeadbeef;
9286 fx
.dwROP
= BLACKNESS
;
9287 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9288 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
9289 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9290 ok(fx
.dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
9291 fx
.dwFillColor
, tests
[i
].name
);
9293 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9295 memset(&surface_desc
, 0, sizeof(surface_desc
));
9296 surface_desc
.dwSize
= sizeof(surface_desc
);
9297 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9298 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9299 color
= surface_desc
.lpSurface
;
9300 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
9301 *color
, tests
[i
].name
);
9302 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9303 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9306 fx
.dwROP
= WHITENESS
;
9307 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9308 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#lx, expected %s, surface %s.\n",
9309 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9310 ok(fx
.dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08lx, surface %s\n",
9311 fx
.dwFillColor
, tests
[i
].name
);
9313 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9315 memset(&surface_desc
, 0, sizeof(surface_desc
));
9316 surface_desc
.dwSize
= sizeof(surface_desc
);
9317 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9318 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9319 color
= surface_desc
.lpSurface
;
9320 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
9321 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
9322 *color
, tests
[i
].name
);
9323 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
9324 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, surface %s.\n", hr
, tests
[i
].name
);
9327 IDirectDrawSurface_Release(surface
);
9330 memset(&fx
, 0, sizeof(fx
));
9331 fx
.dwSize
= sizeof(fx
);
9332 fx
.dwFillColor
= 0xdeadbeef;
9333 fx
.dwROP
= WHITENESS
;
9335 memset(&surface_desc
, 0, sizeof(surface_desc
));
9336 surface_desc
.dwSize
= sizeof(surface_desc
);
9337 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9338 surface_desc
.dwWidth
= 64;
9339 surface_desc
.dwHeight
= 64;
9340 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
9341 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9342 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9343 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9344 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9345 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9346 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
9347 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9348 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9349 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9350 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9353 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
9354 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9355 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
9356 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9358 /* Unused source rectangle. */
9359 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9360 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9361 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9362 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9364 /* Unused source surface. */
9365 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9366 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9367 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9368 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9369 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9370 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9371 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9372 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9374 /* Inverted destination or source rectangle. */
9375 SetRect(&rect
, 5, 7, 7, 5);
9376 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9377 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9378 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9379 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9380 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9381 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9382 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9383 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9384 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9385 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9387 /* Negative rectangle. */
9388 SetRect(&rect
, -1, -1, 5, 5);
9389 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9390 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9391 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9392 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9393 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9394 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9395 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9396 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9397 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9398 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9400 /* Out of bounds rectangle. */
9401 SetRect(&rect
, 0, 0, 65, 65);
9402 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9403 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9404 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9405 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9407 /* Combine multiple flags. */
9408 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9409 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9410 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9411 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9412 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9413 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9415 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
9417 fx
.dwROP
= rops
[i
].rop
;
9418 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9419 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#lx for rop %s.\n", hr
, rops
[i
].name
);
9422 IDirectDrawSurface_Release(surface2
);
9423 IDirectDrawSurface_Release(surface
);
9425 memset(&surface_desc
, 0, sizeof(surface_desc
));
9426 surface_desc
.dwSize
= sizeof(surface_desc
);
9427 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_ZBUFFERBITDEPTH
;
9428 surface_desc
.dwWidth
= 64;
9429 surface_desc
.dwHeight
= 64;
9430 surface_desc
.dwZBufferBitDepth
= get_device_z_depth(device
);
9431 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
9432 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9433 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9434 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
9435 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9438 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
9439 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9441 /* Unused source rectangle. */
9442 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9443 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9445 /* Unused source surface. */
9446 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9447 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9448 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9449 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9451 /* Inverted destination or source rectangle. */
9452 SetRect(&rect
, 5, 7, 7, 5);
9453 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9454 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9455 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9456 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9457 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9458 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9459 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9460 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9462 /* Negative rectangle. */
9463 SetRect(&rect
, -1, -1, 5, 5);
9464 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9465 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9466 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9467 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
9468 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9469 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9470 hr
= IDirectDrawSurface_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9471 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9473 /* Out of bounds rectangle. */
9474 SetRect(&rect
, 0, 0, 65, 65);
9475 hr
= IDirectDrawSurface_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9476 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#lx.\n", hr
);
9478 /* Combine multiple flags. */
9479 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9480 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
9482 IDirectDrawSurface_Release(surface2
);
9483 IDirectDrawSurface_Release(surface
);
9486 IDirect3DDevice_Release(device
);
9487 refcount
= IDirectDraw_Release(ddraw
);
9488 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
9489 DestroyWindow(window
);
9492 static void test_colorkey_precision(void)
9494 static D3DTLVERTEX quad
[] =
9496 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {1.0f
}},
9497 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {0.0f
}, {0.0f
}},
9498 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {1.0f
}},
9499 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0x00000000}, {0x00000000}, {1.0f
}, {0.0f
}},
9501 unsigned int inst_length
, data
[4] = {0}, color_mask
, color
, t
, c
;
9502 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9503 IDirect3DDevice
*device
;
9505 IDirectDrawSurface
*rt
;
9506 IDirect3DViewport
*viewport
;
9507 IDirect3DExecuteBuffer
*execute_buffer
;
9508 D3DEXECUTEBUFFERDESC exec_desc
;
9512 IDirectDrawSurface
*src
, *dst
, *texture
;
9513 D3DTEXTUREHANDLE handle
;
9514 IDirect3DTexture
*d3d_texture
;
9515 IDirect3DMaterial
*green
;
9516 DDSURFACEDESC surface_desc
, lock_desc
;
9520 BOOL is_nvidia
, is_warp
;
9523 unsigned int max
, shift
, bpp
, clear
;
9531 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
9533 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9534 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
9539 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
9541 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9542 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9547 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
9549 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
9550 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
9555 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
9557 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9558 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
9563 window
= create_window();
9564 ddraw
= create_ddraw();
9565 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9566 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9568 skip("Failed to create a 3D device, skipping test.\n");
9569 DestroyWindow(window
);
9570 IDirectDraw_Release(ddraw
);
9573 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
9574 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9576 is_nvidia
= ddraw_is_nvidia(ddraw
);
9577 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
9578 * (color key doesn't match although the values are equal), and a false
9579 * positive when the color key is 0 and the texture contains the value 1.
9580 * I don't want to mark this broken unconditionally since this would
9581 * essentially disable the test on Windows. Also on random occasions
9582 * 254 == 255 and 255 != 255.*/
9583 is_warp
= ddraw_is_warp(ddraw
);
9585 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
9586 viewport
= create_viewport(device
, 0, 0, 640, 480);
9587 viewport_set_background(device
, viewport
, green
);
9589 memset(&exec_desc
, 0, sizeof(exec_desc
));
9590 exec_desc
.dwSize
= sizeof(exec_desc
);
9591 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
9592 exec_desc
.dwBufferSize
= 1024;
9593 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
9594 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
9595 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
9597 memset(&fx
, 0, sizeof(fx
));
9598 fx
.dwSize
= sizeof(fx
);
9599 memset(&lock_desc
, 0, sizeof(lock_desc
));
9600 lock_desc
.dwSize
= sizeof(lock_desc
);
9602 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
9604 if (is_nvidia
&& tests
[t
].skip_nv
)
9606 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
9610 memset(&surface_desc
, 0, sizeof(surface_desc
));
9611 surface_desc
.dwSize
= sizeof(surface_desc
);
9612 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9613 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9614 surface_desc
.dwWidth
= 4;
9615 surface_desc
.dwHeight
= 1;
9616 surface_desc
.ddpfPixelFormat
= tests
[t
].fmt
;
9617 /* Windows XP (at least with the r200 driver, other drivers untested) produces
9618 * garbage when doing color keyed texture->texture blits. */
9619 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
9620 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9621 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
9622 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9624 fx
.dwFillColor
= tests
[t
].clear
;
9625 /* On the w8 testbot (WARP driver) the blit result has different values in the
9627 color_mask
= tests
[t
].fmt
.dwRBitMask
9628 | tests
[t
].fmt
.dwGBitMask
9629 | tests
[t
].fmt
.dwBBitMask
;
9631 for (c
= 0; c
<= tests
[t
].max
; ++c
)
9633 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
9634 * texture after it has been set once... */
9635 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
9636 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9637 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9638 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9639 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
9640 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9642 hr
= IDirectDrawSurface_QueryInterface(texture
, &IID_IDirect3DTexture
, (void **)&d3d_texture
);
9643 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
9644 hr
= IDirect3DTexture_GetHandle(d3d_texture
, device
, &handle
);
9645 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
9646 IDirect3DTexture_Release(d3d_texture
);
9648 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
9649 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
9651 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
9653 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
9654 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 8);
9655 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9656 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, handle
);
9657 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATEALPHA
);
9658 /* D3DRENDERSTATE_COLORKEYENABLE is supposed to be on by default on version
9659 * 1 devices, but for some reason it randomly defaults to FALSE on the W8
9660 * testbot. This is either the fault of Windows 8 or the WARP driver.
9661 * Also D3DRENDERSTATE_COLORKEYENABLE was introduced in D3D 5 aka version 2
9662 * devices only, which might imply this doesn't actually do anything on
9664 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9666 emit_tquad(&ptr
, 0);
9667 emit_tquad(&ptr
, 4);
9668 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
9671 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
9672 inst_length
-= sizeof(quad
);
9673 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
9674 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
9675 set_execute_data(execute_buffer
, 8, sizeof(quad
), inst_length
);
9677 hr
= IDirectDrawSurface_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9678 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#lx.\n", hr
);
9680 hr
= IDirectDrawSurface_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9681 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9682 switch (tests
[t
].bpp
)
9685 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9686 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9687 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9688 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
9692 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
9693 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
9694 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
9695 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
9698 hr
= IDirectDrawSurface_Unlock(src
, 0);
9699 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9700 hr
= IDirectDrawSurface_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
9701 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
9703 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
9704 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
9705 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
9706 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9708 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
9709 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
9711 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
9712 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
9713 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
9714 switch (tests
[t
].bpp
)
9717 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9718 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9719 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9720 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9724 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
9725 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
9726 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
9727 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
9730 hr
= IDirectDrawSurface_Unlock(dst
, 0);
9731 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
9735 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9736 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
9738 if (data
[3] == tests
[t
].clear
)
9740 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
9741 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
9742 * even when a different surface is used. The blit itself doesn't draw anything,
9743 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
9744 * never be masked out by the key.
9746 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
9747 * test is disabled entirely.
9749 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
9750 * terrible on WARP. */
9751 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
9752 IDirectDrawSurface_Release(texture
);
9753 IDirectDrawSurface_Release(src
);
9754 IDirectDrawSurface_Release(dst
);
9759 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9760 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
9762 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9763 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
9765 if (c
== tests
[t
].max
)
9766 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9767 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
9769 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
9770 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
9772 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9773 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
9775 hr
= IDirect3DDevice_BeginScene(device
);
9776 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9777 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
9778 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
9779 hr
= IDirect3DDevice_EndScene(device
);
9780 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9782 color
= get_surface_color(rt
, 80, 240);
9784 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9785 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9786 color
, tests
[t
].name
, c
);
9788 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9789 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9790 color
, tests
[t
].name
, c
);
9792 color
= get_surface_color(rt
, 240, 240);
9793 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9794 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9795 color
, tests
[t
].name
, c
);
9797 color
= get_surface_color(rt
, 400, 240);
9798 if (c
== tests
[t
].max
)
9799 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
9800 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9801 color
, tests
[t
].name
, c
);
9803 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
9804 "Got unexpected color 0x%08x, format %s, c=%u.\n",
9805 color
, tests
[t
].name
, c
);
9807 IDirectDrawSurface_Release(texture
);
9809 IDirectDrawSurface_Release(src
);
9810 IDirectDrawSurface_Release(dst
);
9814 destroy_viewport(device
, viewport
);
9815 destroy_material(green
);
9816 IDirectDrawSurface_Release(rt
);
9817 IDirect3DExecuteBuffer_Release(execute_buffer
);
9818 IDirect3DDevice_Release(device
);
9819 refcount
= IDirectDraw_Release(ddraw
);
9820 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
9821 DestroyWindow(window
);
9824 static void test_range_colorkey(void)
9829 IDirectDrawSurface
*surface
;
9830 DDSURFACEDESC surface_desc
;
9834 window
= create_window();
9835 ddraw
= create_ddraw();
9836 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9837 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9838 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
9840 memset(&surface_desc
, 0, sizeof(surface_desc
));
9841 surface_desc
.dwSize
= sizeof(surface_desc
);
9842 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
9843 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9844 surface_desc
.dwWidth
= 1;
9845 surface_desc
.dwHeight
= 1;
9846 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9847 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
9848 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
9849 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
9850 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
9851 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0x00000000;
9853 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
9854 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9855 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9856 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9857 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9859 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9860 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9861 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9862 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9864 /* Same for DDSCAPS_OFFSCREENPLAIN. */
9865 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9866 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9867 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
9868 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9869 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9871 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
9872 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9873 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9874 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9876 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
9877 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
9878 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9879 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
9881 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
9882 ckey
.dwColorSpaceLowValue
= 0x00000000;
9883 ckey
.dwColorSpaceHighValue
= 0x00000001;
9884 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9885 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9887 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9888 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9889 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9890 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9892 ckey
.dwColorSpaceLowValue
= 0x00000001;
9893 ckey
.dwColorSpaceHighValue
= 0x00000000;
9894 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9895 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9897 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9898 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9899 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9900 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9902 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
9903 ckey
.dwColorSpaceLowValue
= 0x00000000;
9904 ckey
.dwColorSpaceHighValue
= 0x00000000;
9905 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9906 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
9908 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
9909 ckey
.dwColorSpaceLowValue
= 0x00000001;
9910 ckey
.dwColorSpaceHighValue
= 0x00000000;
9911 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9912 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9913 ckey
.dwColorSpaceLowValue
= 0x00000000;
9914 ckey
.dwColorSpaceHighValue
= 0x00000001;
9915 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9916 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9917 /* Range destination keys don't work either. */
9918 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
9919 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9921 /* Just to show it's not because of A, R, and G having equal values. */
9922 ckey
.dwColorSpaceLowValue
= 0x00000000;
9923 ckey
.dwColorSpaceHighValue
= 0x01010101;
9924 hr
= IDirectDrawSurface_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
9925 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#lx.\n", hr
);
9927 /* None of these operations modified the key. */
9928 hr
= IDirectDrawSurface_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9929 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
9930 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceLowValue
);
9931 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08lx.\n", ckey
.dwColorSpaceHighValue
);
9933 IDirectDrawSurface_Release(surface
);
9934 refcount
= IDirectDraw_Release(ddraw
);
9935 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
9936 DestroyWindow(window
);
9939 static void test_shademode(void)
9941 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9942 unsigned int color0
, color1
, i
, inst_length
;
9943 IDirect3DExecuteBuffer
*execute_buffer
;
9944 D3DEXECUTEBUFFERDESC exec_desc
;
9945 IDirect3DMaterial
*background
;
9946 IDirect3DViewport
*viewport
;
9947 IDirect3DDevice
*device
;
9948 IDirectDrawSurface
*rt
;
9949 const D3DLVERTEX
*quad
;
9955 static const D3DLVERTEX quad_strip
[] =
9957 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9958 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9959 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9960 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9964 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xff0000ff}},
9965 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}},
9966 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
9967 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffffffff}},
9973 unsigned int color0
, color1
;
9977 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
9978 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9979 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9980 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
9981 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x000000ff, 0x0000ff00},
9982 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
9985 window
= create_window();
9986 ddraw
= create_ddraw();
9987 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9988 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
9990 skip("Failed to create a 3D device, skipping test.\n");
9991 IDirectDraw_Release(ddraw
);
9992 DestroyWindow(window
);
9996 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
9997 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9999 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
10000 viewport
= create_viewport(device
, 0, 0, 640, 480);
10001 viewport_set_background(device
, viewport
, background
);
10003 memset(&exec_desc
, 0, sizeof(exec_desc
));
10004 exec_desc
.dwSize
= sizeof(exec_desc
);
10005 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
10006 exec_desc
.dwBufferSize
= 1024;
10007 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
10009 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
10010 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
10012 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10013 * the color fixups we have to do for FLAT shading will be dependent on that. */
10015 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10017 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
10018 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
10020 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
10021 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
10023 quad
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? quad_strip
: quad_list
;
10024 memcpy(exec_desc
.lpData
, quad
, sizeof(quad_strip
));
10025 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad_strip
);
10026 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10027 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10028 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
10029 emit_set_rs(&ptr
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10031 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
10032 if (tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
)
10033 emit_tquad(&ptr
, 0);
10035 emit_tquad_tlist(&ptr
, 0);
10037 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
10038 inst_length
-= sizeof(quad_strip
);
10040 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
10041 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
10043 hr
= IDirect3DDevice_BeginScene(device
);
10044 set_execute_data(execute_buffer
, 4, sizeof(quad_strip
), inst_length
);
10045 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
10046 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
10047 hr
= IDirect3DDevice_EndScene(device
);
10048 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
10050 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10051 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10053 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10054 * each triangle. This requires EXT_provoking_vertex or similar
10055 * functionality being available. */
10056 /* PHONG should be the same as GOURAUD, since no hardware implements
10058 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10059 i
, color0
, tests
[i
].color0
);
10060 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10061 i
, color1
, tests
[i
].color1
);
10064 IDirect3DExecuteBuffer_Release(execute_buffer
);
10065 destroy_viewport(device
, viewport
);
10066 destroy_material(background
);
10067 IDirectDrawSurface_Release(rt
);
10068 refcount
= IDirect3DDevice_Release(device
);
10069 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10070 IDirectDraw_Release(ddraw
);
10071 DestroyWindow(window
);
10074 static void test_lockrect_invalid(void)
10077 IDirectDraw
*ddraw
;
10078 IDirectDrawSurface
*surface
;
10081 DDSURFACEDESC surface_desc
;
10083 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10084 static RECT valid
[] =
10089 {120, 60, 128, 68},
10090 {60, 120, 68, 128},
10092 static RECT invalid
[] =
10094 {68, 60, 60, 68}, /* left > right */
10095 {60, 68, 68, 60}, /* top > bottom */
10096 {-8, 60, 0, 68}, /* left < surface */
10097 {60, -8, 68, 0}, /* top < surface */
10098 {-16, 60, -8, 68}, /* right < surface */
10099 {60, -16, 68, -8}, /* bottom < surface */
10100 {60, 60, 136, 68}, /* right > surface */
10101 {60, 60, 68, 136}, /* bottom > surface */
10102 {136, 60, 144, 68}, /* left > surface */
10103 {60, 136, 68, 144}, /* top > surface */
10105 static const struct
10113 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10114 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10115 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "sysmem texture", DDERR_INVALIDPARAMS
},
10116 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "vidmem texture", DDERR_INVALIDPARAMS
},
10119 window
= create_window();
10120 ddraw
= create_ddraw();
10121 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10122 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10123 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10125 memset(&hal_caps
, 0, sizeof(hal_caps
));
10126 hal_caps
.dwSize
= sizeof(hal_caps
);
10127 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, NULL
);
10128 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
10129 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
10131 skip("Required surface types not supported, skipping test.\n");
10135 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
10137 memset(&surface_desc
, 0, sizeof(surface_desc
));
10138 surface_desc
.dwSize
= sizeof(surface_desc
);
10139 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10140 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
10141 surface_desc
.dwWidth
= 128;
10142 surface_desc
.dwHeight
= 128;
10143 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10144 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10145 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
10146 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xff0000;
10147 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x00ff00;
10148 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x0000ff;
10150 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10151 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10153 hr
= IDirectDrawSurface_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
10154 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10156 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
10158 RECT
*rect
= &valid
[i
];
10160 memset(&surface_desc
, 0, sizeof(surface_desc
));
10161 surface_desc
.dwSize
= sizeof(surface_desc
);
10163 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10164 ok(SUCCEEDED(hr
), "Lock failed (%#lx) for rect %s, type %s.\n",
10165 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10167 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10168 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10171 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
10173 RECT
*rect
= &invalid
[i
];
10175 memset(&surface_desc
, 1, sizeof(surface_desc
));
10176 surface_desc
.dwSize
= sizeof(surface_desc
);
10178 hr
= IDirectDrawSurface_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10179 ok(hr
== resources
[r
].hr
, "Lock returned %#lx for rect %s, type %s.\n",
10180 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
10183 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10184 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10187 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
10190 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10191 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#lx, type %s.\n",
10192 hr
, resources
[r
].name
);
10193 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
10194 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#lx, type %s.\n",
10195 hr
, resources
[r
].name
);
10196 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10197 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10199 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10200 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#lx).\n", wine_dbgstr_rect(&valid
[0]), hr
);
10201 hr
= IDirectDrawSurface_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
10202 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#lx).\n",
10203 wine_dbgstr_rect(&valid
[0]), hr
);
10205 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
10206 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
10208 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
10209 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
10211 IDirectDrawSurface_Release(surface
);
10215 IDirectDraw_Release(ddraw
);
10216 DestroyWindow(window
);
10219 static void test_yv12_overlay(void)
10221 IDirectDrawSurface
*src_surface
, *dst_surface
;
10222 RECT rect
= {13, 17, 14, 18};
10223 unsigned int offset
, y
;
10224 unsigned char *base
;
10225 DDSURFACEDESC desc
;
10226 IDirectDraw
*ddraw
;
10230 window
= create_window();
10231 ddraw
= create_ddraw();
10232 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10233 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10234 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10236 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10238 skip("Failed to create a YV12 overlay, skipping test.\n");
10242 memset(&desc
, 0, sizeof(desc
));
10243 desc
.dwSize
= sizeof(desc
);
10244 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10245 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10247 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
10248 "Got unexpected flags %#lx.\n", desc
.dwFlags
);
10249 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
10250 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
10251 "Got unexpected caps %#lx.\n", desc
.ddsCaps
.dwCaps
);
10252 ok(desc
.dwWidth
== 256, "Got unexpected width %lu.\n", desc
.dwWidth
);
10253 ok(desc
.dwHeight
== 256, "Got unexpected height %lu.\n", desc
.dwHeight
);
10254 /* The overlay pitch seems to have 256 byte alignment. */
10255 ok(!(desc
.lPitch
& 0xff), "Got unexpected pitch %lu.\n", desc
.lPitch
);
10257 /* Fill the surface with some data for the blit test. */
10258 base
= desc
.lpSurface
;
10260 for (y
= 0; y
< desc
.dwHeight
; ++y
)
10262 memset(base
+ desc
.lPitch
* y
, 0x10, desc
.dwWidth
);
10265 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
10267 memset(base
+ desc
.lPitch
* y
, 0x20, desc
.dwWidth
);
10270 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
10272 memset(base
+ desc
.lPitch
* y
, 0x30, desc
.dwWidth
);
10275 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10276 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10278 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
10279 * other block-based formats like DXT the entire Y channel is stored in
10280 * one big chunk of memory, followed by the chroma channels. So partial
10281 * locks do not really make sense. Show that they are allowed nevertheless
10282 * and the offset points into the luminance data. */
10283 hr
= IDirectDrawSurface_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
10284 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10285 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
10286 ok(offset
== rect
.top
* desc
.lPitch
+ rect
.left
, "Got unexpected offset %u, expected %lu.\n",
10287 offset
, rect
.top
* desc
.lPitch
+ rect
.left
);
10288 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
10289 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10291 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
10293 /* Windows XP with a Radeon X1600 GPU refuses to create a second
10294 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
10295 skip("Failed to create a second YV12 surface, skipping blit test.\n");
10296 IDirectDrawSurface_Release(src_surface
);
10300 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
10301 /* VMware rejects YV12 blits. This behavior has not been seen on real
10302 * hardware yet, so mark it broken. */
10303 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#lx.\n", hr
);
10307 memset(&desc
, 0, sizeof(desc
));
10308 desc
.dwSize
= sizeof(desc
);
10309 hr
= IDirectDrawSurface_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
10310 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
10312 base
= desc
.lpSurface
;
10313 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
10314 base
+= desc
.dwHeight
* desc
.lPitch
;
10315 ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
10316 base
+= desc
.dwHeight
/ 4 * desc
.lPitch
;
10317 ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
10319 hr
= IDirectDrawSurface_Unlock(dst_surface
, NULL
);
10320 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
10323 IDirectDrawSurface_Release(dst_surface
);
10324 IDirectDrawSurface_Release(src_surface
);
10326 IDirectDraw_Release(ddraw
);
10327 DestroyWindow(window
);
10330 static BOOL
dwm_enabled(void)
10334 if (!strcmp(winetest_platform
, "wine"))
10336 if (!pDwmIsCompositionEnabled
)
10338 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
10343 static void test_offscreen_overlay(void)
10345 IDirectDrawSurface
*overlay
, *offscreen
, *primary
;
10346 DDSURFACEDESC surface_desc
;
10347 IDirectDraw
*ddraw
;
10352 window
= create_window();
10353 ddraw
= create_ddraw();
10354 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10355 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10356 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10358 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10360 skip("Failed to create a UYVY overlay, skipping test.\n");
10364 memset(&surface_desc
, 0, sizeof(surface_desc
));
10365 surface_desc
.dwSize
= sizeof(surface_desc
);
10366 surface_desc
.dwFlags
= DDSD_CAPS
;
10367 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10368 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10369 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10371 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10372 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10373 * surface prevents this by disabling the dwm. */
10374 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10375 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10376 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10377 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10379 /* Try to overlay a NULL surface. */
10380 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
10381 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10382 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
10383 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10385 /* Try to overlay an offscreen surface. */
10386 memset(&surface_desc
, 0, sizeof(surface_desc
));
10387 surface_desc
.dwSize
= sizeof(surface_desc
);
10388 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
10389 surface_desc
.dwWidth
= 64;
10390 surface_desc
.dwHeight
= 64;
10391 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10392 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10393 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10394 surface_desc
.ddpfPixelFormat
.dwFourCC
= 0;
10395 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
10396 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0xf800;
10397 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x07e0;
10398 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x001f;
10399 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
10400 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10402 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
10403 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
10404 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
10405 "Failed to update overlay, hr %#lx.\n", hr
);
10407 /* Try to overlay the primary with a non-overlay surface. */
10408 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10409 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
10410 hr
= IDirectDrawSurface_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10411 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#lx.\n", hr
);
10413 IDirectDrawSurface_Release(offscreen
);
10414 IDirectDrawSurface_Release(primary
);
10415 IDirectDrawSurface_Release(overlay
);
10417 IDirectDraw_Release(ddraw
);
10418 DestroyWindow(window
);
10421 static void test_overlay_rect(void)
10423 IDirectDrawSurface
*overlay
, *primary
= NULL
;
10424 DDSURFACEDESC surface_desc
;
10425 RECT rect
= {0, 0, 64, 64};
10426 IDirectDraw
*ddraw
;
10432 window
= create_window();
10433 ddraw
= create_ddraw();
10434 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10435 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10436 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10438 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
10440 skip("Failed to create a UYVY overlay, skipping test.\n");
10444 memset(&surface_desc
, 0, sizeof(surface_desc
));
10445 surface_desc
.dwSize
= sizeof(surface_desc
);
10446 surface_desc
.dwFlags
= DDSD_CAPS
;
10447 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
10448 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
10449 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n",hr
);
10451 /* On Windows 7, and probably Vista, UpdateOverlay() will return
10452 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
10453 * surface prevents this by disabling the dwm. */
10454 hr
= IDirectDrawSurface_GetDC(primary
, &dc
);
10455 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#lx.\n", hr
);
10456 hr
= IDirectDrawSurface_ReleaseDC(primary
, dc
);
10457 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#lx.\n", hr
);
10459 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
10462 win_skip("Cannot disable DWM, skipping overlay test.\n");
10466 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
10467 * used. This is not true in Windows Vista and earlier, but changed in
10469 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10470 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10471 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
10472 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10473 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
10474 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
10476 /* Show that the overlay position is the (top, left) coordinate of the
10477 * destination rectangle. */
10478 OffsetRect(&rect
, 32, 16);
10479 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
10480 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10481 pos_x
= -1; pos_y
= -1;
10482 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10483 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
10484 ok(pos_x
== rect
.left
, "Got unexpected pos_x %ld, expected %ld.\n", pos_x
, rect
.left
);
10485 ok(pos_y
== rect
.top
, "Got unexpected pos_y %ld, expected %ld.\n", pos_y
, rect
.top
);
10487 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
10488 * seen that the overlay overlays the whole primary(==screen). */
10489 hr2
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
10490 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#lx.\n", hr2
);
10491 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10492 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#lx.\n", hr
);
10493 if (SUCCEEDED(hr2
))
10495 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
10496 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
10500 ok(pos_x
== 32, "Got unexpected pos_x %ld.\n", pos_x
);
10501 ok(pos_y
== 16, "Got unexpected pos_y %ld.\n", pos_y
);
10504 /* The position cannot be retrieved when the overlay is not shown. */
10505 hr
= IDirectDrawSurface_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
10506 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#lx.\n", hr
);
10507 pos_x
= -1; pos_y
= -1;
10508 hr
= IDirectDrawSurface_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
10509 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#lx.\n", hr
);
10510 ok(!pos_x
, "Got unexpected pos_x %ld.\n", pos_x
);
10511 ok(!pos_y
, "Got unexpected pos_y %ld.\n", pos_y
);
10515 IDirectDrawSurface_Release(primary
);
10517 IDirectDrawSurface_Release(overlay
);
10518 IDirectDraw_Release(ddraw
);
10519 DestroyWindow(window
);
10522 static void test_blt(void)
10524 IDirectDrawSurface
*surface
, *rt
;
10525 DDSURFACEDESC surface_desc
;
10526 IDirect3DDevice
*device
;
10527 IDirectDraw
*ddraw
;
10541 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
10542 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
10543 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
10544 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
10545 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
10546 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
10547 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
10548 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
10549 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
10550 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
10553 window
= create_window();
10554 ddraw
= create_ddraw();
10555 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10556 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
10558 skip("Failed to create a 3D device, skipping test.\n");
10559 IDirectDraw_Release(ddraw
);
10560 DestroyWindow(window
);
10564 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
10565 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
10567 memset(&surface_desc
, 0, sizeof(surface_desc
));
10568 surface_desc
.dwSize
= sizeof(surface_desc
);
10569 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10570 surface_desc
.dwWidth
= 640;
10571 surface_desc
.dwHeight
= 480;
10572 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10573 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10574 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10576 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
10577 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10579 hr
= IDirectDrawSurface_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
10580 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
10582 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10584 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10585 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10586 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
10588 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10589 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10590 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#lx, expected %#lx.\n", i
, hr
, test_data
[i
].hr
);
10592 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
,
10593 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
10594 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10596 hr
= IDirectDrawSurface_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
10597 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10600 IDirectDrawSurface_Release(surface
);
10601 IDirectDrawSurface_Release(rt
);
10602 refcount
= IDirect3DDevice_Release(device
);
10603 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10604 IDirectDraw_Release(ddraw
);
10605 DestroyWindow(window
);
10608 static void test_blt_z_alpha(void)
10610 DWORD blt_flags
[] =
10614 DDBLT_ALPHADESTCONSTOVERRIDE
,
10615 DDBLT_ALPHADESTNEG
,
10616 DDBLT_ALPHADESTSURFACEOVERRIDE
,
10617 DDBLT_ALPHAEDGEBLEND
,
10620 DDBLT_ALPHASRCCONSTOVERRIDE
,
10622 DDBLT_ALPHASRCSURFACEOVERRIDE
,
10625 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
10626 DDBLT_ZBUFFERDESTOVERRIDE
,
10627 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
10628 DDBLT_ZBUFFERSRCOVERRIDE
,
10630 IDirectDrawSurface
*src_surface
, *dst_surface
;
10631 DDSURFACEDESC surface_desc
;
10632 unsigned int color
, i
;
10633 IDirectDraw
*ddraw
;
10640 window
= create_window();
10641 ddraw
= create_ddraw();
10642 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10643 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10644 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10646 memset(&pf
, 0, sizeof(pf
));
10647 pf
.dwSize
= sizeof(pf
);
10648 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10649 pf
.dwRGBBitCount
= 32;
10650 pf
.dwRBitMask
= 0x00ff0000;
10651 pf
.dwGBitMask
= 0x0000ff00;
10652 pf
.dwBBitMask
= 0x000000ff;
10653 pf
.dwRGBAlphaBitMask
= 0xff000000;
10655 memset(&surface_desc
, 0, sizeof(surface_desc
));
10656 surface_desc
.dwSize
= sizeof(surface_desc
);
10657 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10658 surface_desc
.dwWidth
= 64;
10659 surface_desc
.dwHeight
= 64;
10660 surface_desc
.ddpfPixelFormat
= pf
;
10661 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10663 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
10664 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#lx.\n", hr
);
10665 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
10666 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#lx.\n", hr
);
10668 memset(&fx
, 0, sizeof(fx
));
10669 fx
.dwSize
= sizeof(fx
);
10670 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
10671 fx
.dwZDestConstBitDepth
= 32;
10672 fx
.dwZDestConst
= 0x11111111;
10673 fx
.dwZSrcConstBitDepth
= 32;
10674 fx
.dwZSrcConst
= 0xeeeeeeee;
10675 fx
.dwAlphaEdgeBlendBitDepth
= 8;
10676 fx
.dwAlphaEdgeBlend
= 0x7f;
10677 fx
.dwAlphaDestConstBitDepth
= 8;
10678 fx
.dwAlphaDestConst
= 0xdd;
10679 fx
.dwAlphaSrcConstBitDepth
= 8;
10680 fx
.dwAlphaSrcConst
= 0x22;
10682 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
10684 fx
.dwFillColor
= 0x3300ff00;
10685 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10686 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10688 fx
.dwFillColor
= 0xccff0000;
10689 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10690 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10692 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
10693 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10695 color
= get_surface_color(dst_surface
, 32, 32);
10696 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
10699 IDirectDrawSurface_Release(dst_surface
);
10700 IDirectDrawSurface_Release(src_surface
);
10701 refcount
= IDirectDraw_Release(ddraw
);
10702 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
10703 DestroyWindow(window
);
10706 static void test_cross_device_blt(void)
10708 IDirectDrawSurface
*surface
, *surface2
, *sysmem_surface
;
10709 IDirect3DDevice
*device
, *device2
;
10710 IDirectDraw
*ddraw
, *ddraw2
;
10711 DDSURFACEDESC surface_desc
;
10712 HWND window
, window2
;
10713 unsigned int color
;
10718 window
= create_window();
10719 ddraw
= create_ddraw();
10720 if (!(device
= create_device(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
10722 skip("Failed to create a 3D device.\n");
10723 IDirectDraw_Release(ddraw
);
10724 DestroyWindow(window
);
10728 window2
= create_window();
10729 ddraw2
= create_ddraw();
10730 if (!(device2
= create_device(ddraw2
, window2
, DDSCL_NORMAL
)))
10732 skip("Failed to create a 3D device.\n");
10733 IDirectDraw_Release(ddraw2
);
10734 IDirect3DDevice_Release(device
);
10735 IDirectDraw_Release(ddraw
);
10736 DestroyWindow(window
);
10737 DestroyWindow(window2
);
10741 memset(&surface_desc
, 0, sizeof(surface_desc
));
10742 surface_desc
.dwSize
= sizeof(surface_desc
);
10743 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10744 surface_desc
.dwWidth
= 640;
10745 surface_desc
.dwHeight
= 480;
10746 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10747 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
10748 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10750 memset(&surface_desc
, 0, sizeof(surface_desc
));
10751 surface_desc
.dwSize
= sizeof(surface_desc
);
10752 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
10753 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
10754 surface_desc
.dwBackBufferCount
= 2;
10755 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10756 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10758 memset(&surface_desc
, 0, sizeof(surface_desc
));
10759 surface_desc
.dwSize
= sizeof(surface_desc
);
10760 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
10761 surface_desc
.dwWidth
= 640;
10762 surface_desc
.dwHeight
= 480;
10763 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10764 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
10765 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10766 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 16;
10767 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00007c00;
10768 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x000003e0;
10769 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x0000001f;
10770 hr
= IDirectDraw_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10771 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10773 memset(&fx
, 0, sizeof(fx
));
10774 fx
.dwSize
= sizeof(fx
);
10775 fx
.dwFillColor
= 0xff0000ff;
10776 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10777 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
10779 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10780 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10781 hr
= IDirectDrawSurface_Flip(surface
, NULL
, DDFLIP_WAIT
);
10782 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
10783 hr
= IDirectDrawSurface_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10784 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10785 color
= get_surface_color(surface
, 320, 240);
10786 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10788 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10789 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10790 color
= get_surface_color(sysmem_surface
, 320, 240);
10791 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10793 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10794 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10795 hr
= IDirectDrawSurface_IsLost(sysmem_surface
);
10796 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10798 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10799 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#lx.\n", hr
);
10800 color
= get_surface_color(sysmem_surface
, 320, 240);
10801 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
10803 IDirectDrawSurface_Release(surface2
);
10804 memset(&surface_desc
, 0, sizeof(surface_desc
));
10805 surface_desc
.dwSize
= sizeof(surface_desc
);
10806 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
10807 surface_desc
.dwWidth
= 640;
10808 surface_desc
.dwHeight
= 480;
10809 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10810 hr
= IDirectDraw_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
10811 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
10812 hr
= IDirectDrawSurface_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10813 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
10815 hr
= IDirectDrawSurface_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
10816 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#lx.\n", hr
);
10817 color
= get_surface_color(sysmem_surface
, 320, 240);
10818 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
10820 IDirectDrawSurface_Release(surface
);
10821 IDirectDrawSurface_Release(surface2
);
10822 IDirectDrawSurface_Release(sysmem_surface
);
10823 refcount
= IDirect3DDevice_Release(device
);
10824 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10825 refcount
= IDirect3DDevice_Release(device2
);
10826 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10827 IDirectDraw_Release(ddraw
);
10828 IDirectDraw_Release(ddraw2
);
10829 DestroyWindow(window
);
10830 DestroyWindow(window2
);
10833 static void test_getdc(void)
10835 IDirectDrawSurface
*surface
, *surface2
, *tmp
;
10836 DDSURFACEDESC surface_desc
, map_desc
;
10837 DDSCAPS caps
= {DDSCAPS_COMPLEX
};
10838 IDirectDraw
*ddraw
;
10839 unsigned int i
, screen_bpp
;
10844 static const struct
10847 DDPIXELFORMAT format
;
10848 BOOL getdc_supported
;
10849 HRESULT alt_result
;
10853 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10854 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
10855 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10856 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
10857 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10858 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10859 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10860 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
10861 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10862 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
10863 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
10864 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10865 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
10866 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10867 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10868 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
10869 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
10870 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10871 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
10872 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
10873 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
10874 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
10875 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
10876 * This is not implemented in wine yet, so disable the test for now.
10877 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
10878 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
10879 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
10881 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
10882 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10883 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
10884 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
10885 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
10886 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10887 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
10888 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10889 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
10890 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10891 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
10892 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10893 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
10894 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
10897 window
= create_window();
10898 ddraw
= create_ddraw();
10899 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10900 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10901 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
10903 surface_desc
.dwSize
= sizeof(surface_desc
);
10904 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
10905 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
10906 screen_bpp
= surface_desc
.ddpfPixelFormat
.dwRGBBitCount
;
10908 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
10910 memset(&surface_desc
, 0, sizeof(surface_desc
));
10911 surface_desc
.dwSize
= sizeof(surface_desc
);
10912 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10913 surface_desc
.dwWidth
= 64;
10914 surface_desc
.dwHeight
= 64;
10915 surface_desc
.ddpfPixelFormat
= test_data
[i
].format
;
10916 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10918 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10920 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10921 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
10923 skip("Failed to create surface for format %s (hr %#lx), skipping tests.\n", test_data
[i
].name
, hr
);
10928 dc
= (void *)0x1234;
10929 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
10930 if (test_data
[i
].getdc_supported
)
10931 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
|| ddraw_is_vmware(ddraw
)),
10932 "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10934 ok(FAILED(hr
), "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
10938 unsigned int width_bytes
;
10944 type
= GetObjectType(dc
);
10945 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
10946 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
10947 type
= GetObjectType(bitmap
);
10948 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#lx for format %s.\n", type
, test_data
[i
].name
);
10950 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
10951 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
10952 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
10953 dib
.dsBm
.bmType
, test_data
[i
].name
);
10954 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
10955 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
10956 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
10957 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
10958 width_bytes
= ((dib
.dsBm
.bmWidth
* test_data
[i
].format
.dwRGBBitCount
+ 31) >> 3) & ~3;
10959 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
10960 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
10961 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
10962 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
10963 ok(dib
.dsBm
.bmBitsPixel
== test_data
[i
].format
.dwRGBBitCount
,
10964 "Got unexpected bit count %d for format %s.\n",
10965 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
10966 /* Windows XP sets bmBits == NULL for formats that match the screen at least on my r200 GPU. I
10967 * suspect this applies to all HW accelerated pre-WDDM drivers because they can handle gdi access
10968 * to ddraw surfaces themselves instead of going through a sysmem DIB section. */
10969 ok(!!dib
.dsBm
.bmBits
|| broken(!pDwmIsCompositionEnabled
&& dib
.dsBm
.bmBitsPixel
== screen_bpp
),
10970 "Got unexpected bits %p for format %s.\n", dib
.dsBm
.bmBits
, test_data
[i
].name
);
10972 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %lu for format %s.\n",
10973 dib
.dsBmih
.biSize
, test_data
[i
].name
);
10974 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %ld for format %s.\n",
10975 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10976 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %ld for format %s.\n",
10977 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
10978 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
10979 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
10980 ok(dib
.dsBmih
.biBitCount
== test_data
[i
].format
.dwRGBBitCount
,
10981 "Got unexpected bit count %u for format %s.\n",
10982 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
10983 ok(dib
.dsBmih
.biCompression
== (test_data
[i
].format
.dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
10984 || broken(test_data
[i
].format
.dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
10985 "Got unexpected compression %#lx for format %s.\n",
10986 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
10987 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %lu for format %s.\n",
10988 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
10989 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %ld for format %s.\n",
10990 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
10991 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %ld for format %s.\n",
10992 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
10993 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %lu for format %s.\n",
10994 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
10995 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %lu for format %s.\n",
10996 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
10998 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11000 ok((dib
.dsBitfields
[0] == test_data
[i
].format
.dwRBitMask
11001 && dib
.dsBitfields
[1] == test_data
[i
].format
.dwGBitMask
11002 && dib
.dsBitfields
[2] == test_data
[i
].format
.dwBBitMask
)
11003 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11004 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11005 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11009 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11010 "Got unexpected colour masks 0x%08lx 0x%08lx 0x%08lx for format %s.\n",
11011 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11013 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11014 ok(!dib
.dsOffset
, "Got unexpected offset %lu for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11016 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11017 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11021 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11024 IDirectDrawSurface_Release(surface
);
11029 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11030 if (FAILED(hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11032 skip("Failed to create mip-mapped texture for format %s (hr %#lx), skipping tests.\n",
11033 test_data
[i
].name
, hr
);
11037 hr
= IDirectDrawSurface_GetAttachedSurface(surface
, &caps
, &tmp
);
11038 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11039 hr
= IDirectDrawSurface_GetAttachedSurface(tmp
, &caps
, &surface2
);
11040 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11041 IDirectDrawSurface_Release(tmp
);
11043 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11044 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11045 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11046 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11047 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11048 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11049 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11050 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11052 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11053 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11054 dc2
= (void *)0x1234;
11055 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11056 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11057 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, 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_ReleaseDC(surface
, dc
);
11061 ok(hr
== DDERR_NODC
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11063 map_desc
.dwSize
= sizeof(map_desc
);
11064 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11065 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11066 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11067 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11068 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11069 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11070 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11071 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11073 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11074 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11075 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11076 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11077 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11078 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11080 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11081 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11082 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11083 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11084 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11085 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11086 /* Geforce 9600, Windows 7 returns E_FAIL. The unlock still seems to work as intended, after-
11087 * wards the surface can be locked again. ReleaseDC() does not unlock the surface, trying to
11088 * Lock it after ReleaseDC returns DDERR_SURFACEBUSY. ddraw4 and 7 are unaffected. */
11089 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11090 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11091 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11093 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11094 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11095 hr
= IDirectDrawSurface_GetDC(surface2
, &dc2
);
11096 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11097 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc2
);
11098 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11099 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11100 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11102 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11103 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11104 hr
= IDirectDrawSurface_GetDC(surface
, &dc2
);
11105 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11106 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc2
);
11107 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11108 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11109 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11111 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11112 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11113 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11114 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11115 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11116 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11117 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11118 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11120 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11121 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11122 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11123 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11124 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11125 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11126 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11127 ok(SUCCEEDED(hr
) || broken(ddraw_is_nvidia(ddraw
) && hr
== E_FAIL
),
11128 "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11130 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11131 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11132 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11133 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11134 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11135 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11136 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11137 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11139 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11140 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11141 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11142 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11143 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11144 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11145 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11146 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11148 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11149 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11150 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11151 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11152 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11153 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11154 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11155 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11157 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11158 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11159 hr
= IDirectDrawSurface_GetDC(surface2
, &dc
);
11160 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11161 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11162 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11163 hr
= IDirectDrawSurface_ReleaseDC(surface2
, dc
);
11164 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11165 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
11166 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11168 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11169 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11170 hr
= IDirectDrawSurface_GetDC(surface
, &dc
);
11171 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11172 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11173 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11174 hr
= IDirectDrawSurface_ReleaseDC(surface
, dc
);
11175 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#lx.\n", test_data
[i
].name
, hr
);
11176 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
11177 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#lx for format %s.\n", hr
, test_data
[i
].name
);
11179 IDirectDrawSurface_Release(surface2
);
11180 IDirectDrawSurface_Release(surface
);
11183 IDirectDraw_Release(ddraw
);
11184 DestroyWindow(window
);
11187 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
11188 * The stride is honored for navigating to the next vertex. 3 floats input position
11189 * are read, and 16 bytes extra vertex data are copied around. */
11190 struct transform_input
11192 float x
, y
, z
, unused1
; /* Position data, transformed. */
11193 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
11197 struct transform_output
11200 unsigned int v1
, v2
, v3
, v4
;
11201 unsigned int unused3
, unused4
;
11204 static void test_transform_vertices(void)
11206 unsigned int inst_length
, color
;
11207 IDirect3DDevice
*device
;
11208 IDirectDrawSurface
*rt
;
11209 IDirectDraw
*ddraw
;
11213 IDirect3DViewport
*viewport
;
11214 IDirect3DExecuteBuffer
*execute_buffer
;
11215 IDirect3DMaterial
*background
;
11216 D3DEXECUTEBUFFERDESC exec_desc
;
11218 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
11219 static struct transform_input position_tests
[] =
11221 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11222 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
11223 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
11224 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
11225 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
11226 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
11228 static struct transform_input cliptest
[] =
11230 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
11231 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
11232 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11233 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
11235 static struct transform_input offscreentest
[] =
11237 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
11239 struct transform_output out
[ARRAY_SIZE(position_tests
)];
11240 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
11241 D3DTRANSFORMDATA transformdata
;
11242 static const D3DVIEWPORT vp_template
=
11244 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
11246 D3DVIEWPORT vp_data
=
11248 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
11252 static D3DMATRIX mat_scale
=
11254 2.0f
, 0.0f
, 0.0f
, 0.0f
,
11255 0.0f
, 2.0f
, 0.0f
, 0.0f
,
11256 0.0f
, 0.0f
, 2.0f
, 0.0f
,
11257 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11261 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11262 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11263 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11264 1.0f
, 0.0f
, 0.0f
, 1.0f
,
11268 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11269 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11270 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11271 0.0f
, 1.0f
, 0.0f
, 1.0f
,
11273 static const D3DLVERTEX quad
[] =
11275 {{-0.75f
},{-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11276 {{-0.75f
},{ 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11277 {{ 0.5f
}, {-0.5f
}, {0.0f
}, 0, {0xffff0000}},
11278 {{ 0.5f
}, { 0.25f
}, {0.0f
}, 0, {0xffff0000}},
11280 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11283 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
11285 out
[i
].unused3
= 0xdeadbeef;
11286 out
[i
].unused4
= 0xcafecafe;
11289 window
= create_window();
11290 ddraw
= create_ddraw();
11291 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11292 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
11294 skip("Failed to create a 3D device, skipping test.\n");
11295 IDirectDraw_Release(ddraw
);
11296 DestroyWindow(window
);
11300 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
11301 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
11303 viewport
= create_viewport(device
, 0, 0, 256, 256);
11304 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11305 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11307 memset(&transformdata
, 0, sizeof(transformdata
));
11308 transformdata
.dwSize
= sizeof(transformdata
);
11309 transformdata
.lpIn
= position_tests
;
11310 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11311 transformdata
.lpOut
= out
;
11312 transformdata
.dwOutSize
= sizeof(out
[0]);
11313 transformdata
.lpHOut
= NULL
;
11315 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11316 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11317 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11318 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11320 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11322 static const struct vec4 cmp
[] =
11324 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
11325 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
11328 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11329 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11330 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11331 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
11332 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
11333 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
11334 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
11335 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
11338 vp_data
= vp_template
;
11339 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11340 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11341 offscreen
= 0xdeadbeef;
11342 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11343 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11344 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11345 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11347 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11349 static const struct vec4 cmp
[] =
11351 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
11352 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
11354 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11355 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11356 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11361 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11362 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11363 offscreen
= 0xdeadbeef;
11364 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11365 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11366 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11367 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11368 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11370 static const struct vec4 cmp
[] =
11372 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
11373 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11375 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11376 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11377 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11380 transformdata
.lpHOut
= out_h
;
11381 offscreen
= 0xdeadbeef;
11382 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11383 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11384 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11385 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11386 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11388 static const D3DHVERTEX cmp_h
[] =
11390 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
11391 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
11392 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
11394 ok(compare_float(cmp_h
[i
].hx
, out_h
[i
].hx
, 4096)
11395 && compare_float(cmp_h
[i
].hy
, out_h
[i
].hy
, 4096)
11396 && compare_float(cmp_h
[i
].hz
, out_h
[i
].hz
, 4096)
11397 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
11398 "HVertex %u differs. Got %#lx %.8e %.8e %.8e.\n", i
,
11399 out_h
[i
].dwFlags
, out_h
[i
].hx
, out_h
[i
].hy
, out_h
[i
].hz
);
11401 /* No scheme has been found behind those return values. It seems to be
11402 * whatever data windows has when throwing the vertex away. Modify the
11403 * input test vertices to test this more. Depending on the input data
11404 * it can happen that the z coord gets written into y, or similar things. */
11407 static const struct vec4 cmp
[] =
11409 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
11410 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
11412 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11413 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11414 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11418 transformdata
.lpIn
= cliptest
;
11419 transformdata
.dwInSize
= sizeof(cliptest
[0]);
11420 offscreen
= 0xdeadbeef;
11421 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11422 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11423 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11424 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11425 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11427 static const DWORD flags
[] =
11430 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
11432 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
11434 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11437 vp_data
= vp_template
;
11438 vp_data
.dwWidth
= 10;
11439 vp_data
.dwHeight
= 1000;
11440 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11441 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11442 offscreen
= 0xdeadbeef;
11443 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11444 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11445 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11446 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11447 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11449 static const DWORD flags
[] =
11452 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
11454 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
11456 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11459 vp_data
= vp_template
;
11460 vp_data
.dwWidth
= 256;
11461 vp_data
.dwHeight
= 256;
11462 vp_data
.dvScaleX
= 1;
11463 vp_data
.dvScaleY
= 1;
11464 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11465 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11466 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
11467 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11468 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11469 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11470 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
11472 static const DWORD flags
[] =
11479 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#lx.\n", i
, out_h
[i
].dwFlags
);
11482 /* Finally try to figure out how the DWORD dwOffscreen works.
11483 * It is a logical AND of the vertices' dwFlags members. */
11484 vp_data
= vp_template
;
11485 vp_data
.dwWidth
= 5;
11486 vp_data
.dwHeight
= 5;
11487 vp_data
.dvScaleX
= 10000.0f
;
11488 vp_data
.dvScaleY
= 10000.0f
;
11489 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11490 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11491 transformdata
.lpIn
= cliptest
;
11492 offscreen
= 0xdeadbeef;
11493 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11494 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11495 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11496 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11498 offscreen
= 0xdeadbeef;
11499 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11500 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11501 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11502 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11503 offscreen
= 0xdeadbeef;
11504 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
11505 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11506 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11507 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11508 hr
= IDirect3DViewport_TransformVertices(viewport
, 3,
11509 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11510 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11511 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11513 transformdata
.lpIn
= cliptest
+ 1;
11514 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11515 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11516 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11517 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %#lx.\n", offscreen
);
11519 transformdata
.lpIn
= cliptest
+ 2;
11520 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11521 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11522 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11523 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11524 offscreen
= 0xdeadbeef;
11525 hr
= IDirect3DViewport_TransformVertices(viewport
, 2,
11526 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11527 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11528 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11530 transformdata
.lpIn
= cliptest
+ 3;
11531 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11532 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11533 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11534 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %#lx.\n", offscreen
);
11536 transformdata
.lpIn
= offscreentest
;
11537 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
11538 vp_data
= vp_template
;
11539 vp_data
.dwWidth
= 257;
11540 vp_data
.dwHeight
= 257;
11541 vp_data
.dvScaleX
= 1.0f
;
11542 vp_data
.dvScaleY
= 1.0f
;
11543 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11544 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11545 offscreen
= 0xdeadbeef;
11546 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11547 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11548 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11549 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11551 vp_data
.dwWidth
= 256;
11552 vp_data
.dwHeight
= 256;
11553 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11554 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11555 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11556 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11557 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11558 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %#lx.\n", offscreen
);
11560 /* Test the effect of Matrices.
11562 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
11563 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
11564 * the view matrix and the +1's from the world and projection matrix. */
11567 vp_data
.dwWidth
= 256;
11568 vp_data
.dwHeight
= 256;
11569 vp_data
.dvScaleX
= 5.0f
;
11570 vp_data
.dvScaleY
= 5.0f
;
11571 vp_data
.dvMinZ
= 0.0f
;
11572 vp_data
.dvMaxZ
= 1.0f
;
11573 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11574 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11576 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
11577 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11578 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat_translate1
);
11579 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11581 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
11582 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11583 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat_scale
);
11584 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11586 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
11587 ok(hr
== D3D_OK
, "Creating a matrix object failed, hr %#lx.\n", hr
);
11588 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat_translate2
);
11589 ok(hr
== D3D_OK
, "Setting a matrix object failed, hr %#lx.\n", hr
);
11591 memset(&exec_desc
, 0, sizeof(exec_desc
));
11592 exec_desc
.dwSize
= sizeof(exec_desc
);
11593 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
11594 exec_desc
.dwBufferSize
= 1024;
11595 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
11596 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
11597 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
11599 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
11600 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
11601 ptr
= (BYTE
*)exec_desc
.lpData
;
11602 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
11603 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
11604 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
11606 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
11607 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
11608 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
11610 set_execute_data(execute_buffer
, 0, 0, inst_length
);
11611 hr
= IDirect3DDevice_BeginScene(device
);
11612 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11613 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
11614 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
11615 hr
= IDirect3DDevice_EndScene(device
);
11616 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11618 transformdata
.lpIn
= position_tests
;
11619 transformdata
.dwInSize
= sizeof(position_tests
[0]);
11620 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11621 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11622 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11624 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
11626 static const struct vec4 cmp
[] =
11628 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
11629 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
11632 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
11633 "Vertex %u differs. Got %.8e %.8e %.8e %.8e.\n", i
,
11634 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
11637 /* Invalid flags. */
11638 offscreen
= 0xdeadbeef;
11639 hr
= IDirect3DViewport_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
11640 &transformdata
, 0, &offscreen
);
11641 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11642 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11644 /* NULL transform data. */
11645 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11646 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11647 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11648 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11649 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11650 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11651 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11652 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11654 /* NULL transform data and NULL dwOffscreen.
11656 * Valid transform data + NULL dwOffscreen -> crash. */
11657 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11658 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
11659 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11662 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11663 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11664 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11665 ok(!offscreen
, "Offscreen is %#lx.\n", offscreen
);
11666 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11667 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11668 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11669 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
11671 /* Invalid sizes. */
11672 offscreen
= 0xdeadbeef;
11673 transformdata
.dwSize
= sizeof(transformdata
) - 1;
11674 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11675 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11676 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11677 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11678 transformdata
.dwSize
= sizeof(transformdata
) + 1;
11679 hr
= IDirect3DViewport_TransformVertices(viewport
, 1,
11680 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
11681 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
11682 ok(offscreen
== 0xdeadbeef, "Offscreen is %#lx.\n", offscreen
);
11684 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
11685 transformdata
.dwSize
= sizeof(transformdata
);
11686 transformdata
.lpIn
= NULL
;
11687 transformdata
.lpOut
= NULL
;
11688 offscreen
= 0xdeadbeef;
11689 hr
= IDirect3DViewport_TransformVertices(viewport
, 0,
11690 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
11691 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#lx.\n", hr
);
11692 ok(offscreen
== ~0u, "Offscreen is %#lx.\n", offscreen
);
11694 /* Test how vertices are transformed by execute buffers. */
11697 vp_data
.dwWidth
= 200;
11698 vp_data
.dwHeight
= 400;
11699 vp_data
.dvScaleX
= 20.0f
;
11700 vp_data
.dvScaleY
= 50.0f
;
11701 vp_data
.dvMinZ
= 0.0f
;
11702 vp_data
.dvMaxZ
= 1.0f
;
11703 hr
= IDirect3DViewport_SetViewport(viewport
, &vp_data
);
11704 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
11706 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 0.0f
);
11707 viewport_set_background(device
, viewport
, background
);
11708 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
11709 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
11711 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
11712 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
11713 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
11714 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
11715 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
11716 emit_tquad(&ptr
, 0);
11718 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
11719 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
11720 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
11722 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
11723 hr
= IDirect3DDevice_BeginScene(device
);
11724 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
11725 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
11726 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
11727 hr
= IDirect3DDevice_EndScene(device
);
11728 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
11730 color
= get_surface_color(rt
, 128, 143);
11731 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11732 color
= get_surface_color(rt
, 132, 143);
11733 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11734 color
= get_surface_color(rt
, 128, 147);
11735 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11736 color
= get_surface_color(rt
, 132, 147);
11737 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11739 color
= get_surface_color(rt
, 177, 217);
11740 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
11741 color
= get_surface_color(rt
, 181, 217);
11742 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11743 color
= get_surface_color(rt
, 177, 221);
11744 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11745 color
= get_surface_color(rt
, 181, 221);
11746 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
11748 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
11749 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
11750 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
11751 IDirect3DExecuteBuffer_Release(execute_buffer
);
11753 IDirectDrawSurface_Release(rt
);
11754 destroy_viewport(device
, viewport
);
11755 IDirect3DMaterial_Release(background
);
11756 refcount
= IDirect3DDevice_Release(device
);
11757 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11758 IDirectDraw_Release(ddraw
);
11759 DestroyWindow(window
);
11762 static void test_display_mode_surface_pixel_format(void)
11764 unsigned int width
, height
, bpp
;
11765 IDirectDrawSurface
*surface
;
11766 DDSURFACEDESC surface_desc
;
11767 IDirectDraw
*ddraw
;
11772 if (!(ddraw
= create_ddraw()))
11774 skip("Failed to create ddraw.\n");
11778 surface_desc
.dwSize
= sizeof(surface_desc
);
11779 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
11780 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11781 width
= surface_desc
.dwWidth
;
11782 height
= surface_desc
.dwHeight
;
11784 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
11785 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
11786 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
11787 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11790 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 16)))
11792 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 24)))
11794 if (SUCCEEDED(IDirectDraw_SetDisplayMode(ddraw
, width
, height
, 32)))
11796 ok(bpp
, "Set display mode failed.\n");
11798 surface_desc
.dwSize
= sizeof(surface_desc
);
11799 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
11800 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#lx.\n", hr
);
11801 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
11802 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
11803 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11804 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
11806 memset(&surface_desc
, 0, sizeof(surface_desc
));
11807 surface_desc
.dwSize
= sizeof(surface_desc
);
11808 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
11809 surface_desc
.dwBackBufferCount
= 1;
11810 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
11811 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11812 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
11813 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11814 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
11815 ok(surface_desc
.dwWidth
== width
, "Got width %lu, expected %u.\n", surface_desc
.dwWidth
, width
);
11816 ok(surface_desc
.dwHeight
== height
, "Got height %lu, expected %u.\n", surface_desc
.dwHeight
, height
);
11817 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
11818 surface_desc
.ddpfPixelFormat
.dwFlags
);
11819 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11820 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
11821 IDirectDrawSurface_Release(surface
);
11823 memset(&surface_desc
, 0, sizeof(surface_desc
));
11824 surface_desc
.dwSize
= sizeof(surface_desc
);
11825 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11826 surface_desc
.dwWidth
= width
;
11827 surface_desc
.dwHeight
= height
;
11828 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11829 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11830 ok(hr
== D3D_OK
, "Failed to create surface, hr %#lx.\n", hr
);
11831 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
11832 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
11833 ok(surface_desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#lx.\n",
11834 surface_desc
.ddpfPixelFormat
.dwFlags
);
11835 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== bpp
, "Got bpp %lu, expected %u.\n",
11836 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
, bpp
);
11837 IDirectDrawSurface_Release(surface
);
11839 refcount
= IDirectDraw_Release(ddraw
);
11840 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
11841 DestroyWindow(window
);
11844 static void test_surface_desc_size(void)
11849 DDSURFACEDESC desc1
;
11850 DDSURFACEDESC2 desc2
;
11853 IDirectDrawSurface7
*surface7
;
11854 IDirectDrawSurface
*surface
;
11855 DDSURFACEDESC surface_desc
;
11856 HRESULT expected_hr
, hr
;
11857 IDirectDraw
*ddraw
;
11861 static const struct
11868 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
11869 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
11870 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
11872 static const unsigned int desc_sizes
[] =
11874 sizeof(DDSURFACEDESC
),
11875 sizeof(DDSURFACEDESC2
),
11876 sizeof(DDSURFACEDESC
) + 1,
11877 sizeof(DDSURFACEDESC2
) + 1,
11878 2 * sizeof(DDSURFACEDESC
),
11879 2 * sizeof(DDSURFACEDESC2
),
11880 sizeof(DDSURFACEDESC
) - 1,
11881 sizeof(DDSURFACEDESC2
) - 1,
11882 sizeof(DDSURFACEDESC
) / 2,
11883 sizeof(DDSURFACEDESC2
) / 2,
11888 sizeof(desc
) - 100,
11891 if (!(ddraw
= create_ddraw()))
11893 skip("Failed to create ddraw.\n");
11896 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
11897 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
11899 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
11901 memset(&surface_desc
, 0, sizeof(surface_desc
));
11902 surface_desc
.dwSize
= sizeof(surface_desc
);
11903 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
11904 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
11905 surface_desc
.dwHeight
= 128;
11906 surface_desc
.dwWidth
= 128;
11907 if (FAILED(IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11909 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
11912 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
11913 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface7, hr %#lx, type %s.\n", hr
, surface_caps
[i
].name
);
11915 /* GetSurfaceDesc() */
11916 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11918 memset(&desc
, 0, sizeof(desc
));
11919 desc
.dwSize
= desc_sizes
[j
];
11920 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11921 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
11922 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11923 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11925 memset(&desc
, 0, sizeof(desc
));
11926 desc
.dwSize
= desc_sizes
[j
];
11927 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
11928 hr
= IDirectDrawSurface7_GetSurfaceDesc(surface7
, &desc
.desc2
);
11929 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11930 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11934 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11936 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
11937 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
11938 DWORD expected_texture_stage
;
11940 memset(&desc
, 0, sizeof(desc
));
11941 desc
.dwSize
= desc_sizes
[j
];
11942 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11943 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11944 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
11945 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11946 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11947 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11948 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
11949 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11950 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
11951 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11954 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
11955 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11956 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
11957 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11958 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11959 todo_wine_if(!expected_texture_stage
)
11960 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11961 "Got unexpected texture stage %#lx, size %u, type %s.\n",
11962 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11963 IDirectDrawSurface_Unlock(surface
, NULL
);
11966 memset(&desc
, 0, sizeof(desc
));
11967 desc
.dwSize
= desc_sizes
[j
];
11968 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
11969 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
11970 hr
= IDirectDrawSurface7_Lock(surface7
, NULL
, &desc
.desc2
, 0, 0);
11971 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
11972 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u, type %s.\n",
11973 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
11974 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %lu, type %s.\n",
11975 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
11976 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, size %u, type %s.\n",
11977 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
11980 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %lu, size %u, type %s.\n",
11981 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
11982 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %lu, size %u, type %s.\n",
11983 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
11984 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
11985 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
11986 "Got unexpected texture stage %#lx, size %u, type %s.\n",
11987 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
11988 IDirectDrawSurface7_Unlock(surface7
, NULL
);
11992 IDirectDrawSurface7_Release(surface7
);
11993 IDirectDrawSurface_Release(surface
);
11996 /* GetDisplayMode() */
11997 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
11999 memset(&desc
, 0xcc, sizeof(desc
));
12000 desc
.dwSize
= desc_sizes
[j
];
12001 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
12002 ? DD_OK
: DDERR_INVALIDPARAMS
;
12003 hr
= IDirectDraw_GetDisplayMode(ddraw
, &desc
.desc1
);
12004 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
12007 ok(desc
.dwSize
== sizeof(DDSURFACEDESC
), "Wrong size %lu for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
12008 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
12009 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
12013 refcount
= IDirectDraw_Release(ddraw
);
12014 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12017 static void test_texture_load(void)
12019 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12020 static D3DTLVERTEX tquad
[] =
12022 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
12023 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
12024 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
12025 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
12027 D3DTEXTUREHANDLE dst_texture_handle
, src_texture_handle
;
12028 IDirectDrawSurface
*dst_surface
, *src_surface
;
12029 IDirect3DExecuteBuffer
*execute_buffer
;
12030 unsigned int inst_length
, color
;
12031 D3DEXECUTEBUFFERDESC exec_desc
;
12032 IDirect3DMaterial
*background
;
12033 IDirect3DViewport
*viewport
;
12034 DDSURFACEDESC surface_desc
;
12035 IDirect3DTexture
*texture
;
12036 IDirect3DDevice
*device
;
12037 IDirectDrawSurface
*rt
;
12038 IDirectDraw
*ddraw
;
12045 window
= create_window();
12046 ddraw
= create_ddraw();
12047 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12048 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12050 skip("Failed to create a 3D device, skipping test.\n");
12051 IDirectDraw_Release(ddraw
);
12052 DestroyWindow(window
);
12056 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
12057 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12059 background
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
12060 viewport
= create_viewport(device
, 0, 0, 640, 480);
12061 viewport_set_background(device
, viewport
, background
);
12063 memset(&exec_desc
, 0, sizeof(exec_desc
));
12064 exec_desc
.dwSize
= sizeof(exec_desc
);
12065 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
12066 exec_desc
.dwBufferSize
= 1024;
12067 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
12068 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
12069 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
12071 memset(&surface_desc
, 0, sizeof(surface_desc
));
12072 surface_desc
.dwSize
= sizeof(surface_desc
);
12073 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12074 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12075 surface_desc
.dwWidth
= 256;
12076 surface_desc
.dwHeight
= 256;
12077 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
12078 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12079 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
12080 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
12081 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
12082 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
12084 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
12085 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12086 hr
= IDirectDrawSurface_QueryInterface(src_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
12087 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
12088 hr
= IDirect3DTexture_GetHandle(texture
, device
, &src_texture_handle
);
12089 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
12090 IDirect3DTexture_Release(texture
);
12092 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
12093 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12094 hr
= IDirectDrawSurface_QueryInterface(dst_surface
, &IID_IDirect3DTexture
, (void **)&texture
);
12095 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#lx.\n", hr
);
12096 hr
= IDirect3DTexture_GetHandle(texture
, device
, &dst_texture_handle
);
12097 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#lx.\n", hr
);
12098 IDirect3DTexture_Release(texture
);
12100 memset(&fx
, 0, sizeof(fx
));
12101 fx
.dwSize
= sizeof(fx
);
12102 fx
.dwFillColor
= 0x0000ffff;
12103 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12104 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
12106 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
12107 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
12108 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
12109 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
12110 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
12111 emit_texture_load(&ptr
, dst_texture_handle
, src_texture_handle
);
12112 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, dst_texture_handle
);
12113 /* WARP randomly applies color keying without having a key set. */
12114 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
12115 emit_tquad(&ptr
, 0);
12117 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
12118 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
12119 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
12121 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12122 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12123 color
= get_surface_color(rt
, 320, 240);
12124 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
12125 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
12126 hr
= IDirect3DDevice_BeginScene(device
);
12127 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12128 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
12129 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12130 hr
= IDirect3DDevice_EndScene(device
);
12131 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12132 color
= get_surface_color(rt
, 320, 240);
12133 ok(compare_color(color
, 0x0000ffff, 1), "Got unexpected color 0x%08x.\n", color
);
12135 memset(&fx
, 0, sizeof(fx
));
12136 fx
.dwSize
= sizeof(fx
);
12137 fx
.dwFillColor
= 0x000000ff;
12138 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12139 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#lx.\n", hr
);
12141 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
12142 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#lx.\n", hr
);
12143 color
= get_surface_color(rt
, 320, 240);
12144 ok(compare_color(color
, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color
);
12145 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
12146 hr
= IDirect3DDevice_BeginScene(device
);
12147 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12148 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
12149 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12150 hr
= IDirect3DDevice_EndScene(device
);
12151 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12152 color
= get_surface_color(rt
, 320, 240);
12153 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12155 IDirectDrawSurface_Release(dst_surface
);
12156 IDirectDrawSurface_Release(src_surface
);
12157 IDirectDrawSurface_Release(rt
);
12158 IDirect3DExecuteBuffer_Release(execute_buffer
);
12159 IDirect3DMaterial_Release(background
);
12160 destroy_viewport(device
, viewport
);
12161 IDirect3DDevice_Release(device
);
12162 refcount
= IDirectDraw_Release(ddraw
);
12163 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12164 DestroyWindow(window
);
12167 static void test_ck_operation(void)
12169 IDirectDrawSurface
*src
, *dst
;
12170 IDirectDrawSurface7
*src7
, *dst7
;
12171 DDSURFACEDESC surface_desc
;
12172 unsigned int i
, *color
;
12173 IDirectDraw
*ddraw
;
12180 window
= create_window();
12181 ddraw
= create_ddraw();
12182 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12183 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12184 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
12186 memset(&surface_desc
, 0, sizeof(surface_desc
));
12187 surface_desc
.dwSize
= sizeof(surface_desc
);
12188 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12189 surface_desc
.dwWidth
= 4;
12190 surface_desc
.dwHeight
= 1;
12191 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12192 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12193 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
12194 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
12195 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
12196 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
12197 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12198 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12200 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
12201 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
12202 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
12203 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12204 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12206 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12207 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12208 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12209 color
= surface_desc
.lpSurface
;
12210 color
[0] = 0x77010203;
12211 color
[1] = 0x00010203;
12212 color
[2] = 0x77ff00ff;
12213 color
[3] = 0x00ff00ff;
12214 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
12215 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12217 for (i
= 0; i
< 2; ++i
)
12219 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12220 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12221 color
= surface_desc
.lpSurface
;
12222 color
[0] = 0xcccccccc;
12223 color
[1] = 0xcccccccc;
12224 color
[2] = 0xcccccccc;
12225 color
[3] = 0xcccccccc;
12226 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12227 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12231 hr
= IDirectDrawSurface_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
12232 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12236 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
12237 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12240 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
12241 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12242 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
12243 color
= surface_desc
.lpSurface
;
12244 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
12245 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
12246 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
12247 * color keying nor copies it. */
12248 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
12249 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
12250 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12251 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
12252 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
12253 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
12254 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
12255 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
12256 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
12257 color
[0], color
[1], color
[2], color
[3], i
);
12258 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12259 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12262 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12263 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12264 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
12265 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12267 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12268 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12269 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12271 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12272 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12273 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12274 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
12275 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12277 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
12278 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
12279 hr
= IDirectDrawSurface_GetSurfaceDesc(src
, &surface_desc
);
12280 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12281 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
12282 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
12283 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12284 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12286 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
12287 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12288 ckey
.dwColorSpaceHighValue
= 0x00000000;
12289 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12290 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12292 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12293 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12294 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12295 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12296 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12298 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12299 ckey
.dwColorSpaceHighValue
= 0x00000001;
12300 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12301 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12303 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12304 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12305 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12306 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
12307 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12309 ckey
.dwColorSpaceLowValue
= 0x000000fe;
12310 ckey
.dwColorSpaceHighValue
= 0x000000fd;
12311 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12312 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12314 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
12315 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12316 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#lx.\n", hr
);
12317 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
12318 "Got unexpected color key low=%08lx high=%08lx.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
12320 IDirectDrawSurface_Release(src
);
12321 IDirectDrawSurface_Release(dst
);
12323 /* Test source and destination keys and where they are read from. Use a surface with alpha
12324 * to avoid driver-dependent content in the X channel. */
12325 memset(&surface_desc
, 0, sizeof(surface_desc
));
12326 surface_desc
.dwSize
= sizeof(surface_desc
);
12327 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12328 surface_desc
.dwWidth
= 6;
12329 surface_desc
.dwHeight
= 1;
12330 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12331 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12332 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
= 32;
12333 surface_desc
.ddpfPixelFormat
.dwRBitMask
= 0x00ff0000;
12334 surface_desc
.ddpfPixelFormat
.dwGBitMask
= 0x0000ff00;
12335 surface_desc
.ddpfPixelFormat
.dwBBitMask
= 0x000000ff;
12336 surface_desc
.ddpfPixelFormat
.dwRGBAlphaBitMask
= 0xff000000;
12337 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
12338 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12339 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
12340 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
12342 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
12343 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
12344 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
12345 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12346 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
12347 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
12348 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
12349 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#lx.\n", hr
);
12352 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
12353 skip("Failed to set destination color key, skipping related tests.\n");
12357 ckey
.dwColorSpaceLowValue
= 0x000000ff;
12358 ckey
.dwColorSpaceHighValue
= 0x000000ff;
12359 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
12360 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12361 ckey
.dwColorSpaceLowValue
= 0x000000aa;
12362 ckey
.dwColorSpaceHighValue
= 0x000000aa;
12363 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12364 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12366 memset(&fx
, 0, sizeof(fx
));
12367 fx
.dwSize
= sizeof(fx
);
12368 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
12369 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
12370 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
12371 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
12373 hr
= IDirectDrawSurface_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12374 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12375 color
= surface_desc
.lpSurface
;
12376 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
12377 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
12378 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
12379 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
12380 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
12381 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
12382 hr
= IDirectDrawSurface_Unlock(src
, NULL
);
12383 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12385 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12386 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12387 color
= surface_desc
.lpSurface
;
12388 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12389 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12390 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12392 /* Test a blit without keying. */
12393 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
12394 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12396 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12397 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12398 color
= surface_desc
.lpSurface
;
12399 /* Should have copied src data unmodified to dst. */
12400 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12401 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12402 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12403 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12405 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12406 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12407 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12410 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12411 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12413 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12414 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12415 color
= surface_desc
.lpSurface
;
12416 /* Src key applied to color[0]. It is unmodified, the others are copied. */
12417 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12418 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12419 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12420 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12422 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12423 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12424 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12426 /* Src override. */
12427 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
12428 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12430 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12431 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12432 color
= surface_desc
.lpSurface
;
12433 /* Override key applied to color[5]. It is unmodified, the others are copied. */
12434 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12435 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
12436 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12437 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12439 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
12440 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12441 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12443 /* Src override AND src key. That is not supposed to work. */
12444 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
12445 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12447 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12448 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12449 color
= surface_desc
.lpSurface
;
12450 /* Ensure the destination was not changed. */
12451 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
12452 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
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 /* Use different dst colors for the dst key test. */
12457 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12458 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12459 color
[2] = 0x00001100; /* Dest key in override. */
12460 color
[3] = 0x00001100; /* Dest key in override. */
12461 color
[4] = 0x000000aa; /* Dest key in src surface. */
12462 color
[5] = 0x000000aa; /* Dest key in src surface. */
12463 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12464 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12466 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12467 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12469 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12470 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12471 color
= surface_desc
.lpSurface
;
12472 /* Dst key applied to color[4,5], they are the only changed pixels. */
12473 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12474 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12475 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12476 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12478 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12479 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12480 color
[2] = 0x00001100; /* Dest key in override. */
12481 color
[3] = 0x00001100; /* Dest key in override. */
12482 color
[4] = 0x000000aa; /* Dest key in src surface. */
12483 color
[5] = 0x000000aa; /* Dest key in src surface. */
12484 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12485 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12487 /* What happens with a QI'd newer version of the interface? It takes the key
12488 * from the destination surface. */
12489 hr
= IDirectDrawSurface_QueryInterface(src
, &IID_IDirectDrawSurface7
, (void **)&src7
);
12490 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
12491 hr
= IDirectDrawSurface_QueryInterface(dst
, &IID_IDirectDrawSurface7
, (void **)&dst7
);
12492 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#lx.\n", hr
);
12494 hr
= IDirectDrawSurface7_Blt(dst7
, NULL
, src7
, NULL
, DDBLT_KEYDEST
, &fx
);
12495 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12497 IDirectDrawSurface7_Release(dst7
);
12498 IDirectDrawSurface7_Release(src7
);
12500 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12501 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12502 color
= surface_desc
.lpSurface
;
12503 /* Dst key applied to color[0,1], they are the only changed pixels. */
12504 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
12505 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12506 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12507 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12509 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12510 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12511 color
[2] = 0x00001100; /* Dest key in override. */
12512 color
[3] = 0x00001100; /* Dest key in override. */
12513 color
[4] = 0x000000aa; /* Dest key in src surface. */
12514 color
[5] = 0x000000aa; /* Dest key in src surface. */
12515 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12516 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12518 /* Dest override key blit. */
12519 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
12520 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12522 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12523 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12524 color
= surface_desc
.lpSurface
;
12525 /* Dst key applied to color[2,3], they are the only changed pixels. */
12526 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
12527 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12528 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12529 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12531 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12532 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12533 color
[2] = 0x00001100; /* Dest key in override. */
12534 color
[3] = 0x00001100; /* Dest key in override. */
12535 color
[4] = 0x000000aa; /* Dest key in src surface. */
12536 color
[5] = 0x000000aa; /* Dest key in src surface. */
12537 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12538 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12540 /* Dest override together with surface key. Supposed to fail. */
12541 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
12542 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12544 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12545 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12546 color
= surface_desc
.lpSurface
;
12547 /* Destination is unchanged. */
12548 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12549 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
12550 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12551 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12552 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12553 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12555 /* Source and destination key. This is driver dependent. New HW treats it like
12556 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
12559 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
12560 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12562 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12563 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12564 color
= surface_desc
.lpSurface
;
12565 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
12566 * the driver applies it. */
12567 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
12568 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12569 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12570 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12572 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
12573 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
12574 color
[2] = 0x00001100; /* Dest key in override. */
12575 color
[3] = 0x00001100; /* Dest key in override. */
12576 color
[4] = 0x000000aa; /* Dest key in src surface. */
12577 color
[5] = 0x000000aa; /* Dest key in src surface. */
12578 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12579 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12582 /* Override keys without ddbltfx parameter fail */
12583 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
12584 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12585 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
12586 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12588 /* Try blitting without keys in the source surface. */
12589 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
12590 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12591 hr
= IDirectDrawSurface_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
12592 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12594 /* That fails now. Do not bother to check that the data is unmodified. */
12595 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
12596 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12598 /* Surprisingly this still works. It uses the old key from the src surface. */
12599 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12600 ok(SUCCEEDED(hr
), "Failed to blit, hr %#lx.\n", hr
);
12602 hr
= IDirectDrawSurface_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
12603 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12604 color
= surface_desc
.lpSurface
;
12605 /* Dst key applied to color[4,5], they are the only changed pixels. */
12606 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
12607 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
12608 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
12609 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
12610 hr
= IDirectDrawSurface_Unlock(dst
, NULL
);
12611 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12613 /* This returns DDERR_NOCOLORKEY as expected. */
12614 hr
= IDirectDrawSurface_GetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
12615 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#lx.\n", hr
);
12617 /* GetSurfaceDesc returns a zeroed key as expected. */
12618 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x12345678;
12619 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x12345678;
12620 hr
= IDirectDrawSurface_GetSurfaceDesc(src
, &surface_desc
);
12621 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
12622 ok(!surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
12623 && !surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
,
12624 "Got unexpected color key low=%08lx high=%08lx.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
12625 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
12627 /* Try blitting without keys in the destination surface. */
12628 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
12629 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12630 hr
= IDirectDrawSurface_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
12631 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#lx.\n", hr
);
12633 /* This is weird. It makes sense in v4 and v7, but because v1
12634 * uses the key from the src surface it makes no sense here. */
12635 hr
= IDirectDrawSurface_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
12636 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
12639 IDirectDrawSurface_Release(src
);
12640 IDirectDrawSurface_Release(dst
);
12641 refcount
= IDirectDraw_Release(ddraw
);
12642 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
12643 DestroyWindow(window
);
12646 static void test_depth_readback(void)
12648 unsigned int depth
, expected_depth
, inst_length
, max_diff
, x
, y
;
12649 IDirect3DExecuteBuffer
*execute_buffer
;
12650 IDirect3DMaterial
*blue_background
;
12651 D3DEXECUTEBUFFERDESC exec_desc
;
12652 IDirectDrawSurface
*rt
, *ds
;
12653 IDirect3DViewport
*viewport
;
12654 DDSURFACEDESC surface_desc
;
12655 IDirect3DDevice
*device
;
12656 DWORD z_depth
, z_mask
;
12657 IDirectDraw
*ddraw
;
12663 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12664 static D3DLVERTEX quad
[] =
12666 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {0xff00ff00}},
12667 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xff00ff00}},
12668 {{ 1.0f
}, {-1.0f
}, {1.0f
}, 0, {0xff00ff00}},
12669 {{ 1.0f
}, { 1.0f
}, {0.9f
}, 0, {0xff00ff00}},
12672 window
= create_window();
12673 ok(!!window
, "Failed to create a window.\n");
12674 ddraw
= create_ddraw();
12675 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12676 if (ddraw_is_nvidia(ddraw
))
12678 /* ddraw1 only has access to D16 Z buffers (and D24 ones, which are even more
12679 * broken on Nvidia), so don't even attempt to run this test on Nvidia cards
12680 * because some of them have broken D16 readback. See the ddraw7 version of
12681 * this test for a more detailed comment. */
12682 skip("Some Nvidia GPUs have broken D16 readback, skipping.\n");
12683 IDirectDraw_Release(ddraw
);
12684 DestroyWindow(window
);
12688 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12690 skip("Failed to create a D3D device, skipping tests.\n");
12691 IDirectDraw_Release(ddraw
);
12692 DestroyWindow(window
);
12696 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
12697 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12698 z_depth
= get_device_z_depth(device
);
12699 z_mask
= 0xffffffff >> (32 - z_depth
);
12700 ds
= get_depth_stencil(device
);
12702 /* Changing depth buffers is hard in d3d1, so we only test with the
12703 * initial depth buffer here. */
12705 blue_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12706 viewport
= create_viewport(device
, 0, 0, 640, 480);
12707 viewport_set_background(device
, viewport
, blue_background
);
12709 memset(&exec_desc
, 0, sizeof(exec_desc
));
12710 exec_desc
.dwSize
= sizeof(exec_desc
);
12711 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
12712 exec_desc
.dwBufferSize
= 1024;
12713 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
12714 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
12715 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
12717 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
12718 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
12720 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
12721 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(quad
);
12722 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
12723 emit_tquad(&ptr
, 0);
12726 inst_length
= ((BYTE
*)ptr
- sizeof(quad
)) - (BYTE
*)exec_desc
.lpData
;
12728 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
12729 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
12731 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
12732 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12733 hr
= IDirect3DDevice_BeginScene(device
);
12734 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
12735 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
12736 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_UNCLIPPED
);
12737 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#lx.\n", hr
);
12738 hr
= IDirect3DDevice_EndScene(device
);
12739 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
12741 memset(&surface_desc
, 0, sizeof(surface_desc
));
12742 surface_desc
.dwSize
= sizeof(surface_desc
);
12743 hr
= IDirectDrawSurface_Lock(ds
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12744 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
12746 for (y
= 60; y
< 480; y
+= 120)
12748 for (x
= 80; x
< 640; x
+= 160)
12750 ptr
= (BYTE
*)surface_desc
.lpSurface
12751 + y
* surface_desc
.lPitch
12752 + x
* (z_depth
== 16 ? 2 : 4);
12753 depth
= *((DWORD
*)ptr
) & z_mask
;
12754 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * z_mask
;
12755 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * z_mask
;
12756 ok(compare_uint(expected_depth
, depth
, max_diff
),
12757 "z_depth %lu: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
12758 z_depth
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
12762 hr
= IDirectDrawSurface_Unlock(ds
, NULL
);
12763 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
12765 IDirect3DExecuteBuffer_Release(execute_buffer
);
12766 destroy_viewport(device
, viewport
);
12767 destroy_material(blue_background
);
12768 IDirectDrawSurface_Release(ds
);
12769 IDirect3DDevice_Release(device
);
12770 refcount
= IDirectDrawSurface_Release(rt
);
12771 ok(!refcount
, "Device has %lu references left.\n", refcount
);
12772 IDirectDraw_Release(ddraw
);
12773 DestroyWindow(window
);
12776 static void test_clear(void)
12778 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
12779 IDirect3DViewport
*viewport
, *viewport2
, *viewport3
;
12780 IDirect3DMaterial
*white
, *red
, *green
, *blue
;
12781 IDirect3DDevice
*device
;
12782 IDirectDrawSurface
*rt
;
12783 unsigned int color
;
12784 IDirectDraw
*ddraw
;
12790 window
= create_window();
12791 ddraw
= create_ddraw();
12792 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12793 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
12795 skip("Failed to create a 3D device, skipping test.\n");
12796 IDirectDraw_Release(ddraw
);
12797 DestroyWindow(window
);
12800 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
12801 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
12803 viewport
= create_viewport(device
, 0, 0, 640, 480);
12805 white
= create_diffuse_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
12806 red
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
12807 green
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
12808 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
12810 viewport_set_background(device
, viewport
, white
);
12811 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12812 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12814 /* Positive x, negative y. */
12820 /* Positive x, positive y. */
12826 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
12827 * refuse negative rectangles, but it will not clear them either. */
12828 viewport_set_background(device
, viewport
, red
);
12829 hr
= IDirect3DViewport_Clear(viewport
, 2, rect
, D3DCLEAR_TARGET
);
12830 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12832 color
= get_surface_color(rt
, 160, 360);
12833 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
12834 color
= get_surface_color(rt
, 160, 120);
12835 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
12836 color
= get_surface_color(rt
, 480, 360);
12837 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
12838 color
= get_surface_color(rt
, 480, 120);
12839 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
12841 viewport_set_background(device
, viewport
, white
);
12842 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12843 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12845 /* negative x, negative y.
12846 * Also ignored, except on WARP, which clears the entire screen. */
12847 rect_negneg
.x1
= 640;
12848 rect_negneg
.y1
= 240;
12849 rect_negneg
.x2
= 320;
12850 rect_negneg
.y2
= 0;
12851 viewport_set_background(device
, viewport
, green
);
12852 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
);
12853 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12855 color
= get_surface_color(rt
, 160, 360);
12856 ok(compare_color(color
, 0x00ffffff, 0)
12857 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12858 "Got unexpected color 0x%08x.\n", color
);
12859 color
= get_surface_color(rt
, 160, 120);
12860 ok(compare_color(color
, 0x00ffffff, 0)
12861 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12862 "Got unexpected color 0x%08x.\n", color
);
12863 color
= get_surface_color(rt
, 480, 360);
12864 ok(compare_color(color
, 0x00ffffff, 0)
12865 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12866 "Got unexpected color 0x%08x.\n", color
);
12867 color
= get_surface_color(rt
, 480, 120);
12868 ok(compare_color(color
, 0x00ffffff, 0)
12869 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12870 "Got unexpected color 0x%08x.\n", color
);
12872 /* Test how the viewport affects clears. */
12873 viewport_set_background(device
, viewport
, white
);
12874 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12875 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12877 viewport2
= create_viewport(device
, 160, 120, 160, 120);
12878 viewport_set_background(device
, viewport2
, blue
);
12879 hr
= IDirect3DViewport_Clear(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
);
12880 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12882 viewport3
= create_viewport(device
, 320, 240, 320, 240);
12883 viewport_set_background(device
, viewport3
, green
);
12889 hr
= IDirect3DViewport_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12890 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12892 /* AMD drivers do not limit the clear area to the viewport rectangle in
12893 * d3d1. It works as intended on other drivers and on d3d2 and newer on
12895 color
= get_surface_color(rt
, 158, 118);
12896 ok(compare_color(color
, 0x00ffffff, 0)
12897 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12898 "(158, 118) has color 0x%08x.\n", color
);
12899 color
= get_surface_color(rt
, 162, 118);
12900 ok(compare_color(color
, 0x00ffffff, 0)
12901 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12902 "(162, 118) has color 0x%08x.\n", color
);
12903 color
= get_surface_color(rt
, 158, 122);
12904 ok(compare_color(color
, 0x00ffffff, 0)
12905 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12906 "(158, 122) has color 0x%08x.\n", color
);
12907 color
= get_surface_color(rt
, 162, 122);
12908 ok(compare_color(color
, 0x000000ff, 0)
12909 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12910 "(162, 122) has color 0x%08x.\n", color
);
12912 color
= get_surface_color(rt
, 318, 238);
12913 ok(compare_color(color
, 0x000000ff, 0)
12914 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12915 "(318, 238) has color 0x%08x.\n", color
);
12916 color
= get_surface_color(rt
, 322, 238);
12917 ok(compare_color(color
, 0x00ffffff, 0)
12918 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12919 "(322, 328) has color 0x%08x.\n", color
);
12920 color
= get_surface_color(rt
, 318, 242);
12921 ok(compare_color(color
, 0x00ffffff, 0)
12922 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
12923 "(318, 242) has color 0x%08x.\n", color
);
12924 color
= get_surface_color(rt
, 322, 242);
12925 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
12927 color
= get_surface_color(rt
, 478, 358);
12928 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
12929 color
= get_surface_color(rt
, 482, 358);
12930 ok(compare_color(color
, 0x00ffffff, 0)
12931 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12932 "(482, 358) has color 0x%08x.\n", color
);
12933 color
= get_surface_color(rt
, 478, 362);
12934 ok(compare_color(color
, 0x00ffffff, 0)
12935 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12936 "(478, 362) has color 0x%08x.\n", color
);
12937 color
= get_surface_color(rt
, 482, 362);
12938 ok(compare_color(color
, 0x00ffffff, 0)
12939 || broken(ddraw_is_amd(ddraw
) && compare_color(color
, 0x000000ff, 0)),
12940 "(482, 362) has color 0x%08x.\n", color
);
12942 /* The clear rectangle is rendertarget absolute, not relative to the
12944 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
12945 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12950 hr
= IDirect3DViewport_Clear(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
);
12951 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
12953 color
= get_surface_color(rt
, 328, 248);
12954 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
12955 color
= get_surface_color(rt
, 332, 248);
12956 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
12957 color
= get_surface_color(rt
, 328, 252);
12958 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
12959 color
= get_surface_color(rt
, 332, 252);
12960 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
12962 color
= get_surface_color(rt
, 338, 248);
12963 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
12964 color
= get_surface_color(rt
, 342, 248);
12965 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
12966 color
= get_surface_color(rt
, 338, 252);
12967 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
12968 color
= get_surface_color(rt
, 342, 252);
12969 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
12971 color
= get_surface_color(rt
, 328, 258);
12972 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
12973 color
= get_surface_color(rt
, 332, 258);
12974 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
12975 color
= get_surface_color(rt
, 328, 262);
12976 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
12977 color
= get_surface_color(rt
, 332, 262);
12978 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
12980 color
= get_surface_color(rt
, 338, 258);
12981 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
12982 color
= get_surface_color(rt
, 342, 258);
12983 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
12984 color
= get_surface_color(rt
, 338, 262);
12985 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
12986 color
= get_surface_color(rt
, 342, 262);
12987 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
12989 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
12992 IDirect3DViewport_Release(viewport3
);
12993 IDirect3DViewport_Release(viewport2
);
12994 IDirect3DViewport_Release(viewport
);
12995 IDirect3DMaterial_Release(white
);
12996 IDirect3DMaterial_Release(red
);
12997 IDirect3DMaterial_Release(green
);
12998 IDirect3DMaterial_Release(blue
);
12999 IDirectDrawSurface_Release(rt
);
13000 refcount
= IDirect3DDevice_Release(device
);
13001 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13002 refcount
= IDirectDraw_Release(ddraw
);
13003 ok(!refcount
, "Ddraw object has %lu references left.\n", refcount
);
13004 DestroyWindow(window
);
13007 struct enum_surfaces_param
13009 IDirectDraw
*ddraw
;
13010 DDSURFACEDESC modes
[20];
13011 unsigned int mode_count
;
13013 IDirectDrawSurface
*surfaces
[8];
13014 unsigned int count
;
13017 static HRESULT CALLBACK
build_mode_list_cb(DDSURFACEDESC
*desc
, void *context
)
13019 struct enum_surfaces_param
*param
= context
;
13020 IDirectDrawSurface
*surface
;
13022 if (SUCCEEDED(IDirectDraw_CreateSurface(param
->ddraw
, desc
, &surface
, NULL
)))
13024 if (param
->mode_count
< ARRAY_SIZE(param
->modes
))
13025 param
->modes
[param
->mode_count
] = *desc
;
13026 ++param
->mode_count
;
13027 IDirectDrawSurface_Release(surface
);
13030 return DDENUMRET_OK
;
13033 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
13035 struct enum_surfaces_param
*param
= context
;
13036 BOOL found
= FALSE
;
13039 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
13041 if (param
->surfaces
[i
] == surface
)
13048 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
13049 IDirectDrawSurface_Release(surface
);
13052 return DDENUMRET_OK
;
13055 static HRESULT WINAPI
enum_surfaces_create_cb(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
13057 static const DWORD expect_flags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PITCH
| DDSD_PIXELFORMAT
;
13058 struct enum_surfaces_param
*param
= context
;
13060 ok(!surface
, "Unexpected surface %p.\n", surface
);
13061 ok((desc
->dwFlags
& expect_flags
) == expect_flags
, "Got unexpected flags %#lx.\n", desc
->dwFlags
);
13062 if (param
->count
< ARRAY_SIZE(param
->modes
))
13064 const DDSURFACEDESC
*expect
= ¶m
->modes
[param
->count
];
13065 ok(desc
->dwWidth
== expect
->dwWidth
, "Expected width %lu, got %lu.\n", expect
->dwWidth
, desc
->dwWidth
);
13066 ok(desc
->dwHeight
== expect
->dwHeight
, "Expected height %lu, got %lu.\n", expect
->dwHeight
, desc
->dwHeight
);
13067 ok(!memcmp(&desc
->ddpfPixelFormat
, &expect
->ddpfPixelFormat
, sizeof(desc
->ddpfPixelFormat
)),
13068 "Pixel formats didn't match.\n");
13073 return DDENUMRET_OK
;
13076 static void test_enum_surfaces(void)
13078 struct enum_surfaces_param param
= {0};
13079 DDPIXELFORMAT current_format
;
13080 IDirectDraw
*ddraw
;
13081 DDSURFACEDESC desc
;
13084 ddraw
= create_ddraw();
13085 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13086 param
.ddraw
= ddraw
;
13088 memset(&desc
, 0, sizeof(desc
));
13089 desc
.dwSize
= sizeof(desc
);
13090 hr
= IDirectDraw_GetDisplayMode(ddraw
, &desc
);
13091 ok(hr
== DD_OK
, "Failed to get display mode, hr %#lx.\n", hr
);
13092 current_format
= desc
.ddpfPixelFormat
;
13094 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13095 ok(hr
== DD_OK
, "Failed to set cooperative level, hr %#lx.\n", hr
);
13097 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
, NULL
, NULL
, enum_surfaces_cb
);
13098 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13100 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
13101 NULL
, NULL
, enum_surfaces_cb
);
13102 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13104 memset(&desc
, 0, sizeof(desc
));
13105 desc
.dwSize
= sizeof(desc
);
13106 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
13107 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
13108 desc
.dwMipMapCount
= 3;
13110 desc
.dwHeight
= 32;
13111 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
13112 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13114 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
13115 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
13116 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
13117 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#lx.\n", hr
);
13118 hr
= IDirectDrawSurface_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
13119 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13120 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
13123 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13124 &desc
, ¶m
, enum_surfaces_cb
);
13125 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13126 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13129 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13130 NULL
, ¶m
, enum_surfaces_cb
);
13131 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13132 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13134 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
13136 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13137 &desc
, ¶m
, enum_surfaces_cb
);
13138 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13139 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13142 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_NOMATCH
,
13143 &desc
, ¶m
, enum_surfaces_cb
);
13144 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13145 ok(param
.count
== 2, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13149 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13150 &desc
, ¶m
, enum_surfaces_cb
);
13151 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13152 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13156 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
, &desc
, ¶m
, enum_surfaces_cb
);
13157 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13158 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13160 IDirectDrawSurface_Release(param
.surfaces
[2]);
13161 IDirectDrawSurface_Release(param
.surfaces
[1]);
13162 IDirectDrawSurface_Release(param
.surfaces
[0]);
13165 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
13166 NULL
, ¶m
, enum_surfaces_cb
);
13167 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13168 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13170 memset(&desc
, 0, sizeof(desc
));
13171 desc
.dwSize
= sizeof(desc
);
13172 desc
.dwFlags
= DDSD_CAPS
;
13173 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
13175 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_ALL
,
13176 &desc
, ¶m
, enum_surfaces_create_cb
);
13177 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13179 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_NOMATCH
,
13180 &desc
, ¶m
, enum_surfaces_create_cb
);
13181 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13183 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
,
13184 &desc
, ¶m
, enum_surfaces_create_cb
);
13185 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13187 /* When not passed width and height, the callback is called with every
13188 * available display resolution. */
13190 param
.mode_count
= 0;
13191 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13192 desc
.ddpfPixelFormat
= current_format
;
13193 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, &desc
, ¶m
, build_mode_list_cb
);
13194 ok(hr
== DD_OK
, "Failed to build mode list, hr %#lx.\n", hr
);
13197 desc
.dwFlags
&= ~DDSD_PIXELFORMAT
;
13198 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13199 &desc
, ¶m
, enum_surfaces_create_cb
);
13200 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13201 ok(param
.count
== param
.mode_count
, "Expected %u surfaces, got %u.\n", param
.mode_count
, param
.count
);
13203 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
13204 desc
.dwWidth
= desc
.dwHeight
= 32;
13206 param
.modes
[0].dwWidth
= param
.modes
[0].dwHeight
= 32;
13209 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13210 &desc
, ¶m
, enum_surfaces_create_cb
);
13211 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13212 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13214 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
13215 ok(hr
== DD_OK
, "Failed to create surface, hr %#lx.\n", hr
);
13217 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_MATCH
,
13218 &desc
, ¶m
, enum_surfaces_create_cb
);
13219 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13220 ok(param
.count
== 1, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13221 IDirectDrawSurface_Release(param
.surfaces
[0]);
13223 desc
.dwFlags
|= DDSD_PIXELFORMAT
;
13224 desc
.ddpfPixelFormat
.dwSize
= sizeof(desc
.ddpfPixelFormat
);
13225 desc
.ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
13226 desc
.ddpfPixelFormat
.dwFourCC
= 0xdeadbeef;
13229 hr
= IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_CANBECREATED
| DDENUMSURFACES_MATCH
,
13230 &desc
, ¶m
, enum_surfaces_create_cb
);
13231 ok(hr
== DD_OK
, "Failed to enumerate surfaces, hr %#lx.\n", hr
);
13232 ok(!param
.count
, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
13234 IDirectDraw_Release(ddraw
);
13237 static void test_execute_data(void)
13239 IDirect3DExecuteBuffer
*execute_buffer
;
13240 D3DEXECUTEBUFFERDESC exec_desc
;
13241 IDirect3DDevice
*device
;
13242 IDirectDraw
*ddraw
;
13245 D3DEXECUTEDATA exec_data
;
13247 window
= create_window();
13248 ddraw
= create_ddraw();
13249 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13250 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13252 skip("Failed to create a 3D device, skipping test.\n");
13253 IDirectDraw_Release(ddraw
);
13254 DestroyWindow(window
);
13258 memset(&exec_desc
, 0, sizeof(exec_desc
));
13259 exec_desc
.dwSize
= sizeof(exec_desc
);
13260 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13261 exec_desc
.dwBufferSize
= 1024;
13262 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13264 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13265 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
13267 memset(&exec_data
, 0, sizeof(exec_data
));
13269 /* Success case. */
13270 exec_data
.dwSize
= sizeof(exec_data
);
13271 exec_data
.dwVertexCount
= 3;
13272 exec_data
.dwInstructionOffset
= 3 * sizeof(D3DVERTEX
);
13273 exec_data
.dwInstructionLength
= 10;
13274 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13275 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13277 /* dwSize is checked against the expected struct size. */
13278 exec_data
.dwSize
= sizeof(exec_data
) - 1;
13279 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13280 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13281 exec_data
.dwSize
= sizeof(exec_data
) + 1;
13282 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13283 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13285 /* The rest of the data is not checked for plausibility. */
13286 exec_data
.dwSize
= sizeof(exec_data
);
13287 exec_data
.dwVertexCount
= 0;
13288 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13289 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13290 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
) - 1;
13291 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13292 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13293 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
);
13294 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13295 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13296 exec_data
.dwVertexCount
= exec_desc
.dwBufferSize
/ sizeof(D3DVERTEX
) + 1;
13297 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13298 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13299 exec_data
.dwVertexCount
= 999999;
13300 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13301 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13302 exec_data
.dwInstructionOffset
= 999999 * sizeof(D3DVERTEX
);
13303 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13304 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13305 exec_data
.dwInstructionLength
= 10240;
13306 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
13307 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#lx.\n", hr
);
13309 /* The input structure is not modified. */
13310 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13312 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13313 exec_data
.dwVertexCount
);
13314 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13315 exec_data
.dwInstructionOffset
);
13316 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13317 exec_data
.dwInstructionLength
);
13319 /* No validation in GetExecuteData. */
13320 memset(&exec_data
, 0, sizeof(exec_data
));
13321 exec_desc
.dwSize
= sizeof(exec_desc
);
13322 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13323 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13325 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13327 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13328 exec_data
.dwVertexCount
);
13329 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13330 exec_data
.dwInstructionOffset
);
13331 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13332 exec_data
.dwInstructionLength
);
13334 memset(&exec_data
, 0xaa, sizeof(exec_data
));
13335 exec_desc
.dwSize
= sizeof(exec_desc
) - 1;
13336 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13337 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13338 ok(exec_data
.dwSize
== sizeof(exec_data
), "Got unexpected struct size %lu.\n",
13340 ok(exec_data
.dwVertexCount
== 999999, "Got unexpected vertex count %lu.\n",
13341 exec_data
.dwVertexCount
);
13342 ok(exec_data
.dwInstructionOffset
== 999999 * sizeof(D3DVERTEX
), "Got unexpected instruction offset %lu.\n",
13343 exec_data
.dwInstructionOffset
);
13344 ok(exec_data
.dwInstructionLength
== 10240, "Got unexpected instruction length %lu.\n",
13345 exec_data
.dwInstructionLength
);
13347 exec_desc
.dwSize
= 0;
13348 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13349 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13350 exec_desc
.dwSize
= sizeof(exec_desc
) + 1;
13351 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13352 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13353 exec_desc
.dwSize
= ~0U;
13354 hr
= IDirect3DExecuteBuffer_GetExecuteData(execute_buffer
, &exec_data
);
13355 ok(SUCCEEDED(hr
), "Failed to get execute data, hr %#lx.\n", hr
);
13357 IDirect3DExecuteBuffer_Release(execute_buffer
);
13358 IDirect3DDevice_Release(device
);
13359 IDirectDraw_Release(ddraw
);
13360 DestroyWindow(window
);
13363 static void test_viewport(void)
13368 RECT expected_rect
;
13369 const char *message
;
13373 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "(0, 0) - (640, 480) viewport"},
13374 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "(0, 0) - (320, 240) viewport"},
13375 {{ 0, 0, 1280, 960}, {-10, -10, -1, -1}, "(0, 0) - (1280, 960) viewport"},
13376 {{ 0, 0, 2000, 1600}, {-10, -10, -1, -1}, "(0, 0) - (2000, 1600) viewport"},
13377 {{100, 100, 640, 480}, {-10, -10, -1, -1}, "(100, 100) - (640, 480) viewport"},
13378 {{ 0, 0, 8192, 8192}, {-10, -10, -1, -1}, "(0, 0) - (8192, 8192) viewport"},
13380 static D3DMATRIX mat
=
13382 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13383 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13384 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13385 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13387 static D3DLVERTEX quad
[] =
13389 {{-1.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
13390 {{-1.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13391 {{ 0.5f
}, {-0.5f
}, {0.1f
}, 0, {0xffffffff}},
13392 {{ 0.5f
}, { 0.5f
}, {0.1f
}, 0, {0xffffffff}},
13394 D3DMATRIXHANDLE world_handle
, view_handle
, proj_handle
;
13395 IDirect3DViewport
*viewport
, *full_viewport
;
13396 IDirect3DExecuteBuffer
*execute_buffer
;
13397 IDirect3DMaterial
*black_background
;
13398 D3DEXECUTEBUFFERDESC exec_desc
;
13399 IDirect3DDevice
*device
;
13400 IDirectDrawSurface
*rt
;
13401 IDirectDraw
*ddraw
;
13402 D3DRECT clear_rect
;
13412 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13413 0, 0, 640, 480, 0, 0, 0, 0);
13414 ddraw
= create_ddraw();
13415 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13416 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13418 skip("Failed to create a 3D device, skipping test.\n");
13419 IDirectDraw_Release(ddraw
);
13420 DestroyWindow(window
);
13424 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
13425 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
13427 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
13428 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#lx.\n", hr
);
13430 black_background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
13432 hr
= IDirect3DDevice_CreateMatrix(device
, &world_handle
);
13433 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13434 hr
= IDirect3DDevice_SetMatrix(device
, world_handle
, &mat
);
13435 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13436 hr
= IDirect3DDevice_CreateMatrix(device
, &view_handle
);
13437 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13438 hr
= IDirect3DDevice_SetMatrix(device
, view_handle
, &mat
);
13439 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13440 hr
= IDirect3DDevice_CreateMatrix(device
, &proj_handle
);
13441 ok(SUCCEEDED(hr
), "Creating a matrix object failed, hr %#lx.\n", hr
);
13442 hr
= IDirect3DDevice_SetMatrix(device
, proj_handle
, &mat
);
13443 ok(SUCCEEDED(hr
), "Setting a matrix object failed, hr %#lx.\n", hr
);
13445 memset(&exec_desc
, 0, sizeof(exec_desc
));
13446 exec_desc
.dwSize
= sizeof(exec_desc
);
13447 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13448 exec_desc
.dwBufferSize
= 1024;
13449 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13451 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13452 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#lx.\n", hr
);
13454 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13455 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#lx.\n", hr
);
13457 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13458 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13459 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_WORLD
, world_handle
);
13460 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_VIEW
, view_handle
);
13461 emit_set_ts(&ptr
, D3DTRANSFORMSTATE_PROJECTION
, proj_handle
);
13462 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13463 emit_set_rs(&ptr
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
13464 emit_set_rs(&ptr
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
13465 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, 4);
13466 emit_tquad(&ptr
, 0);
13468 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13469 inst_length
-= sizeof(quad
);
13471 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13472 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#lx.\n", hr
);
13474 full_viewport
= create_viewport(device
, 0, 0, 640, 480);
13475 viewport_set_background(device
, full_viewport
, black_background
);
13477 clear_rect
.x1
= clear_rect
.y1
= 0;
13478 clear_rect
.x2
= 640;
13479 clear_rect
.y2
= 480;
13481 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
13483 winetest_push_context("%s", tests
[j
].message
);
13485 hr
= IDirect3DViewport_Clear(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
13486 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13488 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
13489 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13490 memset(&vp
, 0, sizeof(vp
));
13491 vp
.dwSize
= sizeof(vp
);
13492 vp
.dwX
= tests
[j
].vp
.dwX
;
13493 vp
.dwY
= tests
[j
].vp
.dwY
;
13494 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
13495 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
13496 vp
.dvScaleX
= tests
[j
].vp
.dwWidth
/ 2.0f
;
13497 vp
.dvScaleY
= tests
[j
].vp
.dwHeight
/ 2.0f
;
13502 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
13503 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#lx.\n", hr
);
13504 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
13505 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13506 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
13507 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13509 hr
= IDirect3DDevice_BeginScene(device
);
13510 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13512 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
13513 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13514 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13516 hr
= IDirect3DDevice_EndScene(device
);
13517 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13519 check_rect(rt
, tests
[j
].expected_rect
);
13521 destroy_viewport(device
, viewport
);
13523 winetest_pop_context();
13526 destroy_viewport(device
, full_viewport
);
13527 IDirectDrawSurface_Release(rt
);
13529 IDirect3DExecuteBuffer_Release(execute_buffer
);
13530 IDirect3DDevice_DeleteMatrix(device
, world_handle
);
13531 IDirect3DDevice_DeleteMatrix(device
, view_handle
);
13532 IDirect3DDevice_DeleteMatrix(device
, proj_handle
);
13533 destroy_material(black_background
);
13534 refcount
= IDirect3DDevice_Release(device
);
13535 ok(!refcount
, "Device has %lu references left.\n", refcount
);
13536 IDirect3D2_Release(d3d
);
13537 IDirectDraw_Release(ddraw
);
13538 DestroyWindow(window
);
13541 static void test_find_device(void)
13543 D3DFINDDEVICESEARCH search
= {0};
13544 D3DFINDDEVICERESULT result
= {0};
13545 IDirect3DDevice
*device
;
13546 IDirectDraw
*ddraw
;
13556 D3DDEVICEDESC_V1 hw_desc
;
13557 D3DDEVICEDESC_V1 sw_desc
;
13564 D3DDEVICEDESC_V2 hw_desc
;
13565 D3DDEVICEDESC_V2 sw_desc
;
13568 static const struct
13575 {&IID_IDirect3D
, DDERR_NOTFOUND
},
13576 {&IID_IDirect3DRampDevice
, D3D_OK
},
13577 {&IID_IDirect3DRGBDevice
, D3D_OK
},
13578 {&IID_IDirect3DMMXDevice
, DDERR_NOTFOUND
},
13579 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
13580 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
13581 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
13584 ddraw
= create_ddraw();
13585 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13587 if (FAILED(IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
)))
13589 skip("D3D interface is not available, skipping test.\n");
13590 IDirectDraw_Release(ddraw
);
13594 result
.dwSize
= sizeof(result
);
13595 search
.dwSize
= sizeof(search
);
13596 hr
= IDirect3D_FindDevice(d3d
, NULL
, NULL
);
13597 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13598 hr
= IDirect3D_FindDevice(d3d
, NULL
, &result
);
13599 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13600 hr
= IDirect3D_FindDevice(d3d
, &search
, NULL
);
13601 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13602 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13603 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13604 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %lu.\n", result
.dwSize
);
13605 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v1
.hw_desc
),
13606 "Got unexpected HW desc size %lu.\n", result
.ddHwDesc
.dwSize
);
13607 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v1
.sw_desc
),
13608 "Got unexpected SW desc size %lu.\n", result
.ddSwDesc
.dwSize
);
13610 memset(&search
, 0, sizeof(search
));
13611 memset(&result
, 0, sizeof(result
));
13612 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13613 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13615 search
.dwSize
= sizeof(search
) + 1;
13616 result
.dwSize
= sizeof(result
) + 1;
13617 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13618 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
13620 search
.dwSize
= sizeof(search
);
13622 memset(&result_v1
, 0, sizeof(result_v1
));
13623 result_v1
.size
= sizeof(result_v1
);
13624 hr
= IDirect3D_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
13625 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13626 ok(result_v1
.hw_desc
.dwSize
== sizeof(result_v1
.hw_desc
),
13627 "Got unexpected HW desc size %lu.\n", result_v1
.hw_desc
.dwSize
);
13628 ok(result_v1
.sw_desc
.dwSize
== sizeof(result_v1
.sw_desc
),
13629 "Got unexpected SW desc size %lu.\n", result_v1
.sw_desc
.dwSize
);
13631 memset(&result_v2
, 0, sizeof(result_v2
));
13632 result_v2
.size
= sizeof(result_v2
);
13633 hr
= IDirect3D_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
13634 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13635 ok(result_v2
.hw_desc
.dwSize
== sizeof(result_v1
.hw_desc
),
13636 "Got unexpected HW desc size %lu.\n", result_v2
.hw_desc
.dwSize
);
13637 ok(result_v2
.sw_desc
.dwSize
== sizeof(result_v1
.sw_desc
),
13638 "Got unexpected SW desc size %lu.\n", result_v2
.sw_desc
.dwSize
);
13640 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13642 memset(&search
, 0, sizeof(search
));
13643 search
.dwSize
= sizeof(search
);
13644 search
.dwFlags
= D3DFDS_GUID
;
13645 search
.guid
= *tests
[i
].guid
;
13647 memset(&result
, 0, sizeof(result
));
13648 result
.dwSize
= sizeof(result
);
13650 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13651 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
13652 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %lu.\n", i
, result
.dwSize
);
13655 ok(result
.ddHwDesc
.dwSize
== sizeof(result_v1
.hw_desc
),
13656 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
13657 ok(result
.ddSwDesc
.dwSize
== sizeof(result_v1
.sw_desc
),
13658 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
13662 ok(!result
.ddHwDesc
.dwSize
,
13663 "Test %u: Got unexpected HW desc size %lu.\n", i
, result
.ddHwDesc
.dwSize
);
13664 ok(!result
.ddSwDesc
.dwSize
,
13665 "Test %u: Got unexpected SW desc size %lu.\n", i
, result
.ddSwDesc
.dwSize
);
13669 /* The HAL device can only be enumerated if hardware acceleration is present. */
13670 search
.dwSize
= sizeof(search
);
13671 search
.dwFlags
= D3DFDS_GUID
;
13672 search
.guid
= IID_IDirect3DHALDevice
;
13673 result
.dwSize
= sizeof(result
);
13674 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13676 window
= create_window();
13677 device
= create_device(ddraw
, window
, DDSCL_NORMAL
);
13679 ok(!!device
, "Failed to create a 3D device.\n");
13681 ok(!device
, "Succeeded to create a 3D device.\n");
13683 IDirect3DDevice_Release(device
);
13684 DestroyWindow(window
);
13686 /* Curiously the colour model criteria seem to be ignored. */
13687 search
.dwSize
= sizeof(search
);
13688 search
.dwFlags
= D3DFDS_COLORMODEL
;
13689 search
.dcmColorModel
= 0xdeadbeef;
13690 result
.dwSize
= sizeof(result
);
13691 hr
= IDirect3D_FindDevice(d3d
, &search
, &result
);
13692 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13694 IDirect3D_Release(d3d
);
13695 IDirectDraw_Release(ddraw
);
13698 static IDirectDraw
*killfocus_ddraw
;
13699 static IDirectDrawSurface
*killfocus_surface
;
13701 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
13705 if (message
== WM_KILLFOCUS
)
13707 ref
= IDirectDrawSurface_Release(killfocus_surface
);
13708 ok(!ref
, "Unexpected surface refcount %lu.\n", ref
);
13709 ref
= IDirectDraw_Release(killfocus_ddraw
);
13710 ok(!ref
, "Unexpected ddraw refcount %lu.\n", ref
);
13711 killfocus_ddraw
= NULL
;
13714 return DefWindowProcA(window
, message
, wparam
, lparam
);
13717 static void test_killfocus(void)
13719 DDSURFACEDESC surface_desc
;
13722 WNDCLASSA wc
= {0};
13724 wc
.lpfnWndProc
= killfocus_proc
;
13725 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
13726 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
13728 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
13729 0, 0, 640, 480, 0, 0, 0, 0);
13731 killfocus_ddraw
= create_ddraw();
13732 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
13734 hr
= IDirectDraw_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
13735 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#lx.\n", hr
);
13737 memset(&surface_desc
, 0, sizeof(surface_desc
));
13738 surface_desc
.dwSize
= sizeof(surface_desc
);
13739 surface_desc
.dwFlags
= DDSD_CAPS
;
13740 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13741 hr
= IDirectDraw_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
13742 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
13744 SetForegroundWindow(GetDesktopWindow());
13745 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
13747 DestroyWindow(window
);
13748 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
13751 static void test_gdi_surface(void)
13753 IDirectDrawSurface
*primary
, *backbuffer
, *gdi_surface
;
13754 DDSCAPS caps
= {DDSCAPS_BACKBUFFER
};
13755 DDSURFACEDESC surface_desc
;
13756 IDirectDraw
*ddraw
;
13761 window
= create_window();
13762 ddraw
= create_ddraw();
13763 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13764 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13765 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13767 /* Retrieving the GDI surface requires a primary surface to exist. */
13768 gdi_surface
= (void *)0xc0dec0de;
13769 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13770 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13771 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
13773 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13774 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
13776 memset(&surface_desc
, 0, sizeof(surface_desc
));
13777 surface_desc
.dwSize
= sizeof(surface_desc
);
13778 surface_desc
.dwFlags
= DDSD_CAPS
;
13779 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
13780 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13781 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13783 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13784 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13785 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13786 IDirectDrawSurface_Release(gdi_surface
);
13788 /* Flipping to the GDI surface requires the primary surface to be
13790 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13791 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#lx.\n", hr
);
13793 IDirectDrawSurface_Release(primary
);
13795 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13796 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13798 memset(&surface_desc
, 0, sizeof(surface_desc
));
13799 surface_desc
.dwSize
= sizeof(surface_desc
);
13800 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13801 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
13802 surface_desc
.dwBackBufferCount
= 1;
13803 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
13804 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13805 hr
= IDirectDrawSurface_GetAttachedSurface(primary
, &caps
, &backbuffer
);
13806 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13807 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
13809 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13810 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13811 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13812 IDirectDrawSurface_Release(gdi_surface
);
13814 hr
= IDirectDrawSurface_Flip(primary
, NULL
, DDFLIP_WAIT
);
13815 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13816 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13817 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13818 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
13819 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
13820 IDirectDrawSurface_Release(gdi_surface
);
13822 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13823 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13825 hr
= IDirectDraw_GetGDISurface(ddraw
, &gdi_surface
);
13826 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13827 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
13828 IDirectDrawSurface_Release(gdi_surface
);
13830 hr
= IDirectDraw_FlipToGDISurface(ddraw
);
13831 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
13833 IDirectDrawSurface_Release(backbuffer
);
13834 IDirectDrawSurface_Release(primary
);
13836 refcount
= IDirectDraw_Release(ddraw
);
13837 ok(!refcount
, "%lu references left.\n", refcount
);
13838 DestroyWindow(window
);
13841 static void test_alphatest(void)
13843 #define ALPHATEST_PASSED 0x0000ff00
13844 #define ALPHATEST_FAILED 0x00ff0000
13845 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
13846 IDirect3DExecuteBuffer
*execute_buffer
;
13847 IDirect3DMaterial
*blue
, *failed
;
13848 D3DEXECUTEBUFFERDESC exec_desc
;
13849 IDirect3DViewport
*viewport
;
13850 IDirect3DDevice
*device
;
13851 IDirectDrawSurface
*rt
;
13852 unsigned int color
, i
;
13853 IDirectDraw
*ddraw
;
13860 static const struct
13863 unsigned int color_less
, color_equal
, color_greater
;
13867 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13868 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
13869 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13870 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
13871 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13872 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
13873 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13874 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
13876 static D3DLVERTEX quad
[] =
13878 {{-1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13879 {{-1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13880 {{ 1.0f
}, {-1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13881 {{ 1.0f
}, { 1.0f
}, {0.1f
}, 0, {ALPHATEST_PASSED
| 0x80000000}},
13884 window
= create_window();
13885 ddraw
= create_ddraw();
13886 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13887 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
13889 skip("Failed to create a 3D device.\n");
13890 IDirectDraw_Release(ddraw
);
13891 DestroyWindow(window
);
13894 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
13895 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13897 blue
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
13898 failed
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
13900 viewport
= create_viewport(device
, 0, 0, 640, 480);
13902 viewport_set_background(device
, viewport
, blue
);
13903 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13904 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13906 memset(&exec_desc
, 0, sizeof(exec_desc
));
13907 exec_desc
.dwSize
= sizeof(exec_desc
);
13908 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
13909 exec_desc
.dwBufferSize
= 1024;
13910 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
13912 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
13913 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13915 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13916 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13918 ptr
= exec_desc
.lpData
;
13919 emit_set_rs(&ptr
, D3DRENDERSTATE_LIGHTING
, FALSE
);
13920 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
13921 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
13923 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13925 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13926 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13928 set_execute_data(execute_buffer
, 0, 0, inst_length
);
13929 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13930 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13932 viewport_set_background(device
, viewport
, failed
);
13933 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
13935 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13936 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13938 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13939 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13940 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
13941 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAREF
, 0x70);
13942 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, ARRAY_SIZE(quad
));
13943 emit_tquad(&ptr
, 0);
13945 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13946 inst_length
-= sizeof(quad
);
13948 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13949 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13951 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13952 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13953 hr
= IDirect3DDevice_BeginScene(device
);
13954 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13955 set_execute_data(execute_buffer
, ARRAY_SIZE(quad
), sizeof(quad
), inst_length
);
13956 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13957 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13958 hr
= IDirect3DDevice_EndScene(device
);
13959 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13960 color
= get_surface_color(rt
, 320, 240);
13961 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13962 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13963 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13965 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
13966 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13968 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
13969 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(quad
);
13970 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
13971 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_TRANSFORM
, 0, ARRAY_SIZE(quad
));
13972 emit_tquad(&ptr
, 0);
13974 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
13975 inst_length
-= sizeof(quad
);
13977 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
13978 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13980 hr
= IDirect3DViewport_Clear(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
);
13981 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13982 hr
= IDirect3DDevice_BeginScene(device
);
13983 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13984 set_execute_data(execute_buffer
, ARRAY_SIZE(quad
), sizeof(quad
), inst_length
);
13985 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
13986 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13987 hr
= IDirect3DDevice_EndScene(device
);
13988 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
13989 color
= get_surface_color(rt
, 320, 240);
13990 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
13991 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
13992 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
13995 IDirect3DExecuteBuffer_Release(execute_buffer
);
13996 destroy_viewport(device
, viewport
);
13997 destroy_material(failed
);
13998 destroy_material(blue
);
13999 IDirectDrawSurface_Release(rt
);
14000 refcount
= IDirect3DDevice_Release(device
);
14001 ok(!refcount
, "Device has %lu references left.\n", refcount
);
14002 refcount
= IDirectDraw_Release(ddraw
);
14003 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
14004 DestroyWindow(window
);
14007 static void test_clipper_refcount(void)
14009 IDirectDrawSurface
*surface
;
14010 IDirectDrawClipper
*clipper
, *clipper2
;
14011 DDSURFACEDESC surface_desc
;
14012 IDirectDraw
*ddraw
;
14017 const IDirectDrawClipperVtbl
*orig_vtbl
;
14019 window
= create_window();
14020 ddraw
= create_ddraw();
14021 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14022 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14023 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14025 memset(&surface_desc
, 0, sizeof(surface_desc
));
14026 surface_desc
.dwSize
= sizeof(surface_desc
);
14027 surface_desc
.dwFlags
= DDSD_CAPS
;
14028 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14029 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14030 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14032 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14033 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14034 refcount
= get_refcount((IUnknown
*)clipper
);
14035 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14037 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
14039 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
14040 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14041 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
14042 clipper
->lpVtbl
, clipper2
->lpVtbl
);
14043 orig_vtbl
= clipper
->lpVtbl
;
14044 IDirectDrawClipper_Release(clipper2
);
14046 /* Surfaces hold a reference to clippers. No surprises there. */
14047 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14048 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14049 refcount
= get_refcount((IUnknown
*)clipper
);
14050 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14052 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14053 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
14054 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14055 refcount
= IDirectDrawClipper_Release(clipper2
);
14056 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14058 hr
= IDirectDrawSurface_SetClipper(surface
, NULL
);
14059 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14060 refcount
= get_refcount((IUnknown
*)clipper
);
14061 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14063 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14064 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14065 refcount
= get_refcount((IUnknown
*)clipper
);
14066 ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14068 refcount
= IDirectDrawSurface_Release(surface
);
14069 ok(!refcount
, "%lu references left.\n", refcount
);
14070 refcount
= get_refcount((IUnknown
*)clipper
);
14071 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14073 /* SetClipper with an invalid pointer crashes. */
14075 /* Clipper methods work with a broken vtable, with the exception of Release. */
14076 clipper
->lpVtbl
= (void *)0xdeadbeef;
14077 refcount
= orig_vtbl
->AddRef(clipper
);
14078 todo_wine
ok(refcount
== 2, "Got unexpected refcount %lu.\n", refcount
);
14079 refcount
= orig_vtbl
->Release(clipper
);
14080 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
14082 clipper
->lpVtbl
= orig_vtbl
;
14083 refcount
= orig_vtbl
->Release(clipper
);
14084 todo_wine
ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
14086 /* Fix the refcount difference because Wine did not increase the ref in the
14087 * AddRef call above. */
14090 refcount
= IDirectDrawClipper_Release(clipper
);
14091 ok(!refcount
, "Got unexpected refcount %lu.\n", refcount
);
14094 /* Steal the reference and see what happens - releasing the surface works fine.
14095 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
14096 * release it after the GetClipper call is likely to crash, and certain to crash
14097 * if we allocate and zero as much heap memory as we can get. */
14098 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14099 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14100 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
14101 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#lx.\n", hr
);
14102 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
14103 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#lx.\n", hr
);
14105 IDirectDrawClipper_Release(clipper
);
14106 IDirectDrawClipper_Release(clipper
);
14110 /* Disabled because it causes heap corruption (HeapValidate fails and random
14111 * hangs in a later HeapFree) on Windows on one of my Machines: MacbookPro 10,1
14112 * running Windows 10 18363.535 and Nvidia driver 425.31. Driver version 441.66
14113 * is affected too. Some testbot machines have crashes directly in GetClipper
14114 * or proceed with a corrupted heap too.
14116 * The same Windows and driver versions run the test without heap corruption on
14117 * a Geforce 1060 GTX card. I have not seen the problem on AMD GPUs either. */
14118 hr
= IDirectDrawSurface_GetClipper(surface
, &clipper2
);
14119 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#lx.\n", hr
);
14120 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
14123 /* Show that invoking the Release method does not crash, but don't get the
14124 * vtable through the clipper pointer because it is no longer pointing to
14126 refcount
= orig_vtbl
->Release(clipper
);
14127 ok(!refcount
, "%lu references left.\n", refcount
);
14129 refcount
= IDirectDrawSurface_Release(surface
);
14130 ok(!refcount
, "%lu references left.\n", refcount
);
14132 /* It looks like the protection against invalid thispointers is part of
14133 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
14134 clipper
= calloc(1, 0x1000);
14135 ok(!!clipper
, "failed to allocate memory\n");
14137 /* Assigning the vtable to our fake clipper does NOT make a difference on
14138 * native - there is a different member of the clipper implementation struct
14139 * that is used to determine if a clipper is valid. */
14140 clipper
->lpVtbl
= orig_vtbl
;
14142 refcount
= orig_vtbl
->AddRef(clipper
);
14143 todo_wine
ok(!refcount
, "Got refcount %lu.\n", refcount
);
14144 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
14145 ok(!refcount
, "Got refcount %lu.\n", refcount
);
14148 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
14149 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14150 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14153 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
14154 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14155 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
14157 /* Nope, we can't initialize our fake clipper. */
14158 hr
= orig_vtbl
->Initialize(clipper
, ddraw
, 0);
14159 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#lx.\n", hr
);
14163 refcount
= IDirectDraw_Release(ddraw
);
14164 ok(!refcount
, "%lu references left.\n", refcount
);
14165 DestroyWindow(window
);
14168 static void test_caps(void)
14170 DWORD caps_never
, caps_always
, caps_hal
;
14171 DDCAPS hal_caps
, hel_caps
;
14172 IDirectDraw
*ddraw
;
14176 caps_never
= DDSCAPS_RESERVED1
14178 | DDSCAPS_PRIMARYSURFACELEFT
14179 | DDSCAPS_SYSTEMMEMORY
14181 | DDSCAPS_WRITEONLY
14182 | DDSCAPS_LIVEVIDEO
14185 | DDSCAPS_RESERVED2
14188 | DDSCAPS_ALLOCONLOAD
14189 | DDSCAPS_VIDEOPORT
14190 | DDSCAPS_STANDARDVGAMODE
14191 | DDSCAPS_OPTIMIZED
;
14193 caps_always
= DDSCAPS_FLIP
14194 | DDSCAPS_OFFSCREENPLAIN
14195 | DDSCAPS_PRIMARYSURFACE
14200 caps_hal
= DDSCAPS_BACKBUFFER
14202 | DDSCAPS_FRONTBUFFER
14204 | DDSCAPS_VIDEOMEMORY
14205 | DDSCAPS_LOCALVIDMEM
14206 | DDSCAPS_NONLOCALVIDMEM
;
14208 ddraw
= create_ddraw();
14209 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14211 memset(&hal_caps
, 0, sizeof(hal_caps
));
14212 memset(&hel_caps
, 0, sizeof(hel_caps
));
14213 hal_caps
.dwSize
= sizeof(hal_caps
);
14214 hel_caps
.dwSize
= sizeof(hel_caps
);
14215 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14216 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14217 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14218 "Got unexpected caps %#lx, expected %#lx.\n",
14219 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14220 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14221 "Got unexpected caps %#lx, expected %#lx.\n",
14222 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14224 no3d
= !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
);
14225 if (hal_caps
.ddsCaps
.dwCaps
)
14227 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14228 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14229 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14230 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14232 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14233 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14234 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14235 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14237 IDirectDraw_Release(ddraw
);
14239 if (hal_caps
.ddsCaps
.dwCaps
)
14241 hr
= DirectDrawCreate((GUID
*)DDCREATE_HARDWAREONLY
, &ddraw
, NULL
);
14242 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14244 memset(&hal_caps
, 0, sizeof(hal_caps
));
14245 memset(&hel_caps
, 0, sizeof(hel_caps
));
14246 hal_caps
.dwSize
= sizeof(hal_caps
);
14247 hel_caps
.dwSize
= sizeof(hel_caps
);
14248 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14249 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14250 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14251 "Got unexpected caps %#lx, expected %#lx.\n",
14252 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14253 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14254 "Got unexpected caps %#lx, expected %#lx.\n",
14255 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14257 ok(!(hal_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14258 ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14259 todo_wine_if(no3d
) ok(!(~hal_caps
.ddsCaps
.dwCaps
& caps_hal
),
14260 "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14263 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14264 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14265 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14266 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14270 todo_wine
ok(!hel_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14273 IDirectDraw_Release(ddraw
);
14276 hr
= DirectDrawCreate((GUID
*)DDCREATE_EMULATIONONLY
, &ddraw
, NULL
);
14277 ok(hr
== DD_OK
|| (is_ddraw64
&& hr
== E_FAIL
), "Got unexpected hr %#lx.\n", hr
);
14280 memset(&hal_caps
, 0, sizeof(hal_caps
));
14281 memset(&hel_caps
, 0, sizeof(hel_caps
));
14282 hal_caps
.dwSize
= sizeof(hal_caps
);
14283 hel_caps
.dwSize
= sizeof(hel_caps
);
14284 hr
= IDirectDraw_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
14285 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14286 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
14287 "Got unexpected caps %#lx, expected %#lx.\n",
14288 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
14289 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
14290 "Got unexpected caps %#lx, expected %#lx.\n",
14291 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
14293 todo_wine
ok(!hal_caps
.ddsCaps
.dwCaps
, "Got unexpected caps %#lx.\n", hal_caps
.ddsCaps
.dwCaps
);
14294 ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_never
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14295 ok(!(~hel_caps
.ddsCaps
.dwCaps
& caps_always
), "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14296 todo_wine_if(!no3d
) ok(!(hel_caps
.ddsCaps
.dwCaps
& caps_hal
),
14297 "Got unexpected caps %#lx.\n", hel_caps
.ddsCaps
.dwCaps
);
14299 IDirectDraw_Release(ddraw
);
14303 static void test_d32_support(void)
14305 IDirectDrawSurface
*surface
;
14306 DDSURFACEDESC surface_desc
;
14307 IDirectDraw
*ddraw
;
14312 window
= create_window();
14313 ddraw
= create_ddraw();
14314 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14315 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14316 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14318 memset(&surface_desc
, 0, sizeof(surface_desc
));
14319 surface_desc
.dwSize
= sizeof(surface_desc
);
14320 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
14321 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
14322 surface_desc
.dwZBufferBitDepth
= 32;
14323 surface_desc
.dwWidth
= 64;
14324 surface_desc
.dwHeight
= 64;
14325 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14326 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14328 memset(&surface_desc
, 0, sizeof(surface_desc
));
14329 surface_desc
.dwSize
= sizeof(surface_desc
);
14330 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &surface_desc
);
14331 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14332 ok((surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
), "Got unexpected flags %#lx.\n", surface_desc
.dwFlags
);
14333 ok(surface_desc
.dwZBufferBitDepth
== 32,
14334 "Got unexpected dwZBufferBitDepth %lu.\n", surface_desc
.dwZBufferBitDepth
);
14335 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
14336 "Got unexpected surface caps %#lx.\n", surface_desc
.ddsCaps
.dwCaps
);
14337 IDirectDrawSurface_Release(surface
);
14339 refcount
= IDirectDraw_Release(ddraw
);
14340 ok(!refcount
, "%lu references left.\n", refcount
);
14341 DestroyWindow(window
);
14344 struct find_different_mode_param
14346 unsigned int old_width
;
14347 unsigned int old_height
;
14348 unsigned int new_width
;
14349 unsigned int new_height
;
14352 static HRESULT CALLBACK
find_different_mode_callback(DDSURFACEDESC
*surface_desc
, void *context
)
14354 struct find_different_mode_param
*param
= context
;
14356 if (surface_desc
->ddpfPixelFormat
.dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
14357 return DDENUMRET_OK
;
14359 if (surface_desc
->dwWidth
!= param
->old_width
&& surface_desc
->dwHeight
!= param
->old_height
)
14361 /* See test_coop_level_mode_set_enum_cb() for why enumeration might accidentally continue. */
14362 if (!param
->new_width
|| (param
->new_width
< registry_mode
.dmPelsWidth
14363 && param
->new_height
< registry_mode
.dmPelsHeight
))
14365 param
->new_width
= surface_desc
->dwWidth
;
14366 param
->new_height
= surface_desc
->dwHeight
;
14368 return DDENUMRET_CANCEL
;
14371 return DDENUMRET_OK
;
14374 static void test_cursor_clipping(void)
14376 struct find_different_mode_param param
;
14377 DDSURFACEDESC surface_desc
;
14378 RECT rect
, clip_rect
;
14379 IDirectDraw
*ddraw
;
14384 window
= create_window();
14385 ok(!!window
, "Failed to create a window.\n");
14386 ddraw
= create_ddraw();
14387 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14389 memset(&surface_desc
, 0, sizeof(surface_desc
));
14390 surface_desc
.dwSize
= sizeof(surface_desc
);
14391 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14392 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14394 memset(¶m
, 0, sizeof(param
));
14395 param
.old_width
= surface_desc
.dwWidth
;
14396 param
.old_height
= surface_desc
.dwHeight
;
14397 hr
= IDirectDraw_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, find_different_mode_callback
);
14398 ok(hr
== DD_OK
, "EnumDisplayModes failed, hr %#lx.\n", hr
);
14399 if (!(param
.new_width
&& param
.new_height
))
14401 skip("Failed to find a different mode than %ux%u.\n", param
.old_width
, param
.old_height
);
14405 ret
= ClipCursor(NULL
);
14406 ok(ret
, "ClipCursor failed, error %lu.\n", GetLastError());
14407 get_virtual_rect(&rect
);
14408 ret
= GetClipCursor(&clip_rect
);
14409 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14410 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14411 wine_dbgstr_rect(&clip_rect
));
14413 /* Set cooperative level to normal */
14414 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14415 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14417 get_virtual_rect(&rect
);
14418 ret
= GetClipCursor(&clip_rect
);
14419 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14420 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14421 wine_dbgstr_rect(&clip_rect
));
14423 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
14424 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
14427 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
14431 get_virtual_rect(&rect
);
14432 ret
= GetClipCursor(&clip_rect
);
14433 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14434 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14435 wine_dbgstr_rect(&clip_rect
));
14437 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
14438 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
14440 get_virtual_rect(&rect
);
14441 ret
= GetClipCursor(&clip_rect
);
14442 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14443 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14444 wine_dbgstr_rect(&clip_rect
));
14446 /* Switch to full screen cooperative level */
14447 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14448 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14450 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
14451 ret
= GetClipCursor(&clip_rect
);
14452 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14453 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14454 wine_dbgstr_rect(&clip_rect
));
14456 hr
= set_display_mode(ddraw
, param
.new_width
, param
.new_height
);
14457 ok(hr
== DD_OK
|| hr
== DDERR_UNSUPPORTED
, "SetDisplayMode failed, hr %#lx.\n", hr
);
14460 win_skip("SetDisplayMode failed, hr %#lx.\n", hr
);
14464 SetRect(&rect
, 0, 0, param
.new_width
, param
.new_height
);
14465 ret
= GetClipCursor(&clip_rect
);
14466 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14467 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14468 wine_dbgstr_rect(&clip_rect
));
14470 /* Restore display mode */
14471 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
14472 ok(hr
== DD_OK
, "RestoreDisplayMode failed, hr %#lx.\n", hr
);
14474 SetRect(&rect
, 0, 0, param
.old_width
, param
.old_height
);
14475 ret
= GetClipCursor(&clip_rect
);
14476 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14477 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14478 wine_dbgstr_rect(&clip_rect
));
14480 /* Switch to normal cooperative level */
14481 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14482 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14484 get_virtual_rect(&rect
);
14485 ret
= GetClipCursor(&clip_rect
);
14486 ok(ret
, "GetClipCursor failed, error %lu.\n", GetLastError());
14487 ok(EqualRect(&clip_rect
, &rect
), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect
),
14488 wine_dbgstr_rect(&clip_rect
));
14491 IDirectDraw_Release(ddraw
);
14492 DestroyWindow(window
);
14495 static void check_vtbl_protection_(int line
, const void *vtbl
)
14497 MEMORY_BASIC_INFORMATION info
;
14498 SIZE_T ret
= VirtualQuery(vtbl
, &info
, sizeof(info
));
14499 ok_(__FILE__
, line
)(ret
== sizeof(info
), "Failed to query memory.\n");
14500 ok_(__FILE__
, line
)(info
.Protect
& (PAGE_READWRITE
| PAGE_WRITECOPY
), "Got protection %#lx.\n", info
.Protect
);
14502 #define check_vtbl_protection(a) check_vtbl_protection_(__LINE__, a)
14504 static void test_vtbl_protection(void)
14506 PALETTEENTRY palette_entries
[256];
14507 IDirectDrawSurface7
*surface7
;
14508 IDirectDrawSurface4
*surface4
;
14509 IDirectDrawSurface3
*surface3
;
14510 IDirectDrawSurface2
*surface2
;
14511 IDirectDrawSurface
*surface1
;
14512 IDirectDrawPalette
*palette
;
14513 DDSURFACEDESC surface_desc
;
14514 IDirectDraw
*ddraw
;
14519 window
= create_window();
14520 ddraw
= create_ddraw();
14521 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14522 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14523 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14525 memset(&surface_desc
, 0, sizeof(surface_desc
));
14526 surface_desc
.dwSize
= sizeof(surface_desc
);
14527 surface_desc
.dwFlags
= DDSD_CAPS
;
14528 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
14529 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
14530 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14531 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface2
, (void **)&surface2
);
14532 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14533 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
14534 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14535 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface4
, (void **)&surface4
);
14536 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14537 hr
= IDirectDrawSurface_QueryInterface(surface1
, &IID_IDirectDrawSurface7
, (void **)&surface7
);
14538 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14540 memset(palette_entries
, 0, sizeof(palette_entries
));
14541 hr
= IDirectDraw_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
14542 palette_entries
, &palette
, NULL
);
14543 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14545 check_vtbl_protection(ddraw
->lpVtbl
);
14546 check_vtbl_protection(palette
->lpVtbl
);
14547 check_vtbl_protection(surface1
->lpVtbl
);
14548 check_vtbl_protection(surface2
->lpVtbl
);
14549 check_vtbl_protection(surface3
->lpVtbl
);
14550 check_vtbl_protection(surface4
->lpVtbl
);
14551 check_vtbl_protection(surface7
->lpVtbl
);
14553 IDirectDrawPalette_Release(palette
);
14554 IDirectDrawSurface_Release(surface1
);
14555 IDirectDrawSurface2_Release(surface2
);
14556 IDirectDrawSurface3_Release(surface3
);
14557 IDirectDrawSurface4_Release(surface4
);
14558 IDirectDrawSurface7_Release(surface7
);
14559 refcount
= IDirectDraw_Release(ddraw
);
14560 ok(!refcount
, "%lu references left.\n", refcount
);
14561 DestroyWindow(window
);
14564 static BOOL CALLBACK
test_window_position_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
14567 RECT primary_rect
, window_rect
, new_rect
;
14568 IDirectDraw
*ddraw
;
14573 ddraw
= create_ddraw();
14574 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14575 window
= CreateWindowA("static", "ddraw_test", WS_POPUP
| WS_VISIBLE
, monitor_rect
->left
,
14576 monitor_rect
->top
, 100, 100, NULL
, NULL
, NULL
, NULL
);
14577 ok(!!window
, "Failed to create a window.\n");
14580 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
14581 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14583 ret
= GetWindowRect(window
, &window_rect
);
14584 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14585 SetRect(&primary_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
14586 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14587 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14589 new_rect
= window_rect
;
14593 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
14594 new_rect
.bottom
- new_rect
.top
, TRUE
);
14595 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14596 ret
= GetWindowRect(window
, &window_rect
);
14597 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14598 ok(EqualRect(&window_rect
, &new_rect
),
14599 "Expected window rect %s, got %s.\n",
14600 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14601 /* After processing window events window rectangle gets restored. But only once, the size set
14602 * on the second resize remains. */
14604 ret
= GetWindowRect(window
, &window_rect
);
14605 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14606 /* Both Windows and Wine change the size of the window. On Windows it is exactly the new size but in Wine
14607 * it may get adjusted depending on window manager. */
14608 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
14609 "Expected window rect %s, got %s.\n",
14610 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14612 ret
= MoveWindow(window
, new_rect
.left
, new_rect
.top
, new_rect
.right
- new_rect
.left
,
14613 new_rect
.bottom
- new_rect
.top
, TRUE
);
14614 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14615 ret
= GetWindowRect(window
, &window_rect
);
14616 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14617 ok(EqualRect(&window_rect
, &new_rect
),
14618 "Expected window rect %s, got %s.\n",
14619 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14621 ret
= GetWindowRect(window
, &window_rect
);
14622 ok(ret
, "Got unexpected ret %#x, error %lu.\n", ret
, GetLastError());
14623 ok(window_rect
.right
!= monitor_rect
->right
&& window_rect
.bottom
!= monitor_rect
->bottom
,
14624 "Expected window rect %s, got %s.\n",
14625 wine_dbgstr_rect(monitor_rect
), wine_dbgstr_rect(&window_rect
));
14627 /* Window activation should restore the window to fit the whole primary monitor */
14628 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
14629 SWP_NOZORDER
| SWP_NOSIZE
);
14630 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
14631 ret
= SetForegroundWindow(GetDesktopWindow());
14632 ok(ret
, "Failed to set foreground window.\n");
14634 ret
= ShowWindow(window
, SW_RESTORE
);
14635 ok(ret
, "Failed to restore window, error %lu.\n", GetLastError());
14637 ret
= SetForegroundWindow(window
);
14638 ok(ret
, "SetForegroundWindow failed, error %lu.\n", GetLastError());
14640 ret
= GetWindowRect(window
, &window_rect
);
14641 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14642 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14643 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14645 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14646 ok(hr
== DD_OK
, "SetCooperativeLevel failed, hr %#lx.\n", hr
);
14647 ret
= GetWindowRect(window
, &window_rect
);
14648 ok(ret
, "GetWindowRect failed, error %lu.\n", GetLastError());
14649 ok(EqualRect(&window_rect
, &primary_rect
), "Expect window rect %s, got %s.\n",
14650 wine_dbgstr_rect(&primary_rect
), wine_dbgstr_rect(&window_rect
));
14652 DestroyWindow(window
);
14653 IDirectDraw_Release(ddraw
);
14657 static void test_window_position(void)
14659 EnumDisplayMonitors(NULL
, NULL
, test_window_position_cb
, 0);
14662 static BOOL CALLBACK
test_get_display_mode_cb(HMONITOR monitor
, HDC hdc
, RECT
*monitor_rect
,
14665 DDSURFACEDESC surface_desc
;
14666 IDirectDraw
*ddraw
;
14671 ddraw
= create_ddraw();
14672 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14673 window
= create_window();
14674 ok(!!window
, "Failed to create a window.\n");
14676 /* Test that DirectDraw doesn't use the device window to determine which monitor to use */
14677 ret
= SetWindowPos(window
, 0, monitor_rect
->left
, monitor_rect
->top
, 0, 0,
14678 SWP_NOZORDER
| SWP_NOSIZE
);
14679 ok(ret
, "SetWindowPos failed, error %lu.\n", GetLastError());
14681 surface_desc
.dwSize
= sizeof(surface_desc
);
14682 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14683 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14684 ok(surface_desc
.dwWidth
== GetSystemMetrics(SM_CXSCREEN
), "Expect width %d, got %lu.\n",
14685 GetSystemMetrics(SM_CXSCREEN
), surface_desc
.dwWidth
);
14686 ok(surface_desc
.dwHeight
== GetSystemMetrics(SM_CYSCREEN
), "Expect height %d, got %lu.\n",
14687 GetSystemMetrics(SM_CYSCREEN
), surface_desc
.dwHeight
);
14689 DestroyWindow(window
);
14690 IDirectDraw_Release(ddraw
);
14694 static void test_get_display_mode(void)
14696 static const DWORD flags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_REFRESHRATE
| DDSD_PIXELFORMAT
| DDSD_PITCH
;
14697 DDSURFACEDESC surface_desc
;
14698 IDirectDraw
*ddraw
;
14703 EnumDisplayMonitors(NULL
, NULL
, test_get_display_mode_cb
, 0);
14705 ddraw
= create_ddraw();
14706 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14708 memset(&devmode
, 0, sizeof(devmode
));
14709 devmode
.dmSize
= sizeof(devmode
);
14710 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
14711 ok(ret
, "EnumDisplaySettingsW failed, error %lu.\n", GetLastError());
14713 surface_desc
.dwSize
= sizeof(surface_desc
);
14714 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
14715 ok(hr
== DD_OK
, "GetDisplayMode failed, hr %#lx.\n", hr
);
14716 ok(surface_desc
.dwSize
== sizeof(surface_desc
), "Got dwSize %lu.\n", surface_desc
.dwSize
);
14717 ok(surface_desc
.dwFlags
== flags
, "Expected dwFlags %#lx, got %#lx.\n", flags
,
14718 surface_desc
.dwFlags
);
14719 ok(surface_desc
.dwWidth
== devmode
.dmPelsWidth
, "Expected width %lu, got %lu.\n",
14720 devmode
.dmPelsWidth
, surface_desc
.dwWidth
);
14721 ok(surface_desc
.dwHeight
== devmode
.dmPelsHeight
, "Expected height %lu, got %lu.\n",
14722 devmode
.dmPelsHeight
, surface_desc
.dwHeight
);
14723 ok(surface_desc
.dwRefreshRate
== devmode
.dmDisplayFrequency
, "Expected frequency %lu, got %lu.\n",
14724 devmode
.dmDisplayFrequency
, surface_desc
.dwRefreshRate
);
14725 ok(surface_desc
.ddpfPixelFormat
.dwSize
== sizeof(surface_desc
.ddpfPixelFormat
),
14726 "Got ddpfPixelFormat.dwSize %lu.\n", surface_desc
.ddpfPixelFormat
.dwSize
);
14727 ok(surface_desc
.ddpfPixelFormat
.dwRGBBitCount
== devmode
.dmBitsPerPel
,
14728 "Expected ddpfPixelFormat.dwRGBBitCount %lu, got %lu.\n", devmode
.dmBitsPerPel
,
14729 surface_desc
.ddpfPixelFormat
.dwRGBBitCount
);
14730 ok(surface_desc
.lPitch
== devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
14731 "Expected pitch %lu, got %lu.\n", devmode
.dmPelsWidth
* devmode
.dmBitsPerPel
/ 8,
14732 surface_desc
.lPitch
);
14734 IDirectDraw_Release(ddraw
);
14737 static void run_for_each_device_type(void (*test_func
)(const GUID
*))
14739 test_func(&IID_IDirect3DHALDevice
);
14740 test_func(&IID_IDirect3DRGBDevice
);
14743 static void test_texture_wrong_caps(const GUID
*device_guid
)
14745 static D3DTLVERTEX quad
[] =
14747 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
14748 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
14749 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
14750 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
14752 static DDPIXELFORMAT fmt
=
14754 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
14755 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
14757 unsigned int inst_length
, color
, expected_color
;
14758 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14759 IDirect3DExecuteBuffer
*execute_buffer
;
14760 IDirectDrawSurface
*surface
, *rt
;
14761 D3DTEXTUREHANDLE texture_handle
;
14762 D3DEXECUTEBUFFERDESC exec_desc
;
14763 IDirect3DMaterial
*background
;
14764 IDirect3DViewport
*viewport
;
14765 IDirect3DTexture
*texture
;
14766 IDirect3DDevice
*device
;
14767 IDirectDraw
*ddraw
;
14768 DDSURFACEDESC ddsd
;
14774 window
= create_window();
14775 ddraw
= create_ddraw();
14776 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14777 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, device_guid
)))
14779 skip("Failed to create a 3D device, skipping test.\n");
14780 DestroyWindow(window
);
14783 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
14784 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14786 viewport
= create_viewport(device
, 0, 0, 640, 480);
14788 memset(&ddsd
, 0, sizeof(ddsd
));
14789 ddsd
.dwSize
= sizeof(ddsd
);
14790 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
14791 ddsd
.dwHeight
= 16;
14793 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14794 ddsd
.ddpfPixelFormat
= fmt
;
14795 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
14796 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14797 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
14798 ok(hr
== DD_OK
, "Got unexpected hr %#lx.\n", hr
);
14799 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
14800 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14802 fill_surface(surface
, 0xff00ff00);
14804 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
14805 viewport_set_background(device
, viewport
, background
);
14807 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
14808 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14809 if (is_software_device_type(device_guid
))
14810 fill_surface(rt
, 0xffff0000);
14812 memset(&exec_desc
, 0, sizeof(exec_desc
));
14813 exec_desc
.dwSize
= sizeof(exec_desc
);
14814 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
14815 exec_desc
.dwBufferSize
= 1024;
14816 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
14817 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
14818 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14820 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
14821 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14822 memcpy(exec_desc
.lpData
, quad
, sizeof(quad
));
14823 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(quad
);
14824 emit_process_vertices(&ptr
, D3DPROCESSVERTICES_COPY
, 0, 4);
14825 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
14826 emit_set_rs(&ptr
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14827 emit_tquad(&ptr
, 0);
14829 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(quad
);
14830 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
14831 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14833 set_execute_data(execute_buffer
, 4, sizeof(quad
), inst_length
);
14835 hr
= IDirect3DDevice_BeginScene(device
);
14836 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14837 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
14838 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14839 hr
= IDirect3DDevice_EndScene(device
);
14840 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
14842 expected_color
= is_software_device_type(device_guid
) ? 0x0000ff00 : 0x00ffffff;
14843 color
= get_surface_color(rt
, 320, 240);
14844 ok(compare_color(color
, expected_color
, 1), "Got color 0x%08x, expected 0x%08x.\n", color
, expected_color
);
14846 IDirect3DTexture_Release(texture
);
14847 IDirectDrawSurface_Release(surface
);
14848 IDirectDrawSurface_Release(rt
);
14849 IDirect3DExecuteBuffer_Release(execute_buffer
);
14850 destroy_material(background
);
14851 destroy_viewport(device
, viewport
);
14853 IDirect3DDevice_Release(device
);
14854 refcount
= IDirectDraw_Release(ddraw
);
14855 ok(!refcount
, "DirectDraw has %lu references left.\n", refcount
);
14856 DestroyWindow(window
);
14859 static void test_filling_convention(void)
14861 unsigned int inst_length
, colour
, expected
, i
, x
, y
;
14862 static const DWORD colour_bottom
= 0x00ffff00;
14863 static const DWORD colour_clear
= 0x000000ff;
14864 static const DWORD colour_right
= 0x00000000;
14865 static const DWORD colour_left
= 0x00ff0000;
14866 static const DWORD colour_top
= 0x0000ff00;
14867 IDirect3DExecuteBuffer
*execute_buffer
;
14868 D3DEXECUTEBUFFERDESC exec_desc
;
14869 IDirectDrawSurface
*backbuffer
;
14870 IDirect3DMaterial
*background
;
14871 IDirect3DViewport
*viewport
;
14872 IDirect3DDevice
*device
;
14873 IDirectDraw
*ddraw
;
14880 static const unsigned int vp_size
= 8;
14881 D3DRECT clear_rect
= {{0}, {0}, {vp_size
}, {vp_size
}};
14883 /* This test data follows the examples in MSDN's
14884 * "Rasterization Rules (Direct3D 9)" article.
14886 * See the d3d9 test for a comment about the eps value. */
14887 static const float eps
= 1.0f
/ 64.0f
;
14888 D3DLVERTEX center_tris
[] =
14891 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14892 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14893 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14896 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14897 {{-2.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14898 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14901 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14902 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14903 {{-0.5f
/ 4.0f
}, { 2.5f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14906 {{-2.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14907 {{-1.5f
/ 4.0f
}, { 0.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14908 {{-0.5f
/ 4.0f
}, {-1.5f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14913 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14914 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14915 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14918 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14919 {{-2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14920 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14923 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14924 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14925 {{ 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14928 {{-2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14929 {{-1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14930 {{ 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14932 nudge_right_tris
[] =
14935 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14936 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14937 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14940 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14941 {{eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14942 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14945 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14946 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14947 {{eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14950 {{eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14951 {{eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14952 {{eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14954 nudge_left_tris
[] =
14956 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14957 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14958 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14961 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14962 {{-eps
- 2.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14963 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14966 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14967 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14968 {{-eps
- 0.0f
/ 4.0f
}, { 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14971 {{-eps
- 2.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14972 {{-eps
- 1.0f
/ 4.0f
}, { 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14973 {{-eps
- 0.0f
/ 4.0f
}, {-1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14978 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14979 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14980 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
14983 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14984 {{-2.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14985 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
14988 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14989 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14990 {{ 0.0f
/ 4.0f
}, {eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
14993 {{-2.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14994 {{-1.0f
/ 4.0f
}, {eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14995 {{ 0.0f
/ 4.0f
}, {eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
14997 nudge_bottom_tris
[] =
15000 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15001 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15002 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_left
}},
15005 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15006 {{-2.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15007 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_top
}},
15010 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15011 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15012 {{ 0.0f
/ 4.0f
}, {-eps
+ 3.0f
/ 4.0f
}, {0.0f
}, 0, {colour_right
}},
15015 {{-2.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15016 {{-1.0f
/ 4.0f
}, {-eps
+ 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15017 {{ 0.0f
/ 4.0f
}, {-eps
- 1.0f
/ 4.0f
}, {0.0f
}, 0, {colour_bottom
}},
15020 D3DTLVERTEX center_tris_t
[] =
15023 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15024 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15025 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15028 {{1.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15029 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15030 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15033 {{3.5f
}, {1.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15034 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15035 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15038 {{2.5f
}, {3.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15039 {{3.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15040 {{1.5f
}, {5.5f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15045 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15046 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15047 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_left
}},
15050 {{2.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15051 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15052 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_top
}},
15055 {{4.0f
}, {1.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15056 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15057 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_right
}},
15060 {{3.0f
}, {3.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15061 {{4.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15062 {{2.0f
}, {5.0f
}, {0.0f
}, {1.0f
}, {colour_bottom
}},
15069 const char *expected
[8];
15075 D3DPROCESSVERTICES_TRANSFORM
,
15089 D3DPROCESSVERTICES_TRANSFORM
,
15103 D3DPROCESSVERTICES_TRANSFORM
,
15117 D3DPROCESSVERTICES_TRANSFORM
,
15131 D3DPROCESSVERTICES_TRANSFORM
,
15145 D3DPROCESSVERTICES_TRANSFORM
,
15159 D3DPROCESSVERTICES_COPY
,
15173 D3DPROCESSVERTICES_COPY
,
15186 static WORD indices
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
15188 window
= create_window();
15189 ddraw
= create_ddraw();
15190 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15191 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
15193 skip("Failed to create a 3D device.\n");
15194 IDirectDraw_Release(ddraw
);
15195 DestroyWindow(window
);
15199 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&backbuffer
);
15200 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15202 viewport
= create_viewport(device
, 0, 0, vp_size
, vp_size
);
15203 background
= create_diffuse_material(device
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
15204 viewport_set_background(device
, viewport
, background
);
15206 memset(&exec_desc
, 0, sizeof(exec_desc
));
15207 exec_desc
.dwSize
= sizeof(exec_desc
);
15208 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
15209 exec_desc
.dwBufferSize
= 1024;
15210 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
15212 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
15213 ok(hr
== D3D_OK
, "Failed to create execute buffer, hr %#lx.\n", hr
);
15215 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15217 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
15218 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15220 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
15221 ok(hr
== D3D_OK
, "Failed to lock execute buffer, hr %#lx.\n", hr
);
15223 /* All test geometry has the same vertex count and vertex size. */
15224 memcpy(exec_desc
.lpData
, tests
[i
].geometry
, sizeof(center_tris
));
15225 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(center_tris
);
15226 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, FALSE
);
15227 /* Old WARP versions (w8, early win10) apply color keying without textures. */
15228 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
15230 emit_process_vertices(&ptr
, tests
[i
].op
, 0, 12);
15231 emit_tri_indices(&ptr
, indices
, 4);
15233 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
15234 inst_length
-= sizeof(center_tris
);
15236 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
15237 ok(hr
== D3D_OK
, "Failed to lock execute buffer, hr %#lx.\n", hr
);
15239 set_execute_data(execute_buffer
, 12, sizeof(center_tris
), inst_length
);
15241 hr
= IDirect3DDevice_BeginScene(device
);
15242 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15243 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
15244 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15245 hr
= IDirect3DDevice_EndScene(device
);
15246 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
15248 for (y
= 0; y
< 8; y
++)
15250 for (x
= 0; x
< 8; x
++)
15253 switch (tests
[i
].expected
[y
][x
])
15255 case 'l': todo
= TRUE
;
15257 expected
= colour_left
;
15259 case 't': todo
= TRUE
;
15261 expected
= colour_top
;
15263 case 'r': todo
= TRUE
;
15265 expected
= colour_right
;
15267 case 'b': todo
= TRUE
;
15269 expected
= colour_bottom
;
15272 expected
= colour_clear
;
15275 ok(0, "Unexpected entry in expected test char\n");
15276 expected
= 0xdeadbeef;
15278 colour
= get_surface_color(backbuffer
, x
, y
);
15279 /* The nudge-to-bottom test fails on cards that give us a bottom-left
15280 * filling convention. The cause isn't the bottom part of the filling
15281 * convention, but because wined3d will nudge geometry to the left to
15282 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
15283 todo_wine_if(todo
&& !compare_color(colour
, expected
, 1))
15284 ok(compare_color(colour
, expected
, 1), "Got unexpected colour %08x, %ux%u, case %u.\n",
15290 destroy_viewport(device
, viewport
);
15291 IDirectDrawSurface_Release(backbuffer
);
15292 IDirect3DDevice_Release(device
);
15293 refcount
= IDirectDraw_Release(ddraw
);
15294 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15295 DestroyWindow(window
);
15298 static HRESULT WINAPI
test_enum_devices_caps_callback(GUID
*guid
, char *device_desc
,
15299 char *device_name
, D3DDEVICEDESC
*hal
, D3DDEVICEDESC
*hel
, void *ctx
)
15301 if(IsEqualGUID(&IID_IDirect3DRGBDevice
, guid
))
15303 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15304 "RGB Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15305 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15306 "RGB Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15307 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15308 "RGB Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15309 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15310 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15312 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15313 "RGB Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15314 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15315 "RGB Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15316 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15317 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15318 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15319 "RGB Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15321 ok(hal
->dcmColorModel
== 0, "RGB Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15322 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "RGB Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15324 ok(hal
->dwFlags
== 0, "RGB Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15325 ok(hel
->dwFlags
!= 0, "RGB Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15327 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15328 "RGB Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15329 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15330 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15331 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15332 "RGB Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15333 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15334 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15335 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWRASTERIZATION
) == 0,
15336 "RGB Device hal device caps has D3DDEVCAPS_HWRASTERIZATION set\n");
15337 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWRASTERIZATION
) == 0,
15338 "RGB Device hel device caps has D3DDEVCAPS_HWRASTERIZATION set\n");
15340 else if(IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
15342 ok(hal
->dcmColorModel
== D3DCOLOR_RGB
, "HAL Device hal caps has colormodel %lu\n", hel
->dcmColorModel
);
15343 ok(hel
->dcmColorModel
== 0, "HAL Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15345 ok(hal
->dwFlags
!= 0, "HAL Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15346 ok(hel
->dwFlags
!= 0, "HAL Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15348 ok(hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
,
15349 "HAL Device hal device caps does not have D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15350 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15351 "RGB Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15352 ok(hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
,
15353 "HAL Device hal device caps does not have D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15354 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15355 "RGB Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15357 else if(IsEqualGUID(&IID_IDirect3DRefDevice
, guid
))
15359 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15360 "REF Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15361 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15362 "REF Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15363 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15364 "REF Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15365 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15366 "REF Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15368 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15369 "REF Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15370 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15371 "REF Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15372 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15373 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15374 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15375 "REF Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15377 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15378 "REF Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15379 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15380 "REF Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15381 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15382 "REF Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15383 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15384 "REF Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15386 else if(IsEqualGUID(&IID_IDirect3DRampDevice
, guid
))
15388 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15389 "Ramp Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15390 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15391 "Ramp Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15392 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15393 "Ramp Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15394 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15395 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15397 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15398 "Ramp Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15399 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15400 "Ramp Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15401 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15402 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15403 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15404 "Ramp Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15406 ok(hal
->dcmColorModel
== 0, "Ramp Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15407 ok(hel
->dcmColorModel
== D3DCOLOR_MONO
, "Ramp Device hel caps has colormodel %lu\n",
15408 hel
->dcmColorModel
);
15410 ok(hal
->dwFlags
== 0, "Ramp Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15411 ok(hel
->dwFlags
!= 0, "Ramp Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15413 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15414 "Ramp Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15415 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15416 "Ramp Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15417 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15418 "Ramp Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15419 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15420 "Ramp Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15422 else if(IsEqualGUID(&IID_IDirect3DMMXDevice
, guid
))
15424 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15425 "MMX Device hal line caps has D3DPTEXTURECAPS_POW2 flag set\n");
15426 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
) == 0,
15427 "MMX Device hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n");
15428 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15429 "MMX Device hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15430 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
,
15431 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n");
15433 ok((hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15434 "MMX Device hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15435 ok((hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
) == 0,
15436 "MMX Device hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n");
15437 ok(hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15438 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15439 ok(hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_PERSPECTIVE
,
15440 "MMX Device hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n");
15442 ok(hal
->dcmColorModel
== 0, "MMX Device hal caps has colormodel %lu\n", hal
->dcmColorModel
);
15443 ok(hel
->dcmColorModel
== D3DCOLOR_RGB
, "MMX Device hel caps has colormodel %lu\n", hel
->dcmColorModel
);
15445 ok(hal
->dwFlags
== 0, "MMX Device hal caps has hardware flags %#lx\n", hal
->dwFlags
);
15446 ok(hel
->dwFlags
!= 0, "MMX Device hel caps has hardware flags %#lx\n", hel
->dwFlags
);
15448 ok((hal
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15449 "MMX Device hal device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15450 ok((hel
->dwDevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
) == 0,
15451 "MMX Device hel device caps has D3DDEVCAPS_HWTRANSFORMANDLIGHT set\n");
15452 ok((hal
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15453 "MMX Device hal device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15454 ok((hel
->dwDevCaps
& D3DDEVCAPS_DRAWPRIMITIVES2EX
) == 0,
15455 "MMX Device hel device caps has D3DDEVCAPS_DRAWPRIMITIVES2EX set\n");
15459 ok(FALSE
, "Unexpected device enumerated: \"%s\" \"%s\"\n", device_desc
, device_name
);
15460 if (hal
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15461 trace("hal line has pow2 set\n");
15463 trace("hal line does NOT have pow2 set\n");
15464 if (hal
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15465 trace("hal tri has pow2 set\n");
15467 trace("hal tri does NOT have pow2 set\n");
15468 if (hel
->dpcLineCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15469 trace("hel line has pow2 set\n");
15471 trace("hel line does NOT have pow2 set\n");
15472 if (hel
->dpcTriCaps
.dwTextureCaps
& D3DPTEXTURECAPS_POW2
)
15473 trace("hel tri has pow2 set\n");
15475 trace("hel tri does NOT have pow2 set\n");
15478 return DDENUMRET_OK
;
15481 static void test_enum_devices(void)
15483 IDirectDraw
*ddraw
;
15488 ddraw
= create_ddraw();
15489 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15491 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
15494 skip("D3D interface is not available, skipping test.\n");
15495 IDirectDraw_Release(ddraw
);
15499 hr
= IDirect3D_EnumDevices(d3d
, NULL
, NULL
);
15500 ok(hr
== DDERR_INVALIDPARAMS
, "Got hr %#lx.\n", hr
);
15502 hr
= IDirect3D_EnumDevices(d3d
, test_enum_devices_caps_callback
, NULL
);
15503 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
15505 IDirect3D_Release(d3d
);
15506 refcount
= IDirectDraw_Release(ddraw
);
15507 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15510 /* Emperor: Rise of the Middle Kingdom locks a sysmem surface and then accesses
15511 * the pointer after unlocking it. This test roughly replicates the calls that
15513 static void test_pinned_sysmem(void)
15515 DDBLTFX fx
= {.dwSize
= sizeof(fx
), .dwFillColor
= 0xface};
15516 IDirectDrawSurface
*surface
, *surface2
;
15517 DDSURFACEDESC surface_desc
;
15518 unsigned int color
;
15519 IDirectDraw
*ddraw
;
15524 window
= create_window();
15525 ddraw
= create_ddraw();
15526 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15527 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15529 memset(&surface_desc
, 0, sizeof(surface_desc
));
15530 surface_desc
.dwSize
= sizeof(surface_desc
);
15531 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
15532 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
15533 surface_desc
.dwWidth
= 32;
15534 surface_desc
.dwHeight
= 32;
15535 init_format_b5g6r5(&surface_desc
.ddpfPixelFormat
);
15536 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15537 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15538 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
15539 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15541 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15542 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15543 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
15544 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15546 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
15547 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15549 color
= ((unsigned short *)surface_desc
.lpSurface
)[0];
15550 ok(color
== 0xface, "Got color %04x.\n", color
);
15552 memset(surface_desc
.lpSurface
, 0x55, 32 * 16 * 2);
15554 hr
= IDirectDrawSurface_BltFast(surface2
, 0, 0, surface
, NULL
, DDBLTFAST_WAIT
);
15555 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15557 hr
= IDirectDrawSurface_Lock(surface2
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
15558 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15559 color
= ((unsigned short *)surface_desc
.lpSurface
)[0];
15560 ok(color
== 0x5555, "Got color %04x.\n", color
);
15561 color
= ((unsigned short *)surface_desc
.lpSurface
)[32 * 16];
15562 ok(color
== 0xface, "Got color %04x.\n", color
);
15563 hr
= IDirectDrawSurface_Unlock(surface2
, NULL
);
15564 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
15566 IDirectDrawSurface_Release(surface2
);
15567 IDirectDrawSurface_Release(surface
);
15568 refcount
= IDirectDraw_Release(ddraw
);
15569 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15570 DestroyWindow(window
);
15573 static void test_multiple_devices(void)
15575 static D3DMATRIX test_matrix
=
15577 1.0f
, 0.0f
, 0.0f
, 0.0f
,
15578 0.0f
, 2.0f
, 0.0f
, 0.0f
,
15579 0.0f
, 0.0f
, 3.0f
, 0.0f
,
15580 0.0f
, 0.0f
, 0.0f
, 4.0f
,
15583 D3DTEXTUREHANDLE texture_handle
, texture_handle2
;
15584 D3DMATERIALHANDLE mat_handle
, mat_handle2
;
15585 IDirect3DViewport
*viewport
, *viewport2
;
15586 IDirect3DDevice
*device
, *device2
;
15587 IDirectDrawSurface
*texture_surf
;
15588 D3DMATRIXHANDLE matrix_handle
;
15589 IDirectDraw
*ddraw
, *ddraw2
;
15590 IDirect3DMaterial
*material
;
15591 DDSURFACEDESC surface_desc
;
15592 IDirect3DTexture
*texture
;
15598 window
= create_window();
15599 ddraw
= create_ddraw();
15600 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15602 if (!(device
= create_device_ex(ddraw
, window
, DDSCL_NORMAL
, &IID_IDirect3DHALDevice
)))
15604 skip("Failed to create a 3D device, skipping test.\n");
15605 DestroyWindow(window
);
15609 ddraw2
= create_ddraw();
15610 ok(!!ddraw2
, "Failed to create a ddraw object.\n");
15612 device2
= create_device_ex(ddraw2
, window
, DDSCL_NORMAL
, &IID_IDirect3DHALDevice
);
15613 ok(!!device2
, "got NULL.\n");
15615 viewport
= create_viewport(device
, 0, 0, 640, 480);
15616 viewport2
= create_viewport(device2
, 0, 0, 640, 480);
15618 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
15619 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle
);
15620 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15621 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &mat_handle2
);
15622 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15623 ok(mat_handle
== mat_handle2
, "got different handles.\n");
15625 hr
= IDirect3DMaterial_GetHandle(material
, device2
, &mat_handle2
);
15626 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15627 todo_wine
ok(mat_handle
!= mat_handle2
, "got same handles.\n");
15629 hr
= IDirect3DViewport_SetBackground(viewport
, mat_handle
);
15630 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15631 hr
= IDirect3DViewport_SetBackground(viewport2
, mat_handle
);
15632 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15634 memset(&surface_desc
, 0, sizeof(surface_desc
));
15635 surface_desc
.dwSize
= sizeof(surface_desc
);
15636 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15637 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
15638 surface_desc
.dwWidth
= 256;
15639 surface_desc
.dwHeight
= 256;
15640 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &texture_surf
, NULL
);
15641 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15642 hr
= IDirectDrawSurface_QueryInterface(texture_surf
, &IID_IDirect3DTexture2
, (void **)&texture
);
15643 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15644 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
15645 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15646 hr
= IDirect3DTexture_GetHandle(texture
, device2
, &texture_handle2
);
15647 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15648 ok(texture_handle
!= texture_handle2
, "got same handles.\n");
15650 hr
= IDirect3DDevice_CreateMatrix(device
, &matrix_handle
);
15651 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15652 hr
= IDirect3DDevice_SetMatrix(device
, matrix_handle
, &test_matrix
);
15653 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15655 memset(&matrix
, 0xcc, sizeof(matrix
));
15656 hr
= IDirect3DDevice_GetMatrix(device2
, matrix_handle
, &matrix
);
15657 ok(hr
== D3D_OK
, "got %#lx.\n", hr
);
15658 ok(!memcmp(&matrix
, &test_matrix
, sizeof(matrix
)), "matrix does not match.\n");
15660 IDirect3DTexture_Release(texture
);
15661 IDirectDrawSurface_Release(texture_surf
);
15662 IDirect3DMaterial_Release(material
);
15663 IDirect3DViewport_Release(viewport
);
15664 IDirect3DViewport_Release(viewport2
);
15666 refcount
= IDirect3DDevice_Release(device
);
15667 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15668 refcount
= IDirect3DDevice_Release(device2
);
15669 ok(!refcount
, "Device has %lu references left.\n", refcount
);
15671 IDirectDraw_Release(ddraw
);
15672 IDirectDraw_Release(ddraw2
);
15673 DestroyWindow(window
);
15678 DDDEVICEIDENTIFIER identifier
;
15679 DEVMODEW current_mode
;
15680 IDirectDraw
*ddraw
;
15683 if (!(ddraw
= create_ddraw()))
15685 skip("Failed to create a ddraw object, skipping tests.\n");
15689 if (ddraw_get_identifier(ddraw
, &identifier
))
15691 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
15692 trace("Description string: \"%s\"\n", identifier
.szDescription
);
15693 trace("Driver version %d.%d.%d.%d\n",
15694 HIWORD(identifier
.liDriverVersion
.HighPart
), LOWORD(identifier
.liDriverVersion
.HighPart
),
15695 HIWORD(identifier
.liDriverVersion
.LowPart
), LOWORD(identifier
.liDriverVersion
.LowPart
));
15697 IDirectDraw_Release(ddraw
);
15699 memset(¤t_mode
, 0, sizeof(current_mode
));
15700 current_mode
.dmSize
= sizeof(current_mode
);
15701 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
15702 registry_mode
.dmSize
= sizeof(registry_mode
);
15703 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
15704 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
15705 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
15707 skip("Current mode does not match registry mode, skipping test.\n");
15711 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
15712 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
15714 test_coop_level_create_device_window();
15715 test_clipper_blt();
15716 test_coop_level_d3d_state();
15717 test_surface_interface_mismatch();
15718 test_coop_level_threaded();
15719 test_viewport_object();
15720 run_for_each_device_type(test_zenable
);
15721 run_for_each_device_type(test_ck_rgba
);
15727 test_window_style();
15728 test_redundant_mode_set();
15729 test_coop_level_mode_set();
15730 test_coop_level_mode_set_multi();
15732 test_coop_level_surf_create();
15733 test_coop_level_multi_window();
15734 test_clear_rect_count();
15735 test_coop_level_activateapp();
15736 test_unsupported_formats();
15737 run_for_each_device_type(test_rt_caps
);
15738 test_primary_caps();
15739 test_surface_lock();
15740 test_surface_discard();
15742 test_sysmem_overlay();
15743 test_primary_palette();
15744 test_surface_attachment();
15745 test_pixel_format();
15746 test_create_surface_pitch();
15748 test_palette_complex();
15752 test_specular_lighting();
15753 test_palette_gdi();
15754 test_palette_alpha();
15755 test_lost_device();
15756 test_surface_desc_lock();
15757 test_texturemapblend();
15758 test_viewport_clear_rect();
15760 test_colorkey_precision();
15761 test_range_colorkey();
15763 test_lockrect_invalid();
15764 test_yv12_overlay();
15765 test_offscreen_overlay();
15766 test_overlay_rect();
15768 test_blt_z_alpha();
15769 test_cross_device_blt();
15771 test_transform_vertices();
15772 test_display_mode_surface_pixel_format();
15773 test_surface_desc_size();
15774 test_texture_load();
15775 test_ck_operation();
15776 test_depth_readback();
15778 test_enum_surfaces();
15779 test_execute_data();
15781 test_find_device();
15783 test_gdi_surface();
15785 test_clipper_refcount();
15787 test_d32_support();
15788 test_cursor_clipping();
15789 test_vtbl_protection();
15790 test_window_position();
15791 test_get_display_mode();
15792 run_for_each_device_type(test_texture_wrong_caps
);
15793 test_filling_convention();
15794 test_enum_devices();
15795 test_pinned_sysmem();
15796 test_multiple_devices();