2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
27 HRESULT WINAPI
GetSurfaceFromDC(HDC dc
, struct IDirectDrawSurface
**surface
, HDC
*device_dc
);
29 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
30 static DEVMODEW registry_mode
;
32 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
35 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
53 struct create_window_thread_param
56 HANDLE window_created
;
57 HANDLE destroy_window
;
61 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
71 if (abs(x
- y
) > ulps
)
77 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
79 return compare_float(vec
->x
, x
, ulps
)
80 && compare_float(vec
->y
, y
, ulps
)
81 && compare_float(vec
->z
, z
, ulps
)
82 && compare_float(vec
->w
, w
, ulps
);
85 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
87 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
89 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
91 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
93 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
97 static BOOL
ddraw_get_identifier(IDirectDraw4
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
101 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw
, identifier
, 0);
102 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
104 return SUCCEEDED(hr
);
107 static BOOL
ddraw_is_warp(IDirectDraw4
*ddraw
)
109 DDDEVICEIDENTIFIER identifier
;
111 return strcmp(winetest_platform
, "wine")
112 && ddraw_get_identifier(ddraw
, &identifier
)
113 && strstr(identifier
.szDriver
, "warp");
116 static BOOL
ddraw_is_vendor(IDirectDraw4
*ddraw
, DWORD vendor
)
118 DDDEVICEIDENTIFIER identifier
;
120 return strcmp(winetest_platform
, "wine")
121 && ddraw_get_identifier(ddraw
, &identifier
)
122 && identifier
.dwVendorId
== vendor
;
125 static BOOL
ddraw_is_intel(IDirectDraw4
*ddraw
)
127 return ddraw_is_vendor(ddraw
, 0x8086);
130 static BOOL
ddraw_is_nvidia(IDirectDraw4
*ddraw
)
132 return ddraw_is_vendor(ddraw
, 0x10de);
135 static BOOL
ddraw_is_vmware(IDirectDraw4
*ddraw
)
137 return ddraw_is_vendor(ddraw
, 0x15ad);
140 static IDirectDrawSurface4
*create_overlay(IDirectDraw4
*ddraw
,
141 unsigned int width
, unsigned int height
, DWORD format
)
143 IDirectDrawSurface4
*surface
;
146 memset(&desc
, 0, sizeof(desc
));
147 desc
.dwSize
= sizeof(desc
);
148 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
149 desc
.dwWidth
= width
;
150 desc
.dwHeight
= height
;
151 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
152 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
153 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
154 U4(desc
).ddpfPixelFormat
.dwFourCC
= format
;
156 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
161 static HWND
create_window(void)
163 RECT r
= {0, 0, 640, 480};
165 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
167 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
168 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
171 static DWORD WINAPI
create_window_thread_proc(void *param
)
173 struct create_window_thread_param
*p
= param
;
177 p
->window
= create_window();
178 ret
= SetEvent(p
->window_created
);
179 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
185 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
186 DispatchMessageA(&msg
);
187 res
= WaitForSingleObject(p
->destroy_window
, 100);
188 if (res
== WAIT_OBJECT_0
)
190 if (res
!= WAIT_TIMEOUT
)
192 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
197 DestroyWindow(p
->window
);
202 static void create_window_thread(struct create_window_thread_param
*p
)
206 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
207 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
208 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
209 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
210 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
211 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
212 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
213 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
216 static void destroy_window_thread(struct create_window_thread_param
*p
)
218 SetEvent(p
->destroy_window
);
219 WaitForSingleObject(p
->thread
, INFINITE
);
220 CloseHandle(p
->destroy_window
);
221 CloseHandle(p
->window_created
);
222 CloseHandle(p
->thread
);
225 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
227 IDirectDrawSurface4
*rt
, *ret
;
228 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, {0}};
231 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
232 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
233 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
234 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
235 IDirectDrawSurface4_Release(rt
);
239 static HRESULT
set_display_mode(IDirectDraw4
*ddraw
, DWORD width
, DWORD height
)
241 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
243 return IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
246 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
248 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
249 DDSURFACEDESC2 surface_desc
;
253 memset(&surface_desc
, 0, sizeof(surface_desc
));
254 surface_desc
.dwSize
= sizeof(surface_desc
);
256 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
257 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
261 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
263 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
264 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
269 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
271 DDPIXELFORMAT
*z_fmt
= ctx
;
273 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
279 static IDirectDraw4
*create_ddraw(void)
281 IDirectDraw4
*ddraw4
;
285 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
288 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
289 IDirectDraw_Release(ddraw1
);
296 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
298 IDirectDrawSurface4
*surface
, *ds
;
299 IDirect3DDevice3
*device
= NULL
;
300 DDSURFACEDESC2 surface_desc
;
301 IDirectDraw4
*ddraw4
;
306 if (!(ddraw4
= create_ddraw()))
309 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
310 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
312 memset(&surface_desc
, 0, sizeof(surface_desc
));
313 surface_desc
.dwSize
= sizeof(surface_desc
);
314 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
315 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
316 surface_desc
.dwWidth
= 640;
317 surface_desc
.dwHeight
= 480;
319 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
320 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
322 if (coop_level
& DDSCL_NORMAL
)
324 IDirectDrawClipper
*clipper
;
326 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
327 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
328 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
329 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
330 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
331 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
332 IDirectDrawClipper_Release(clipper
);
335 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
336 IDirectDraw4_Release(ddraw4
);
339 IDirectDrawSurface4_Release(surface
);
343 memset(&z_fmt
, 0, sizeof(z_fmt
));
344 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
345 if (FAILED(hr
) || !z_fmt
.dwSize
)
347 IDirect3D3_Release(d3d3
);
348 IDirectDrawSurface4_Release(surface
);
352 memset(&surface_desc
, 0, sizeof(surface_desc
));
353 surface_desc
.dwSize
= sizeof(surface_desc
);
354 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
355 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
356 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
357 surface_desc
.dwWidth
= 640;
358 surface_desc
.dwHeight
= 480;
359 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
360 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
363 IDirect3D3_Release(d3d3
);
364 IDirectDrawSurface4_Release(surface
);
368 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
369 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
370 IDirectDrawSurface4_Release(ds
);
373 IDirect3D3_Release(d3d3
);
374 IDirectDrawSurface4_Release(surface
);
378 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
379 IDirect3D3_Release(d3d3
);
380 IDirectDrawSurface4_Release(surface
);
387 static IDirect3DViewport3
*create_viewport(IDirect3DDevice3
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
389 IDirect3DViewport3
*viewport
;
394 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
395 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
396 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
397 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
398 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
399 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
400 memset(&vp
, 0, sizeof(vp
));
401 vp
.dwSize
= sizeof(vp
);
408 vp
.dvClipWidth
= 2.0f
;
409 vp
.dvClipHeight
= 2.0f
;
412 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
413 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
414 IDirect3D3_Release(d3d
);
419 static void destroy_viewport(IDirect3DDevice3
*device
, IDirect3DViewport3
*viewport
)
423 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
424 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
425 IDirect3DViewport3_Release(viewport
);
428 static IDirect3DMaterial3
*create_material(IDirect3DDevice3
*device
, D3DMATERIAL
*mat
)
430 IDirect3DMaterial3
*material
;
434 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
435 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
436 hr
= IDirect3D3_CreateMaterial(d3d
, &material
, NULL
);
437 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
438 hr
= IDirect3DMaterial3_SetMaterial(material
, mat
);
439 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
440 IDirect3D3_Release(d3d
);
445 static IDirect3DMaterial3
*create_diffuse_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
449 memset(&mat
, 0, sizeof(mat
));
450 mat
.dwSize
= sizeof(mat
);
451 U1(U(mat
).diffuse
).r
= r
;
452 U2(U(mat
).diffuse
).g
= g
;
453 U3(U(mat
).diffuse
).b
= b
;
454 U4(U(mat
).diffuse
).a
= a
;
456 return create_material(device
, &mat
);
459 static IDirect3DMaterial3
*create_specular_material(IDirect3DDevice3
*device
,
460 float r
, float g
, float b
, float a
, float power
)
464 memset(&mat
, 0, sizeof(mat
));
465 mat
.dwSize
= sizeof(mat
);
466 U1(U2(mat
).specular
).r
= r
;
467 U2(U2(mat
).specular
).g
= g
;
468 U3(U2(mat
).specular
).b
= b
;
469 U4(U2(mat
).specular
).a
= a
;
470 U4(mat
).power
= power
;
472 return create_material(device
, &mat
);
475 static IDirect3DMaterial3
*create_emissive_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
479 memset(&mat
, 0, sizeof(mat
));
480 mat
.dwSize
= sizeof(mat
);
481 U1(U3(mat
).emissive
).r
= r
;
482 U2(U3(mat
).emissive
).g
= g
;
483 U3(U3(mat
).emissive
).b
= b
;
484 U4(U3(mat
).emissive
).a
= a
;
486 return create_material(device
, &mat
);
489 static void destroy_material(IDirect3DMaterial3
*material
)
491 IDirect3DMaterial3_Release(material
);
498 WPARAM expect_wparam
;
501 static const struct message
*expect_messages
;
503 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
505 if (expect_messages
&& message
== expect_messages
->message
)
507 if (expect_messages
->check_wparam
)
508 ok (wparam
== expect_messages
->expect_wparam
,
509 "Got unexpected wparam %lx for message %x, expected %lx.\n",
510 wparam
, message
, expect_messages
->expect_wparam
);
515 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
518 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
519 * interface. This prevents subsequent SetCooperativeLevel() calls on a
520 * different window from failing with DDERR_HWNDALREADYSET. */
521 static void fix_wndproc(HWND window
, LONG_PTR proc
)
526 if (!(ddraw
= create_ddraw()))
529 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
530 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
531 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
532 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
533 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
535 IDirectDraw4_Release(ddraw
);
538 static void test_process_vertices(void)
540 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
541 IDirect3DViewport3
*viewport
;
542 D3DVERTEXBUFFERDESC vb_desc
;
543 IDirect3DDevice3
*device
;
544 struct vec3
*src_data
;
545 struct vec4
*dst_data
;
552 static D3DMATRIX identity
=
554 1.0f
, 0.0f
, 0.0f
, 0.0f
,
555 0.0f
, 1.0f
, 0.0f
, 0.0f
,
556 0.0f
, 0.0f
, 1.0f
, 0.0f
,
557 0.0f
, 0.0f
, 0.0f
, 1.0f
,
559 static D3DMATRIX projection
=
561 1.0f
, 0.0f
, 0.0f
, 0.0f
,
562 0.0f
, 1.0f
, 0.0f
, 0.0f
,
563 0.0f
, 0.0f
, 1.0f
, 0.0f
,
564 6.0f
, 7.0f
, 8.0f
, 1.0f
,
567 window
= create_window();
568 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
570 skip("Failed to create a 3D device, skipping test.\n");
571 DestroyWindow(window
);
575 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
576 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
578 memset(&vb_desc
, 0, sizeof(vb_desc
));
579 vb_desc
.dwSize
= sizeof(vb_desc
);
580 vb_desc
.dwFVF
= D3DFVF_XYZ
;
581 vb_desc
.dwNumVertices
= 3;
582 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
583 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
585 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
586 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
587 src_data
[0].x
= -1.0f
;
588 src_data
[0].y
= -1.0f
;
589 src_data
[0].z
= -1.0f
;
590 src_data
[1].x
= 0.0f
;
591 src_data
[1].y
= 0.0f
;
592 src_data
[1].z
= 0.0f
;
593 src_data
[2].x
= 1.0f
;
594 src_data
[2].y
= 1.0f
;
595 src_data
[2].z
= 1.0f
;
596 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
597 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
599 memset(&vb_desc
, 0, sizeof(vb_desc
));
600 vb_desc
.dwSize
= sizeof(vb_desc
);
601 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
602 vb_desc
.dwNumVertices
= 3;
603 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
604 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
606 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
607 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
608 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
609 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
610 vp2
.dwSize
= sizeof(vp2
);
617 vp2
.dvClipWidth
= 4.0f
;
618 vp2
.dvClipHeight
= 5.0f
;
621 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
622 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
623 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
624 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
626 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
627 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
628 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
629 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
630 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
631 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
633 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
634 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
636 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
637 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
638 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
639 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
640 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
641 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
642 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
643 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
644 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
645 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
646 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
647 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
648 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
650 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
651 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
653 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
654 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
656 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
657 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
658 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
659 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
660 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
661 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
662 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
663 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
664 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
665 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
666 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
667 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
668 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
670 vp2
.dwSize
= sizeof(vp2
);
677 vp2
.dvClipWidth
= 2.0f
;
678 vp2
.dvClipHeight
= 4.0f
;
681 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
682 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
684 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
685 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
687 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
688 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
689 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
690 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
691 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
692 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
693 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
694 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
695 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
696 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
697 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
698 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
699 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
701 vp1
.dwSize
= sizeof(vp1
);
712 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
713 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
715 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
716 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
718 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
719 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
720 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
721 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
722 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
723 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
724 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
725 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
726 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
727 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
728 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
729 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
730 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
732 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
733 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
735 IDirect3DVertexBuffer_Release(dst_vb
);
736 IDirect3DVertexBuffer_Release(src_vb
);
737 IDirect3DViewport3_Release(viewport
);
738 IDirect3D3_Release(d3d3
);
739 IDirect3DDevice3_Release(device
);
740 DestroyWindow(window
);
743 static void test_coop_level_create_device_window(void)
745 HWND focus_window
, device_window
;
749 focus_window
= create_window();
750 ddraw
= create_ddraw();
751 ok(!!ddraw
, "Failed to create a ddraw object.\n");
753 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
754 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
755 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
756 ok(!device_window
, "Unexpected device window found.\n");
757 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
758 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
759 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
760 ok(!device_window
, "Unexpected device window found.\n");
761 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
762 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
763 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
764 ok(!device_window
, "Unexpected device window found.\n");
765 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
766 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
767 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
768 ok(!device_window
, "Unexpected device window found.\n");
769 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
770 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
771 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
772 ok(!device_window
, "Unexpected device window found.\n");
774 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
775 if (broken(hr
== DDERR_INVALIDPARAMS
))
777 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
778 IDirectDraw4_Release(ddraw
);
779 DestroyWindow(focus_window
);
783 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
784 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
785 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
786 ok(!device_window
, "Unexpected device window found.\n");
787 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
788 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
789 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
790 ok(!device_window
, "Unexpected device window found.\n");
792 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
793 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
794 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
795 ok(!device_window
, "Unexpected device window found.\n");
796 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
797 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
798 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
799 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
800 ok(!!device_window
, "Device window not found.\n");
802 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
803 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
804 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
805 ok(!device_window
, "Unexpected device window found.\n");
806 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
807 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
808 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
809 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
810 ok(!!device_window
, "Device window not found.\n");
812 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
813 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
814 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
815 ok(!device_window
, "Unexpected device window found.\n");
816 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
817 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
818 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
819 ok(!device_window
, "Unexpected device window found.\n");
820 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
821 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
822 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
823 ok(!device_window
, "Unexpected device window found.\n");
824 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
826 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
827 ok(!!device_window
, "Device window not found.\n");
829 IDirectDraw4_Release(ddraw
);
830 DestroyWindow(focus_window
);
833 static void test_clipper_blt(void)
835 IDirectDrawSurface4
*src_surface
, *dst_surface
;
836 RECT client_rect
, src_rect
;
837 IDirectDrawClipper
*clipper
;
838 DDSURFACEDESC2 surface_desc
;
839 unsigned int i
, j
, x
, y
;
851 static const DWORD src_data
[] =
853 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
854 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
855 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
857 static const D3DCOLOR expected1
[] =
859 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
860 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
861 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
862 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
864 /* Nvidia on Windows seems to have an off-by-one error
865 * when processing source rectangles. Our left = 1 and
866 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
867 * read as well, but only for the edge pixels on the
868 * output image. The bug happens on the y axis as well,
869 * but we only read one row there, and all source rows
870 * contain the same data. This bug is not dependent on
871 * the presence of a clipper. */
872 static const D3DCOLOR expected1_broken
[] =
874 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
875 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
876 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
877 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
879 static const D3DCOLOR expected2
[] =
881 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
882 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
883 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
884 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
887 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
888 10, 10, 640, 480, 0, 0, 0, 0);
889 ShowWindow(window
, SW_SHOW
);
890 ddraw
= create_ddraw();
891 ok(!!ddraw
, "Failed to create a ddraw object.\n");
893 ret
= GetClientRect(window
, &client_rect
);
894 ok(ret
, "Failed to get client rect.\n");
895 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
896 ok(ret
, "Failed to map client rect.\n");
898 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
899 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
901 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
902 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
903 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
904 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
905 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
906 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
907 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
908 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
909 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
910 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
911 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
912 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
913 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
914 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
915 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
916 "Got unexpected bounding rect %s, expected %s.\n",
917 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
918 HeapFree(GetProcessHeap(), 0, rgn_data
);
920 r1
= CreateRectRgn(0, 0, 320, 240);
921 ok(!!r1
, "Failed to create region.\n");
922 r2
= CreateRectRgn(320, 240, 640, 480);
923 ok(!!r2
, "Failed to create region.\n");
924 CombineRgn(r1
, r1
, r2
, RGN_OR
);
925 ret
= GetRegionData(r1
, 0, NULL
);
926 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
927 ret
= GetRegionData(r1
, ret
, rgn_data
);
928 ok(!!ret
, "Failed to get region data.\n");
933 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
934 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
935 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
936 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
937 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
938 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
940 HeapFree(GetProcessHeap(), 0, rgn_data
);
942 memset(&surface_desc
, 0, sizeof(surface_desc
));
943 surface_desc
.dwSize
= sizeof(surface_desc
);
944 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
945 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
946 surface_desc
.dwWidth
= 640;
947 surface_desc
.dwHeight
= 480;
948 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
949 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
950 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
951 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
952 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
953 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
955 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
956 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
957 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
958 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
960 memset(&fx
, 0, sizeof(fx
));
961 fx
.dwSize
= sizeof(fx
);
962 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
963 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
964 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
965 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
967 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
968 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
969 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
970 ptr
= surface_desc
.lpSurface
;
971 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
972 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
973 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
974 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
975 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
977 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
978 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
980 SetRect(&src_rect
, 1, 1, 5, 2);
981 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
982 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
983 for (i
= 0; i
< 4; ++i
)
985 for (j
= 0; j
< 4; ++j
)
987 x
= 80 * ((2 * j
) + 1);
988 y
= 60 * ((2 * i
) + 1);
989 color
= get_surface_color(dst_surface
, x
, y
);
990 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
991 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
992 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
996 U5(fx
).dwFillColor
= 0xff0000ff;
997 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
998 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
999 for (i
= 0; i
< 4; ++i
)
1001 for (j
= 0; j
< 4; ++j
)
1003 x
= 80 * ((2 * j
) + 1);
1004 y
= 60 * ((2 * i
) + 1);
1005 color
= get_surface_color(dst_surface
, x
, y
);
1006 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1007 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1011 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1012 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
1014 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1015 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1016 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1017 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1018 DestroyWindow(window
);
1019 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1020 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
1021 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1022 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1023 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1024 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1025 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1026 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1027 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1028 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1029 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1030 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1032 IDirectDrawSurface4_Release(dst_surface
);
1033 IDirectDrawSurface4_Release(src_surface
);
1034 refcount
= IDirectDrawClipper_Release(clipper
);
1035 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
1036 IDirectDraw4_Release(ddraw
);
1039 static void test_coop_level_d3d_state(void)
1041 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1042 IDirectDrawSurface4
*rt
, *surface
;
1043 IDirect3DViewport3
*viewport
;
1044 IDirect3DDevice3
*device
;
1045 IDirectDraw4
*ddraw
;
1052 window
= create_window();
1053 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1055 skip("Failed to create a 3D device, skipping test.\n");
1056 DestroyWindow(window
);
1060 viewport
= create_viewport(device
, 0, 0, 640, 480);
1062 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1063 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1064 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1065 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1066 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1067 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1068 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1069 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1070 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1071 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
1072 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1073 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1074 color
= get_surface_color(rt
, 320, 240);
1075 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1077 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1078 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1079 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1080 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1081 IDirect3D3_Release(d3d
);
1082 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1083 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1084 hr
= IDirectDrawSurface4_IsLost(rt
);
1085 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1086 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
1087 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
1088 IDirectDraw4_Release(ddraw
);
1090 hr
= IDirect3DDevice3_GetRenderTarget(device
, &surface
);
1091 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1092 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1093 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1094 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1095 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1096 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1097 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1098 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1099 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
1100 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1101 color
= get_surface_color(rt
, 320, 240);
1102 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1104 destroy_viewport(device
, viewport
);
1105 IDirectDrawSurface4_Release(surface
);
1106 IDirectDrawSurface4_Release(rt
);
1107 IDirect3DDevice3_Release(device
);
1108 DestroyWindow(window
);
1111 static void test_surface_interface_mismatch(void)
1113 IDirectDraw4
*ddraw
= NULL
;
1114 IDirect3D3
*d3d
= NULL
;
1115 IDirectDrawSurface4
*surface
= NULL
, *ds
;
1116 IDirectDrawSurface3
*surface3
= NULL
;
1117 IDirect3DDevice3
*device
= NULL
;
1118 IDirect3DViewport3
*viewport
= NULL
;
1119 DDSURFACEDESC2 surface_desc
;
1120 DDPIXELFORMAT z_fmt
;
1125 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1127 window
= create_window();
1128 ddraw
= create_ddraw();
1129 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1130 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1131 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1133 memset(&surface_desc
, 0, sizeof(surface_desc
));
1134 surface_desc
.dwSize
= sizeof(surface_desc
);
1135 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1137 surface_desc
.dwWidth
= 640;
1138 surface_desc
.dwHeight
= 480;
1140 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1141 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1143 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1144 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
1146 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
1148 skip("D3D interface is not available, skipping test.\n");
1152 memset(&z_fmt
, 0, sizeof(z_fmt
));
1153 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
1154 if (FAILED(hr
) || !z_fmt
.dwSize
)
1156 skip("No depth buffer formats available, skipping test.\n");
1160 memset(&surface_desc
, 0, sizeof(surface_desc
));
1161 surface_desc
.dwSize
= sizeof(surface_desc
);
1162 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
1163 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1164 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
1165 surface_desc
.dwWidth
= 640;
1166 surface_desc
.dwHeight
= 480;
1167 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1168 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1172 /* Using a different surface interface version still works */
1173 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1174 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1175 refcount
= IDirectDrawSurface4_Release(ds
);
1176 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1181 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
1182 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1186 viewport
= create_viewport(device
, 0, 0, 640, 480);
1188 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1189 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1190 color
= get_surface_color(surface
, 320, 240);
1191 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1195 destroy_viewport(device
, viewport
);
1196 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1197 if (surface
) IDirectDrawSurface4_Release(surface
);
1198 if (device
) IDirect3DDevice3_Release(device
);
1199 if (d3d
) IDirect3D3_Release(d3d
);
1200 if (ddraw
) IDirectDraw4_Release(ddraw
);
1201 DestroyWindow(window
);
1204 static void test_coop_level_threaded(void)
1206 struct create_window_thread_param p
;
1207 IDirectDraw4
*ddraw
;
1210 ddraw
= create_ddraw();
1211 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1212 create_window_thread(&p
);
1214 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1215 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1217 IDirectDraw4_Release(ddraw
);
1218 destroy_window_thread(&p
);
1221 static void test_depth_blit(void)
1230 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1231 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1232 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1233 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1235 static const D3DCOLOR expected_colors
[4][4] =
1237 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1238 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1239 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1240 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1242 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1244 IDirect3DDevice3
*device
;
1245 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1246 IDirect3DViewport3
*viewport
;
1247 RECT src_rect
, dst_rect
;
1252 IDirectDraw4
*ddraw
;
1257 window
= create_window();
1258 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1260 skip("Failed to create a 3D device, skipping test.\n");
1261 DestroyWindow(window
);
1265 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1266 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1267 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1268 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1269 IDirect3D3_Release(d3d
);
1271 ds1
= get_depth_stencil(device
);
1273 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1274 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1275 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1276 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1277 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1278 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1279 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1280 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1281 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1282 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1283 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1284 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1285 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1286 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1287 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1288 IDirectDraw4_Release(ddraw
);
1290 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1291 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1292 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1294 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1295 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1296 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1297 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1299 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1300 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1301 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1302 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1305 SetRect(&src_rect
, 0, 0, 320, 240);
1306 SetRect(&dst_rect
, 0, 0, 320, 240);
1307 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1308 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1309 /* Different locations. */
1310 SetRect(&src_rect
, 0, 0, 320, 240);
1311 SetRect(&dst_rect
, 320, 240, 640, 480);
1312 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1313 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1315 SetRect(&src_rect
, 0, 0, 320, 240);
1316 SetRect(&dst_rect
, 0, 0, 640, 480);
1317 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1318 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1320 SetRect(&src_rect
, 0, 480, 640, 0);
1321 SetRect(&dst_rect
, 0, 0, 640, 480);
1322 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1323 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1324 SetRect(&src_rect
, 0, 0, 640, 480);
1325 SetRect(&dst_rect
, 0, 480, 640, 0);
1326 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1327 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1328 /* Full, explicit. */
1329 SetRect(&src_rect
, 0, 0, 640, 480);
1330 SetRect(&dst_rect
, 0, 0, 640, 480);
1331 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1332 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1333 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1335 /* Depth blit inside a BeginScene / EndScene pair */
1336 hr
= IDirect3DDevice3_BeginScene(device
);
1337 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1338 /* From the current depth stencil */
1339 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1340 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1341 /* To the current depth stencil */
1342 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1343 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1344 /* Between unbound surfaces */
1345 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1346 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1347 hr
= IDirect3DDevice3_EndScene(device
);
1348 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1350 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1351 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1352 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1353 * a reliable result(z = 0.0) */
1354 memset(&fx
, 0, sizeof(fx
));
1355 fx
.dwSize
= sizeof(fx
);
1356 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1357 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1359 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1360 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1361 SetRect(&dst_rect
, 0, 0, 320, 240);
1362 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1363 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1364 IDirectDrawSurface4_Release(ds3
);
1365 IDirectDrawSurface4_Release(ds2
);
1366 IDirectDrawSurface4_Release(ds1
);
1368 hr
= IDirect3DDevice3_BeginScene(device
);
1369 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1370 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1372 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1373 hr
= IDirect3DDevice3_EndScene(device
);
1374 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1376 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1377 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1378 for (i
= 0; i
< 4; ++i
)
1380 for (j
= 0; j
< 4; ++j
)
1382 unsigned int x
= 80 * ((2 * j
) + 1);
1383 unsigned int y
= 60 * ((2 * i
) + 1);
1384 color
= get_surface_color(rt
, x
, y
);
1385 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1386 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1389 IDirectDrawSurface4_Release(rt
);
1391 destroy_viewport(device
, viewport
);
1392 IDirect3DDevice3_Release(device
);
1393 DestroyWindow(window
);
1396 static void test_texture_load_ckey(void)
1398 IDirectDraw4
*ddraw
;
1399 IDirectDrawSurface4
*src
;
1400 IDirectDrawSurface4
*dst
;
1401 IDirect3DTexture2
*src_tex
;
1402 IDirect3DTexture2
*dst_tex
;
1403 DDSURFACEDESC2 ddsd
;
1407 ddraw
= create_ddraw();
1408 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1409 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1410 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1412 memset(&ddsd
, 0, sizeof(ddsd
));
1413 ddsd
.dwSize
= sizeof(ddsd
);
1414 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1415 ddsd
.dwHeight
= 128;
1417 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1418 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1419 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1420 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1421 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1422 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1424 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1425 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1428 /* 64 bit ddraw does not support d3d */
1429 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1430 IDirectDrawSurface4_Release(dst
);
1431 IDirectDrawSurface4_Release(src
);
1432 IDirectDraw4_Release(ddraw
);
1435 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1436 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1438 /* No surface has a color key */
1439 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1440 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1441 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1442 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1443 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1444 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1445 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1447 /* Source surface has a color key */
1448 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1449 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1450 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1451 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1452 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1453 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1454 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1455 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1456 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1458 /* Both surfaces have a color key: Dest ckey is overwritten */
1459 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1460 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1461 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1462 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1463 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1464 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1465 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1466 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1467 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1469 /* Only the destination has a color key: It is not deleted */
1470 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1471 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1472 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1473 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1474 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1475 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1476 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1477 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1478 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1479 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1481 IDirect3DTexture2_Release(dst_tex
);
1482 IDirect3DTexture2_Release(src_tex
);
1483 IDirectDrawSurface4_Release(dst
);
1484 IDirectDrawSurface4_Release(src
);
1485 IDirectDraw4_Release(ddraw
);
1488 static ULONG
get_refcount(IUnknown
*test_iface
)
1490 IUnknown_AddRef(test_iface
);
1491 return IUnknown_Release(test_iface
);
1494 static void test_viewport(void)
1496 IDirectDraw4
*ddraw
;
1498 HRESULT hr
, old_d3d_ref
;
1500 IDirect3DViewport
*viewport
;
1501 IDirect3DViewport2
*viewport2
;
1502 IDirect3DViewport3
*viewport3
, *another_vp
, *test_vp
;
1503 IDirectDrawGammaControl
*gamma
;
1506 IDirect3DDevice3
*device
;
1508 window
= create_window();
1509 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1511 skip("Failed to create a 3D device, skipping test.\n");
1512 DestroyWindow(window
);
1515 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1516 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1517 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1518 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1519 old_d3d_ref
= get_refcount((IUnknown
*) d3d
);
1521 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1522 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1523 ref
= get_refcount((IUnknown
*)viewport3
);
1524 ok(ref
== 1, "Initial IDirect3DViewport3 refcount is %u\n", ref
);
1525 ref
= get_refcount((IUnknown
*)d3d
);
1526 ok(ref
== old_d3d_ref
, "IDirect3D3 refcount is %u\n", ref
);
1528 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1529 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1530 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1531 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1532 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1533 /* NULL iid: Segfaults */
1535 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1536 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1539 ref
= get_refcount((IUnknown
*)viewport
);
1540 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1541 ref
= get_refcount((IUnknown
*)viewport3
);
1542 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1543 IDirect3DViewport_Release(viewport
);
1547 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1548 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1551 ref
= get_refcount((IUnknown
*)viewport2
);
1552 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1553 ref
= get_refcount((IUnknown
*)viewport3
);
1554 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1555 IDirect3DViewport3_Release(viewport2
);
1558 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IUnknown
, (void **)&unknown
);
1559 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1562 ref
= get_refcount((IUnknown
*)viewport3
);
1563 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1564 ref
= get_refcount(unknown
);
1565 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1566 IUnknown_Release(unknown
);
1569 /* AddViewport(NULL): Segfault */
1570 hr
= IDirect3DDevice3_DeleteViewport(device
, NULL
);
1571 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1572 hr
= IDirect3DDevice3_GetCurrentViewport(device
, NULL
);
1573 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1575 hr
= IDirect3D3_CreateViewport(d3d
, &another_vp
, NULL
);
1576 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1578 /* Setting a viewport not in the viewport list fails */
1579 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1580 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1582 hr
= IDirect3DDevice3_AddViewport(device
, viewport3
);
1583 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1584 ref
= get_refcount((IUnknown
*) viewport3
);
1585 ok(ref
== 2, "viewport3 refcount is %d\n", ref
);
1586 hr
= IDirect3DDevice3_AddViewport(device
, another_vp
);
1587 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1588 ref
= get_refcount((IUnknown
*) another_vp
);
1589 ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1591 test_vp
= (IDirect3DViewport3
*) 0xbaadc0de;
1592 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1593 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1594 ok(test_vp
== (IDirect3DViewport3
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1596 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1597 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1598 ref
= get_refcount((IUnknown
*) viewport3
);
1599 ok(ref
== 3, "viewport3 refcount is %d\n", ref
);
1600 ref
= get_refcount((IUnknown
*) device
);
1601 ok(ref
== 1, "device refcount is %d\n", ref
);
1604 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1605 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1606 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1607 ref
= get_refcount((IUnknown
*) viewport3
);
1608 ok(ref
== 4, "viewport3 refcount is %d\n", ref
);
1609 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1611 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1613 /* Cannot set the viewport to NULL */
1614 hr
= IDirect3DDevice3_SetCurrentViewport(device
, NULL
);
1615 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1617 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1618 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1619 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1620 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1622 /* SetCurrentViewport properly releases the old viewport's reference */
1623 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1624 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1625 ref
= get_refcount((IUnknown
*) viewport3
);
1626 ok(ref
== 2, "viewport3 refcount is %d\n", ref
);
1627 ref
= get_refcount((IUnknown
*) another_vp
);
1628 ok(ref
== 3, "another_vp refcount is %d\n", ref
);
1630 /* Unlike device2::DeleteViewport, device3::DeleteViewport releases the
1631 * reference held by SetCurrentViewport */
1632 hr
= IDirect3DDevice3_DeleteViewport(device
, another_vp
);
1633 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1634 ref
= get_refcount((IUnknown
*) another_vp
);
1635 ok(ref
== 1, "another_vp refcount is %d\n", ref
);
1637 /* GetCurrentViewport still fails */
1639 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1640 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1641 ok(test_vp
== NULL
, "Got unexpected viewport %p\n", test_vp
);
1642 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1644 /* Setting a different viewport doesn't have any surprises now */
1645 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1646 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1647 ref
= get_refcount((IUnknown
*) viewport3
);
1648 ok(ref
== 3, "viewport3 refcount is %d\n", ref
);
1649 ref
= get_refcount((IUnknown
*) another_vp
);
1650 ok(ref
== 1, "another_vp refcount is %d\n", ref
);
1652 /* Destroying the device removes the viewport and releases the reference */
1653 IDirect3DDevice3_Release(device
);
1654 ref
= get_refcount((IUnknown
*) viewport3
);
1655 ok(ref
== 1, "viewport3 refcount is %d\n", ref
);
1657 ref
= IDirect3DViewport3_Release(another_vp
);
1658 ok(ref
== 0, "Got unexpected ref %d\n", ref
);
1659 ref
= IDirect3DViewport3_Release(viewport3
);
1660 ok(ref
== 0, "Got unexpected ref %d\n", ref
);
1661 IDirect3D3_Release(d3d
);
1662 DestroyWindow(window
);
1663 IDirectDraw4_Release(ddraw
);
1666 static void test_zenable(void)
1668 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1671 struct vec4 position
;
1676 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1677 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1678 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1679 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1681 IDirect3DViewport3
*viewport
;
1682 IDirect3DDevice3
*device
;
1683 IDirectDrawSurface4
*rt
;
1690 window
= create_window();
1691 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1693 skip("Failed to create a 3D device, skipping test.\n");
1694 DestroyWindow(window
);
1698 viewport
= create_viewport(device
, 0, 0, 640, 480);
1699 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1700 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1702 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1703 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1705 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1706 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1707 hr
= IDirect3DDevice3_BeginScene(device
);
1708 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1709 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1710 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1711 hr
= IDirect3DDevice3_EndScene(device
);
1712 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1714 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1715 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1716 for (i
= 0; i
< 4; ++i
)
1718 for (j
= 0; j
< 4; ++j
)
1720 x
= 80 * ((2 * j
) + 1);
1721 y
= 60 * ((2 * i
) + 1);
1722 color
= get_surface_color(rt
, x
, y
);
1723 ok(compare_color(color
, 0x0000ff00, 1),
1724 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1727 IDirectDrawSurface4_Release(rt
);
1729 destroy_viewport(device
, viewport
);
1730 IDirect3DDevice3_Release(device
);
1731 DestroyWindow(window
);
1734 static void test_ck_rgba(void)
1736 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1739 struct vec4 position
;
1740 struct vec2 texcoord
;
1744 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1745 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1746 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1747 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1748 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1749 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1750 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1751 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1755 D3DCOLOR fill_color
;
1758 D3DCOLOR result1
, result1_broken
;
1759 D3DCOLOR result2
, result2_broken
;
1763 /* r200 on Windows doesn't check the alpha component when applying the color
1764 * key, so the key matches on every texel. */
1765 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1766 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1767 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1768 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1769 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1770 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1771 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1772 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1775 IDirectDrawSurface4
*surface
;
1776 IDirect3DViewport3
*viewport
;
1777 DDSURFACEDESC2 surface_desc
;
1778 IDirect3DTexture2
*texture
;
1779 IDirect3DDevice3
*device
;
1780 IDirectDrawSurface4
*rt
;
1781 IDirectDraw4
*ddraw
;
1789 window
= create_window();
1790 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1792 skip("Failed to create a 3D device, skipping test.\n");
1793 DestroyWindow(window
);
1797 viewport
= create_viewport(device
, 0, 0, 640, 480);
1798 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1799 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1801 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1802 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1803 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1804 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1805 IDirect3D3_Release(d3d
);
1807 memset(&surface_desc
, 0, sizeof(surface_desc
));
1808 surface_desc
.dwSize
= sizeof(surface_desc
);
1809 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1810 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1811 surface_desc
.dwWidth
= 256;
1812 surface_desc
.dwHeight
= 256;
1813 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1814 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1815 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1816 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1817 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1818 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1819 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1820 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1821 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1822 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1823 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1824 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1825 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1827 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1828 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1829 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1830 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1831 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1832 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1834 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1835 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1837 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1839 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1840 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1841 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1842 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1844 memset(&fx
, 0, sizeof(fx
));
1845 fx
.dwSize
= sizeof(fx
);
1846 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1847 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1848 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1850 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
1851 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1852 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1853 hr
= IDirect3DDevice3_BeginScene(device
);
1854 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1855 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1856 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1857 hr
= IDirect3DDevice3_EndScene(device
);
1858 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1860 color
= get_surface_color(rt
, 320, 240);
1861 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
1862 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1863 tests
[i
].result1
, i
, color
);
1865 U5(fx
).dwFillColor
= 0xff0000ff;
1866 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1867 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1869 hr
= IDirect3DDevice3_BeginScene(device
);
1870 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1871 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1872 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1873 hr
= IDirect3DDevice3_EndScene(device
);
1874 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1876 /* This tests that fragments that are masked out by the color key are
1877 * discarded, instead of just fully transparent. */
1878 color
= get_surface_color(rt
, 320, 240);
1879 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
1880 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1881 tests
[i
].result2
, i
, color
);
1884 IDirectDrawSurface4_Release(rt
);
1885 IDirect3DTexture2_Release(texture
);
1886 IDirectDrawSurface4_Release(surface
);
1887 destroy_viewport(device
, viewport
);
1888 IDirectDraw4_Release(ddraw
);
1889 IDirect3DDevice3_Release(device
);
1890 DestroyWindow(window
);
1893 static void test_ck_default(void)
1895 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1898 struct vec4 position
;
1899 struct vec2 texcoord
;
1903 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
1904 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
1905 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
1906 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
1908 IDirectDrawSurface4
*surface
, *rt
;
1909 IDirect3DViewport3
*viewport
;
1910 DDSURFACEDESC2 surface_desc
;
1911 IDirect3DTexture2
*texture
;
1912 IDirect3DDevice3
*device
;
1913 IDirectDraw4
*ddraw
;
1921 window
= create_window();
1922 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1924 skip("Failed to create a 3D device, skipping test.\n");
1925 DestroyWindow(window
);
1929 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1930 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1931 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1932 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1933 IDirect3D3_Release(d3d
);
1935 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1936 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1938 viewport
= create_viewport(device
, 0, 0, 640, 480);
1939 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1940 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1942 memset(&surface_desc
, 0, sizeof(surface_desc
));
1943 surface_desc
.dwSize
= sizeof(surface_desc
);
1944 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1945 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1946 surface_desc
.dwWidth
= 256;
1947 surface_desc
.dwHeight
= 256;
1948 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1949 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1950 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1951 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1952 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1953 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1954 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1955 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1956 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1957 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1958 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1959 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1960 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1961 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1963 memset(&fx
, 0, sizeof(fx
));
1964 fx
.dwSize
= sizeof(fx
);
1965 U5(fx
).dwFillColor
= 0x000000ff;
1966 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1967 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1969 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1970 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1971 hr
= IDirect3DDevice3_BeginScene(device
);
1972 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1973 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1974 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1975 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1976 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1977 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1978 hr
= IDirect3DDevice3_EndScene(device
);
1979 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1980 color
= get_surface_color(rt
, 320, 240);
1981 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1983 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1984 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1985 hr
= IDirect3DDevice3_BeginScene(device
);
1986 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1987 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1988 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1989 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1990 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1991 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1992 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1993 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1994 hr
= IDirect3DDevice3_EndScene(device
);
1995 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1996 color
= get_surface_color(rt
, 320, 240);
1997 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1999 IDirect3DTexture_Release(texture
);
2000 IDirectDrawSurface4_Release(surface
);
2001 destroy_viewport(device
, viewport
);
2002 IDirectDrawSurface4_Release(rt
);
2003 IDirect3DDevice3_Release(device
);
2004 IDirectDraw4_Release(ddraw
);
2005 DestroyWindow(window
);
2008 static void test_ck_complex(void)
2010 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
2011 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
2012 DDSURFACEDESC2 surface_desc
;
2013 IDirect3DDevice3
*device
;
2014 DDCOLORKEY color_key
;
2015 IDirectDraw4
*ddraw
;
2022 window
= create_window();
2023 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2025 skip("Failed to create a 3D device, skipping test.\n");
2026 DestroyWindow(window
);
2029 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2030 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2031 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2032 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
2033 IDirect3D3_Release(d3d
);
2035 memset(&surface_desc
, 0, sizeof(surface_desc
));
2036 surface_desc
.dwSize
= sizeof(surface_desc
);
2037 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2038 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2039 surface_desc
.dwWidth
= 128;
2040 surface_desc
.dwHeight
= 128;
2041 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2042 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2044 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2045 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2046 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2047 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2048 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2049 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2050 memset(&color_key
, 0, sizeof(color_key
));
2051 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2052 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2053 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2054 color_key
.dwColorSpaceLowValue
);
2055 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2056 color_key
.dwColorSpaceHighValue
);
2059 IDirectDrawSurface_AddRef(mipmap
);
2060 for (i
= 0; i
< 7; ++i
)
2062 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2063 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2065 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2066 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2067 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2068 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2069 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2070 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
2071 memset(&color_key
, 0, sizeof(color_key
));
2072 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2073 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
2074 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2075 color_key
.dwColorSpaceLowValue
, i
);
2076 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2077 color_key
.dwColorSpaceHighValue
, i
);
2079 IDirectDrawSurface_Release(mipmap
);
2083 memset(&color_key
, 0, sizeof(color_key
));
2084 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2085 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2086 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2087 color_key
.dwColorSpaceLowValue
);
2088 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2089 color_key
.dwColorSpaceHighValue
);
2091 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2092 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2093 IDirectDrawSurface_Release(mipmap
);
2094 refcount
= IDirectDrawSurface4_Release(surface
);
2095 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2097 memset(&surface_desc
, 0, sizeof(surface_desc
));
2098 surface_desc
.dwSize
= sizeof(surface_desc
);
2099 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2100 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2101 U5(surface_desc
).dwBackBufferCount
= 1;
2102 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2103 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2105 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2106 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2107 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2108 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2109 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2110 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2111 memset(&color_key
, 0, sizeof(color_key
));
2112 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2113 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2114 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2115 color_key
.dwColorSpaceLowValue
);
2116 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2117 color_key
.dwColorSpaceHighValue
);
2119 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
2120 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2122 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2123 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2124 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2125 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2126 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2127 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2128 memset(&color_key
, 0, sizeof(color_key
));
2129 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2130 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2131 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2132 color_key
.dwColorSpaceLowValue
);
2133 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2134 color_key
.dwColorSpaceHighValue
);
2136 IDirectDrawSurface_Release(tmp
);
2138 refcount
= IDirectDrawSurface4_Release(surface
);
2139 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2140 IDirectDraw4_Release(ddraw
);
2141 refcount
= IDirect3DDevice3_Release(device
);
2142 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2143 DestroyWindow(window
);
2149 REFIID refcount_iid
;
2153 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2154 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2156 ULONG refcount
, expected_refcount
;
2157 IUnknown
*iface1
, *iface2
;
2161 for (i
= 0; i
< entry_count
; ++i
)
2163 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2164 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2167 for (j
= 0; j
< entry_count
; ++j
)
2169 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2170 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2173 expected_refcount
= 0;
2174 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2175 ++expected_refcount
;
2176 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2177 ++expected_refcount
;
2178 refcount
= IUnknown_Release(iface2
);
2179 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2180 refcount
, test_name
, i
, j
, expected_refcount
);
2184 expected_refcount
= 0;
2185 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2186 ++expected_refcount
;
2187 refcount
= IUnknown_Release(iface1
);
2188 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2189 refcount
, test_name
, i
, expected_refcount
);
2194 static void test_surface_qi(void)
2196 static const struct qi_test tests
[] =
2198 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface4
, S_OK
},
2199 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface4
, S_OK
},
2200 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2201 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2202 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2203 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2204 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2205 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2206 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2207 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2208 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2209 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2210 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2211 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2212 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2213 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2214 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2215 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2216 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2217 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2218 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2219 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2220 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2221 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2222 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2223 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2224 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2225 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2226 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2227 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2228 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2229 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2230 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2231 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2232 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2233 {NULL
, NULL
, E_INVALIDARG
},
2236 IDirectDrawSurface4
*surface
;
2237 DDSURFACEDESC2 surface_desc
;
2238 IDirect3DDevice3
*device
;
2239 IDirectDraw4
*ddraw
;
2243 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2245 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2249 window
= create_window();
2250 /* Try to create a D3D device to see if the ddraw implementation supports
2251 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2252 * doesn't support e.g. the IDirect3DTexture interfaces. */
2253 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2255 skip("Failed to create a 3D device, skipping test.\n");
2256 DestroyWindow(window
);
2259 IDirect3DDevice_Release(device
);
2260 ddraw
= create_ddraw();
2261 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2262 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2263 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2265 memset(&surface_desc
, 0, sizeof(surface_desc
));
2266 surface_desc
.dwSize
= sizeof(surface_desc
);
2267 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2268 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2269 surface_desc
.dwWidth
= 512;
2270 surface_desc
.dwHeight
= 512;
2271 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface4
**)0xdeadbeef, NULL
);
2272 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2273 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2274 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2276 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface4
, tests
, ARRAY_SIZE(tests
));
2278 IDirectDrawSurface4_Release(surface
);
2279 IDirectDraw4_Release(ddraw
);
2280 DestroyWindow(window
);
2283 static void test_device_qi(void)
2285 static const struct qi_test tests
[] =
2287 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2288 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2289 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2290 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2291 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2292 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2293 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2294 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2295 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2296 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2297 {&IID_IDirect3DDevice3
, &IID_IDirect3DDevice3
, S_OK
},
2298 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice3
, S_OK
},
2299 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice3
, S_OK
},
2300 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2301 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2302 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2303 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2304 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2305 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2306 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2307 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2308 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2309 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2310 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2311 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2312 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2313 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2314 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2315 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2316 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2317 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2318 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2319 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2320 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2321 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2322 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2323 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2324 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2325 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2326 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2327 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2328 {&IID_IUnknown
, &IID_IDirect3DDevice3
, S_OK
},
2331 IDirect3DDevice3
*device
;
2334 window
= create_window();
2335 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2337 skip("Failed to create a 3D device, skipping test.\n");
2338 DestroyWindow(window
);
2342 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice3
, tests
, ARRAY_SIZE(tests
));
2344 IDirect3DDevice3_Release(device
);
2345 DestroyWindow(window
);
2348 static void test_wndproc(void)
2350 LONG_PTR proc
, ddraw_proc
;
2351 IDirectDraw4
*ddraw
;
2357 static struct message messages
[] =
2359 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2360 {WM_MOVE
, FALSE
, 0},
2361 {WM_SIZE
, FALSE
, 0},
2362 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2363 {WM_ACTIVATE
, FALSE
, 0},
2364 {WM_SETFOCUS
, FALSE
, 0},
2368 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2369 ddraw
= create_ddraw();
2370 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2372 wc
.lpfnWndProc
= test_proc
;
2373 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2374 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2376 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2377 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2379 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2380 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2381 (LONG_PTR
)test_proc
, proc
);
2382 expect_messages
= messages
;
2383 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2384 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2385 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2386 expect_messages
= NULL
;
2387 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2388 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2389 (LONG_PTR
)test_proc
, proc
);
2390 ref
= IDirectDraw4_Release(ddraw
);
2391 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2392 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2393 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2394 (LONG_PTR
)test_proc
, proc
);
2396 /* DDSCL_NORMAL doesn't. */
2397 ddraw
= create_ddraw();
2398 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2399 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2400 (LONG_PTR
)test_proc
, proc
);
2401 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2402 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2403 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2404 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2405 (LONG_PTR
)test_proc
, proc
);
2406 ref
= IDirectDraw4_Release(ddraw
);
2407 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2408 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2409 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2410 (LONG_PTR
)test_proc
, proc
);
2412 /* The original window proc is only restored by ddraw if the current
2413 * window proc matches the one ddraw set. This also affects switching
2414 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2415 ddraw
= create_ddraw();
2416 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2417 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2418 (LONG_PTR
)test_proc
, proc
);
2419 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2420 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2421 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2422 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2423 (LONG_PTR
)test_proc
, proc
);
2425 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2426 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2427 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2428 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2429 (LONG_PTR
)test_proc
, proc
);
2430 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2431 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2432 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2433 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2434 (LONG_PTR
)test_proc
, proc
);
2435 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2436 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2437 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2438 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2439 (LONG_PTR
)DefWindowProcA
, proc
);
2440 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2441 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2442 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2443 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2444 (LONG_PTR
)DefWindowProcA
, proc
);
2445 ref
= IDirectDraw4_Release(ddraw
);
2446 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2447 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2448 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2449 (LONG_PTR
)test_proc
, proc
);
2451 ddraw
= create_ddraw();
2452 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2453 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2454 (LONG_PTR
)test_proc
, proc
);
2455 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2456 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2457 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2458 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2459 (LONG_PTR
)test_proc
, proc
);
2460 ref
= IDirectDraw4_Release(ddraw
);
2461 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2462 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2463 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2464 (LONG_PTR
)DefWindowProcA
, proc
);
2466 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2467 expect_messages
= NULL
;
2468 DestroyWindow(window
);
2469 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2472 static void test_window_style(void)
2474 LONG style
, exstyle
, tmp
, expected_style
;
2475 RECT fullscreen_rect
, r
;
2476 IDirectDraw4
*ddraw
;
2482 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2483 0, 0, 100, 100, 0, 0, 0, 0);
2484 ddraw
= create_ddraw();
2485 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2487 style
= GetWindowLongA(window
, GWL_STYLE
);
2488 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2489 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2491 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2492 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2494 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2495 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2496 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2497 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2499 GetWindowRect(window
, &r
);
2500 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2501 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2502 GetClientRect(window
, &r
);
2503 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2505 ret
= SetForegroundWindow(GetDesktopWindow());
2506 ok(ret
, "Failed to set foreground window.\n");
2508 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2509 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2510 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2511 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2513 ret
= SetForegroundWindow(window
);
2514 ok(ret
, "Failed to set foreground window.\n");
2515 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2516 * the next tests expect this. */
2517 ShowWindow(window
, SW_HIDE
);
2519 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2520 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2522 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2523 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2524 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2525 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2527 ShowWindow(window
, SW_SHOW
);
2528 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2529 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2531 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2532 expected_style
= style
| WS_VISIBLE
;
2533 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2534 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2535 expected_style
= exstyle
| WS_EX_TOPMOST
;
2536 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2538 ret
= SetForegroundWindow(GetDesktopWindow());
2539 ok(ret
, "Failed to set foreground window.\n");
2540 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2541 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2542 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2543 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2544 expected_style
= exstyle
| WS_EX_TOPMOST
;
2545 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2547 ref
= IDirectDraw4_Release(ddraw
);
2548 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2550 DestroyWindow(window
);
2553 static void test_redundant_mode_set(void)
2555 DDSURFACEDESC2 surface_desc
= {0};
2556 IDirectDraw4
*ddraw
;
2562 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2563 0, 0, 100, 100, 0, 0, 0, 0);
2564 ddraw
= create_ddraw();
2565 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2567 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2568 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2570 surface_desc
.dwSize
= sizeof(surface_desc
);
2571 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
2572 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2574 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2575 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2576 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2578 GetWindowRect(window
, &q
);
2582 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2583 GetWindowRect(window
, &s
);
2584 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2586 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2587 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2588 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2590 GetWindowRect(window
, &s
);
2591 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2592 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2594 ref
= IDirectDraw4_Release(ddraw
);
2595 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2597 DestroyWindow(window
);
2600 static SIZE screen_size
, screen_size2
;
2602 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2604 if (message
== WM_SIZE
)
2606 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2607 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2610 return test_proc(hwnd
, message
, wparam
, lparam
);
2613 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2615 if (message
== WM_SIZE
)
2617 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2618 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2621 return test_proc(hwnd
, message
, wparam
, lparam
);
2624 struct test_coop_level_mode_set_enum_param
2626 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2629 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
2631 struct test_coop_level_mode_set_enum_param
*param
= context
;
2633 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2634 return DDENUMRET_OK
;
2635 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2636 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2637 return DDENUMRET_OK
;
2639 if (!param
->ddraw_width
)
2641 param
->ddraw_width
= surface_desc
->dwWidth
;
2642 param
->ddraw_height
= surface_desc
->dwHeight
;
2643 return DDENUMRET_OK
;
2645 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2646 return DDENUMRET_OK
;
2648 param
->user32_width
= surface_desc
->dwWidth
;
2649 param
->user32_height
= surface_desc
->dwHeight
;
2650 return DDENUMRET_CANCEL
;
2653 static void test_coop_level_mode_set(void)
2655 IDirectDrawSurface4
*primary
;
2656 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2657 IDirectDraw4
*ddraw
;
2658 DDSURFACEDESC2 ddsd
;
2660 HWND window
, window2
;
2664 struct test_coop_level_mode_set_enum_param param
;
2669 static const struct message exclusive_messages
[] =
2671 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2672 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2673 {WM_SIZE
, FALSE
, 0},
2674 {WM_DISPLAYCHANGE
, FALSE
, 0},
2677 static const struct message exclusive_focus_loss_messages
[] =
2679 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2680 {WM_DISPLAYCHANGE
, FALSE
, 0},
2681 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2682 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2683 * SW_MINIMIZED, causing a recursive window activation that does not
2684 * produce the same result in Wine yet. Ignore the difference for now.
2685 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2686 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2687 {WM_MOVE
, FALSE
, 0},
2688 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2689 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2692 static const struct message exclusive_focus_restore_messages
[] =
2694 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2695 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2696 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2697 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2698 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2699 /* Native redundantly sets the window size here. */
2700 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2701 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2702 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2703 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2706 static const struct message sc_restore_messages
[] =
2708 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2709 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2710 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2711 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2714 static const struct message sc_minimize_messages
[] =
2716 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2717 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2718 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2719 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2722 static const struct message sc_maximize_messages
[] =
2724 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2725 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2726 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2727 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2731 static const struct message normal_messages
[] =
2733 {WM_DISPLAYCHANGE
, FALSE
, 0},
2737 ddraw
= create_ddraw();
2738 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2740 memset(¶m
, 0, sizeof(param
));
2741 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2742 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2743 ref
= IDirectDraw4_Release(ddraw
);
2744 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2746 if (!param
.user32_height
)
2748 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2752 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2753 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2754 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2756 memset(&devmode
, 0, sizeof(devmode
));
2757 devmode
.dmSize
= sizeof(devmode
);
2758 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2759 devmode
.dmPelsWidth
= param
.user32_width
;
2760 devmode
.dmPelsHeight
= param
.user32_height
;
2761 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2762 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2764 ddraw
= create_ddraw();
2765 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2767 wc
.lpfnWndProc
= mode_set_proc
;
2768 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2769 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2770 wc
.lpfnWndProc
= mode_set_proc2
;
2771 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2772 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2774 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2775 0, 0, 100, 100, 0, 0, 0, 0);
2776 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2777 0, 0, 100, 100, 0, 0, 0, 0);
2779 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2780 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2782 GetWindowRect(window
, &r
);
2783 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2784 wine_dbgstr_rect(&r
));
2786 memset(&ddsd
, 0, sizeof(ddsd
));
2787 ddsd
.dwSize
= sizeof(ddsd
);
2788 ddsd
.dwFlags
= DDSD_CAPS
;
2789 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2791 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2792 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2793 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2794 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2795 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2796 param
.user32_width
, ddsd
.dwWidth
);
2797 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2798 param
.user32_height
, ddsd
.dwHeight
);
2800 GetWindowRect(window
, &r
);
2801 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2802 wine_dbgstr_rect(&r
));
2804 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2805 expect_messages
= exclusive_messages
;
2809 hr
= IDirectDrawSurface4_IsLost(primary
);
2810 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2811 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2812 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2813 hr
= IDirectDrawSurface4_IsLost(primary
);
2814 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2816 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2817 expect_messages
= NULL
;
2818 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2819 "Expected screen size %ux%u, got %ux%u.\n",
2820 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2822 GetWindowRect(window
, &r
);
2823 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2824 wine_dbgstr_rect(&r
));
2826 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2827 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2828 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2829 param
.user32_width
, ddsd
.dwWidth
);
2830 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2831 param
.user32_height
, ddsd
.dwHeight
);
2832 IDirectDrawSurface4_Release(primary
);
2834 memset(&ddsd
, 0, sizeof(ddsd
));
2835 ddsd
.dwSize
= sizeof(ddsd
);
2836 ddsd
.dwFlags
= DDSD_CAPS
;
2837 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2839 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2840 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2841 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2842 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2843 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2844 param
.ddraw_width
, ddsd
.dwWidth
);
2845 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2846 param
.ddraw_height
, ddsd
.dwHeight
);
2848 GetWindowRect(window
, &r
);
2849 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2850 wine_dbgstr_rect(&r
));
2852 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2853 expect_messages
= exclusive_messages
;
2857 hr
= IDirectDrawSurface4_IsLost(primary
);
2858 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2859 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2860 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2861 hr
= IDirectDrawSurface4_IsLost(primary
);
2862 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2864 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2865 expect_messages
= NULL
;
2866 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2867 "Expected screen size %ux%u, got %ux%u.\n",
2868 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2870 GetWindowRect(window
, &r
);
2871 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2872 wine_dbgstr_rect(&r
));
2874 expect_messages
= exclusive_focus_loss_messages
;
2875 ret
= SetForegroundWindow(GetDesktopWindow());
2876 ok(ret
, "Failed to set foreground window.\n");
2877 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2878 memset(&devmode
, 0, sizeof(devmode
));
2879 devmode
.dmSize
= sizeof(devmode
);
2880 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2881 ok(ret
, "Failed to get display mode.\n");
2882 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2883 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
2884 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2886 expect_messages
= exclusive_focus_restore_messages
;
2887 ShowWindow(window
, SW_RESTORE
);
2888 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2890 GetWindowRect(window
, &r
);
2891 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2892 wine_dbgstr_rect(&r
));
2893 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2894 ok(ret
, "Failed to get display mode.\n");
2895 ok(devmode
.dmPelsWidth
== param
.ddraw_width
2896 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
2897 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2899 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2900 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2901 /* Normally the primary should be restored here. Unfortunately this causes the
2902 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
2903 * testbot. Another Restore call would presumably avoid the crash, but it also moots
2904 * the point of the GetSurfaceDesc call. */
2906 expect_messages
= sc_minimize_messages
;
2907 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
2908 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2909 expect_messages
= NULL
;
2911 expect_messages
= sc_restore_messages
;
2912 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
2913 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2914 expect_messages
= NULL
;
2916 expect_messages
= sc_maximize_messages
;
2917 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
2918 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2919 expect_messages
= NULL
;
2921 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2922 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2924 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2925 expect_messages
= exclusive_messages
;
2929 hr
= IDirectDrawSurface4_IsLost(primary
);
2930 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2931 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
2932 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2933 hr
= IDirectDrawSurface4_IsLost(primary
);
2934 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2936 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2937 expect_messages
= NULL
;
2938 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
2939 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
2940 "Expected screen size %ux%u, got %ux%u.\n",
2941 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
2943 GetWindowRect(window
, &r
);
2944 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2945 wine_dbgstr_rect(&r
));
2947 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2948 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2949 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2950 param
.ddraw_width
, ddsd
.dwWidth
);
2951 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2952 param
.ddraw_height
, ddsd
.dwHeight
);
2953 IDirectDrawSurface4_Release(primary
);
2956 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2957 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2959 memset(&ddsd
, 0, sizeof(ddsd
));
2960 ddsd
.dwSize
= sizeof(ddsd
);
2961 ddsd
.dwFlags
= DDSD_CAPS
;
2962 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2964 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2965 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2966 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2967 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2968 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2969 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2970 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2971 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2973 GetWindowRect(window
, &r
);
2974 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2975 wine_dbgstr_rect(&r
));
2977 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2978 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2980 GetWindowRect(window
, &r
);
2981 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2982 wine_dbgstr_rect(&r
));
2984 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2985 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2986 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2987 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2988 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2989 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2990 IDirectDrawSurface4_Release(primary
);
2992 memset(&ddsd
, 0, sizeof(ddsd
));
2993 ddsd
.dwSize
= sizeof(ddsd
);
2994 ddsd
.dwFlags
= DDSD_CAPS
;
2995 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2997 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2998 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2999 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3000 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3001 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3002 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3003 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3004 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3006 GetWindowRect(window
, &r
);
3007 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3008 wine_dbgstr_rect(&r
));
3010 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3011 expect_messages
= normal_messages
;
3015 hr
= IDirectDrawSurface4_IsLost(primary
);
3016 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3017 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3018 devmode
.dmPelsWidth
= param
.user32_width
;
3019 devmode
.dmPelsHeight
= param
.user32_height
;
3020 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3021 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3022 hr
= IDirectDrawSurface4_IsLost(primary
);
3023 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3025 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3026 expect_messages
= NULL
;
3027 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3029 GetWindowRect(window
, &r
);
3030 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3031 wine_dbgstr_rect(&r
));
3033 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3034 expect_messages
= normal_messages
;
3038 hr
= IDirectDrawSurface4_Restore(primary
);
3039 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3040 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3041 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3042 hr
= IDirectDrawSurface4_Restore(primary
);
3043 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3044 hr
= IDirectDrawSurface4_IsLost(primary
);
3045 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3047 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3048 expect_messages
= NULL
;
3049 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3051 GetWindowRect(window
, &r
);
3052 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3053 wine_dbgstr_rect(&r
));
3055 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3056 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3057 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3058 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3059 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3060 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3061 IDirectDrawSurface4_Release(primary
);
3063 memset(&ddsd
, 0, sizeof(ddsd
));
3064 ddsd
.dwSize
= sizeof(ddsd
);
3065 ddsd
.dwFlags
= DDSD_CAPS
;
3066 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3068 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3069 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3070 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3071 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3072 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3073 param
.ddraw_width
, ddsd
.dwWidth
);
3074 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3075 param
.ddraw_height
, ddsd
.dwHeight
);
3077 GetWindowRect(window
, &r
);
3078 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3079 wine_dbgstr_rect(&r
));
3081 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3082 expect_messages
= normal_messages
;
3086 hr
= IDirectDrawSurface4_IsLost(primary
);
3087 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3088 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3089 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3090 hr
= IDirectDrawSurface4_IsLost(primary
);
3091 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3093 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3094 expect_messages
= NULL
;
3095 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3097 GetWindowRect(window
, &r
);
3098 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3099 wine_dbgstr_rect(&r
));
3101 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3102 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3103 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3104 param
.ddraw_width
, ddsd
.dwWidth
);
3105 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3106 param
.ddraw_height
, ddsd
.dwHeight
);
3107 IDirectDrawSurface4_Release(primary
);
3109 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3110 ok(ret
, "Failed to get display mode.\n");
3111 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3112 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3113 "Expected resolution %ux%u, got %ux%u.\n",
3114 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3115 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3116 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3117 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3119 memset(&ddsd
, 0, sizeof(ddsd
));
3120 ddsd
.dwSize
= sizeof(ddsd
);
3121 ddsd
.dwFlags
= DDSD_CAPS
;
3122 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3124 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3125 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3126 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3127 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3128 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3129 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3130 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3131 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3133 GetWindowRect(window
, &r
);
3134 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3135 wine_dbgstr_rect(&r
));
3137 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3138 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3139 * not DDSCL_FULLSCREEN. */
3140 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3141 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3143 GetWindowRect(window
, &r
);
3144 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3145 wine_dbgstr_rect(&r
));
3147 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3148 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3149 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3150 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3151 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3152 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3153 IDirectDrawSurface4_Release(primary
);
3155 memset(&ddsd
, 0, sizeof(ddsd
));
3156 ddsd
.dwSize
= sizeof(ddsd
);
3157 ddsd
.dwFlags
= DDSD_CAPS
;
3158 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3160 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3161 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3162 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3163 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3164 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3165 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3166 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3167 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3169 GetWindowRect(window
, &r
);
3170 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3171 wine_dbgstr_rect(&r
));
3173 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3174 expect_messages
= normal_messages
;
3178 hr
= IDirectDrawSurface4_IsLost(primary
);
3179 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3180 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3181 devmode
.dmPelsWidth
= param
.user32_width
;
3182 devmode
.dmPelsHeight
= param
.user32_height
;
3183 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3184 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3185 hr
= IDirectDrawSurface4_IsLost(primary
);
3186 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3188 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3189 expect_messages
= NULL
;
3190 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3192 GetWindowRect(window
, &r
);
3193 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3194 wine_dbgstr_rect(&r
));
3196 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3197 expect_messages
= normal_messages
;
3201 hr
= IDirectDrawSurface4_Restore(primary
);
3202 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3203 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3204 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3205 hr
= IDirectDrawSurface4_Restore(primary
);
3206 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3207 hr
= IDirectDrawSurface4_IsLost(primary
);
3208 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3210 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3211 expect_messages
= NULL
;
3212 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3214 GetWindowRect(window
, &r
);
3215 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3216 wine_dbgstr_rect(&r
));
3218 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3219 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3220 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3221 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3222 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3223 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3224 IDirectDrawSurface4_Release(primary
);
3226 memset(&ddsd
, 0, sizeof(ddsd
));
3227 ddsd
.dwSize
= sizeof(ddsd
);
3228 ddsd
.dwFlags
= DDSD_CAPS
;
3229 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3231 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3232 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3233 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3234 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3235 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3236 param
.ddraw_width
, ddsd
.dwWidth
);
3237 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3238 param
.ddraw_height
, ddsd
.dwHeight
);
3240 GetWindowRect(window
, &r
);
3241 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3242 wine_dbgstr_rect(&r
));
3244 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3245 expect_messages
= normal_messages
;
3249 hr
= IDirectDrawSurface4_IsLost(primary
);
3250 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3251 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3252 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3253 hr
= IDirectDrawSurface4_IsLost(primary
);
3254 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3256 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3257 expect_messages
= NULL
;
3258 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3260 GetWindowRect(window
, &r
);
3261 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3262 wine_dbgstr_rect(&r
));
3264 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3265 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3266 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3267 param
.ddraw_width
, ddsd
.dwWidth
);
3268 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3269 param
.ddraw_height
, ddsd
.dwHeight
);
3270 IDirectDrawSurface4_Release(primary
);
3272 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3273 ok(ret
, "Failed to get display mode.\n");
3274 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3275 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3276 "Expected resolution %ux%u, got %ux%u.\n",
3277 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3278 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3279 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3280 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3282 memset(&ddsd
, 0, sizeof(ddsd
));
3283 ddsd
.dwSize
= sizeof(ddsd
);
3284 ddsd
.dwFlags
= DDSD_CAPS
;
3285 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3287 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3288 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3289 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3290 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3291 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3292 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3293 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3294 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3295 IDirectDrawSurface4_Release(primary
);
3297 GetWindowRect(window
, &r
);
3298 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3299 wine_dbgstr_rect(&r
));
3301 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3302 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3303 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3304 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3305 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3307 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3308 expect_messages
= exclusive_messages
;
3312 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3313 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3315 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3316 expect_messages
= NULL
;
3317 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3318 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3319 "Expected screen size %ux%u, got %ux%u.\n",
3320 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3321 screen_size
.cx
, screen_size
.cy
);
3323 GetWindowRect(window
, &r
);
3324 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3325 wine_dbgstr_rect(&r
));
3327 memset(&ddsd
, 0, sizeof(ddsd
));
3328 ddsd
.dwSize
= sizeof(ddsd
);
3329 ddsd
.dwFlags
= DDSD_CAPS
;
3330 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3332 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3333 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3334 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3335 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3336 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3337 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3338 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3339 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3340 IDirectDrawSurface4_Release(primary
);
3342 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3343 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3344 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3345 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3346 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3348 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3349 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3351 memset(&ddsd
, 0, sizeof(ddsd
));
3352 ddsd
.dwSize
= sizeof(ddsd
);
3353 ddsd
.dwFlags
= DDSD_CAPS
;
3354 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3356 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3357 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3358 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3359 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3360 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3361 param
.ddraw_width
, ddsd
.dwWidth
);
3362 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3363 param
.ddraw_height
, ddsd
.dwHeight
);
3364 IDirectDrawSurface4_Release(primary
);
3366 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3367 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3369 /* If the window is changed at the same time, messages are sent to the new window. */
3370 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3371 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3372 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3373 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3375 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3376 expect_messages
= exclusive_messages
;
3379 screen_size2
.cx
= 0;
3380 screen_size2
.cy
= 0;
3382 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3383 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3385 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3386 expect_messages
= NULL
;
3387 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3388 screen_size
.cx
, screen_size
.cy
);
3389 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3390 "Expected screen size 2 %ux%u, got %ux%u.\n",
3391 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3393 GetWindowRect(window
, &r
);
3394 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3395 wine_dbgstr_rect(&r
));
3396 GetWindowRect(window2
, &r
);
3397 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3398 wine_dbgstr_rect(&r
));
3400 memset(&ddsd
, 0, sizeof(ddsd
));
3401 ddsd
.dwSize
= sizeof(ddsd
);
3402 ddsd
.dwFlags
= DDSD_CAPS
;
3403 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3405 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3406 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3407 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3408 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3409 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3410 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3411 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3412 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3413 IDirectDrawSurface4_Release(primary
);
3415 ref
= IDirectDraw4_Release(ddraw
);
3416 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3418 GetWindowRect(window
, &r
);
3419 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3420 wine_dbgstr_rect(&r
));
3422 expect_messages
= NULL
;
3423 DestroyWindow(window
);
3424 DestroyWindow(window2
);
3425 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3426 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3429 static void test_coop_level_mode_set_multi(void)
3431 IDirectDraw4
*ddraw1
, *ddraw2
;
3437 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3438 0, 0, 100, 100, 0, 0, 0, 0);
3439 ddraw1
= create_ddraw();
3440 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3442 /* With just a single ddraw object, the display mode is restored on
3444 hr
= set_display_mode(ddraw1
, 800, 600);
3445 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3446 w
= GetSystemMetrics(SM_CXSCREEN
);
3447 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3448 h
= GetSystemMetrics(SM_CYSCREEN
);
3449 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3451 ref
= IDirectDraw4_Release(ddraw1
);
3452 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3453 w
= GetSystemMetrics(SM_CXSCREEN
);
3454 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3455 h
= GetSystemMetrics(SM_CYSCREEN
);
3456 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3458 /* When there are multiple ddraw objects, the display mode is restored to
3459 * the initial mode, before the first SetDisplayMode() call. */
3460 ddraw1
= create_ddraw();
3461 hr
= set_display_mode(ddraw1
, 800, 600);
3462 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3463 w
= GetSystemMetrics(SM_CXSCREEN
);
3464 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3465 h
= GetSystemMetrics(SM_CYSCREEN
);
3466 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3468 ddraw2
= create_ddraw();
3469 hr
= set_display_mode(ddraw2
, 640, 480);
3470 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3471 w
= GetSystemMetrics(SM_CXSCREEN
);
3472 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3473 h
= GetSystemMetrics(SM_CYSCREEN
);
3474 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3476 ref
= IDirectDraw4_Release(ddraw2
);
3477 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3478 w
= GetSystemMetrics(SM_CXSCREEN
);
3479 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3480 h
= GetSystemMetrics(SM_CYSCREEN
);
3481 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3483 ref
= IDirectDraw4_Release(ddraw1
);
3484 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3485 w
= GetSystemMetrics(SM_CXSCREEN
);
3486 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3487 h
= GetSystemMetrics(SM_CYSCREEN
);
3488 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3490 /* Regardless of release ordering. */
3491 ddraw1
= create_ddraw();
3492 hr
= set_display_mode(ddraw1
, 800, 600);
3493 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3494 w
= GetSystemMetrics(SM_CXSCREEN
);
3495 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3496 h
= GetSystemMetrics(SM_CYSCREEN
);
3497 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3499 ddraw2
= create_ddraw();
3500 hr
= set_display_mode(ddraw2
, 640, 480);
3501 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3502 w
= GetSystemMetrics(SM_CXSCREEN
);
3503 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3504 h
= GetSystemMetrics(SM_CYSCREEN
);
3505 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3507 ref
= IDirectDraw4_Release(ddraw1
);
3508 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3509 w
= GetSystemMetrics(SM_CXSCREEN
);
3510 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3511 h
= GetSystemMetrics(SM_CYSCREEN
);
3512 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3514 ref
= IDirectDraw4_Release(ddraw2
);
3515 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3516 w
= GetSystemMetrics(SM_CXSCREEN
);
3517 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3518 h
= GetSystemMetrics(SM_CYSCREEN
);
3519 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3521 /* But only for ddraw objects that called SetDisplayMode(). */
3522 ddraw1
= create_ddraw();
3523 ddraw2
= create_ddraw();
3524 hr
= set_display_mode(ddraw2
, 640, 480);
3525 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3526 w
= GetSystemMetrics(SM_CXSCREEN
);
3527 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3528 h
= GetSystemMetrics(SM_CYSCREEN
);
3529 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3531 ref
= IDirectDraw4_Release(ddraw1
);
3532 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3533 w
= GetSystemMetrics(SM_CXSCREEN
);
3534 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3535 h
= GetSystemMetrics(SM_CYSCREEN
);
3536 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3538 ref
= IDirectDraw4_Release(ddraw2
);
3539 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3540 w
= GetSystemMetrics(SM_CXSCREEN
);
3541 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3542 h
= GetSystemMetrics(SM_CYSCREEN
);
3543 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3545 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3546 * restoring the display mode. */
3547 ddraw1
= create_ddraw();
3548 hr
= set_display_mode(ddraw1
, 800, 600);
3549 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3550 w
= GetSystemMetrics(SM_CXSCREEN
);
3551 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3552 h
= GetSystemMetrics(SM_CYSCREEN
);
3553 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3555 ddraw2
= create_ddraw();
3556 hr
= set_display_mode(ddraw2
, 640, 480);
3557 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3558 w
= GetSystemMetrics(SM_CXSCREEN
);
3559 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3560 h
= GetSystemMetrics(SM_CYSCREEN
);
3561 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3563 hr
= IDirectDraw4_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3564 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3566 ref
= IDirectDraw4_Release(ddraw1
);
3567 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3568 w
= GetSystemMetrics(SM_CXSCREEN
);
3569 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3570 h
= GetSystemMetrics(SM_CYSCREEN
);
3571 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3573 ref
= IDirectDraw4_Release(ddraw2
);
3574 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3575 w
= GetSystemMetrics(SM_CXSCREEN
);
3576 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3577 h
= GetSystemMetrics(SM_CYSCREEN
);
3578 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3580 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3581 ddraw1
= create_ddraw();
3582 hr
= set_display_mode(ddraw1
, 800, 600);
3583 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3584 w
= GetSystemMetrics(SM_CXSCREEN
);
3585 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3586 h
= GetSystemMetrics(SM_CYSCREEN
);
3587 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3589 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3590 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3592 ddraw2
= create_ddraw();
3593 hr
= set_display_mode(ddraw2
, 640, 480);
3594 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3596 ref
= IDirectDraw4_Release(ddraw1
);
3597 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3598 w
= GetSystemMetrics(SM_CXSCREEN
);
3599 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3600 h
= GetSystemMetrics(SM_CYSCREEN
);
3601 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3603 ref
= IDirectDraw4_Release(ddraw2
);
3604 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3605 w
= GetSystemMetrics(SM_CXSCREEN
);
3606 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3607 h
= GetSystemMetrics(SM_CYSCREEN
);
3608 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3610 DestroyWindow(window
);
3613 static void test_initialize(void)
3615 IDirectDraw4
*ddraw
;
3618 ddraw
= create_ddraw();
3619 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3621 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3622 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3623 IDirectDraw4_Release(ddraw
);
3626 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw4
, (void **)&ddraw
);
3627 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr
);
3628 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3629 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3630 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3631 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3632 IDirectDraw4_Release(ddraw
);
3636 static void test_coop_level_surf_create(void)
3638 IDirectDrawSurface4
*surface
;
3639 IDirectDraw4
*ddraw
;
3640 DDSURFACEDESC2 ddsd
;
3643 ddraw
= create_ddraw();
3644 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3646 memset(&ddsd
, 0, sizeof(ddsd
));
3647 ddsd
.dwSize
= sizeof(ddsd
);
3648 ddsd
.dwFlags
= DDSD_CAPS
;
3649 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3650 surface
= (void *)0xdeadbeef;
3651 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3652 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3653 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3655 surface
= (void *)0xdeadbeef;
3656 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3657 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3658 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3660 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3661 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3663 surface
= (void *)0xdeadbeef;
3664 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3665 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
3666 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3668 IDirectDraw4_Release(ddraw
);
3671 static void test_vb_discard(void)
3673 static const struct vec4 quad
[] =
3675 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
3676 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
3677 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
3678 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
3681 IDirect3DDevice3
*device
;
3683 IDirect3DVertexBuffer
*buffer
;
3686 D3DVERTEXBUFFERDESC desc
;
3688 static const unsigned int vbsize
= 16;
3691 window
= create_window();
3692 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3694 skip("Failed to create a 3D device, skipping test.\n");
3695 DestroyWindow(window
);
3699 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
3700 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
3702 memset(&desc
, 0, sizeof(desc
));
3703 desc
.dwSize
= sizeof(desc
);
3704 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
3705 desc
.dwFVF
= D3DFVF_XYZRHW
;
3706 desc
.dwNumVertices
= vbsize
;
3707 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
3708 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
3710 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3711 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3712 memcpy(data
, quad
, sizeof(quad
));
3713 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3714 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3716 hr
= IDirect3DDevice3_BeginScene(device
);
3717 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3718 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
3719 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3720 hr
= IDirect3DDevice3_EndScene(device
);
3721 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3723 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3724 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3725 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
3726 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3727 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3729 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3730 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3731 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
3733 if (data
[i
] != 0xaa)
3735 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
3739 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3740 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3742 IDirect3DVertexBuffer_Release(buffer
);
3743 IDirect3D3_Release(d3d
);
3744 IDirect3DDevice3_Release(device
);
3745 DestroyWindow(window
);
3748 static void test_coop_level_multi_window(void)
3750 HWND window1
, window2
;
3751 IDirectDraw4
*ddraw
;
3754 window1
= create_window();
3755 window2
= create_window();
3756 ddraw
= create_ddraw();
3757 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3759 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3760 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3761 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3762 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3763 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3764 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3766 IDirectDraw4_Release(ddraw
);
3767 DestroyWindow(window2
);
3768 DestroyWindow(window1
);
3771 static void test_draw_strided(void)
3773 static struct vec3 position
[] =
3780 static DWORD diffuse
[] =
3782 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3784 static WORD indices
[] =
3789 IDirectDrawSurface4
*rt
;
3790 IDirect3DDevice3
*device
;
3794 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
3795 IDirect3DViewport3
*viewport
;
3796 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3798 window
= create_window();
3799 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3801 skip("Failed to create a 3D device, skipping test.\n");
3802 DestroyWindow(window
);
3806 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
3807 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3808 viewport
= create_viewport(device
, 0, 0, 640, 480);
3809 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
3810 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
3811 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
3812 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
3814 hr
= IDirect3DDevice3_BeginScene(device
);
3815 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3817 memset(&strided
, 0x55, sizeof(strided
));
3818 strided
.position
.lpvData
= position
;
3819 strided
.position
.dwStride
= sizeof(*position
);
3820 strided
.diffuse
.lpvData
= diffuse
;
3821 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
3822 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
3823 &strided
, 4, indices
, 6, 0);
3824 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3826 hr
= IDirect3DDevice3_EndScene(device
);
3827 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3829 color
= get_surface_color(rt
, 320, 240);
3830 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
3832 IDirect3DViewport3_Release(viewport
);
3833 IDirectDrawSurface4_Release(rt
);
3834 IDirect3DDevice3_Release(device
);
3835 DestroyWindow(window
);
3838 static void test_lighting(void)
3840 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3841 static D3DMATRIX mat
=
3843 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3844 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3845 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3846 0.0f
, 0.0f
, 0.0f
, 1.0f
,
3850 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3851 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3852 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3853 0.0f
, 0.0f
, 0.5f
, 1.0f
,
3857 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3858 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3859 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
3860 10.f
, 10.0f
, 10.0f
, 1.0f
,
3864 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3865 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3866 0.0f
, 0.0f
, 1.0f
, -1.0f
,
3867 10.f
, 10.0f
, 10.0f
, 0.0f
,
3871 struct vec3 position
;
3876 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
3877 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
3878 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
3879 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
3883 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
3884 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
3885 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
3886 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
3890 struct vec3 position
;
3896 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3897 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3898 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3899 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3903 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3904 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3905 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3906 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3910 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3911 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3912 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3913 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3917 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3918 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3919 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3920 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3924 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3925 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3926 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3927 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3929 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
3932 D3DMATRIX
*world_matrix
;
3935 const char *message
;
3939 {&mat
, nquad
, 0x000000ff, "Lit quad with light"},
3940 {&mat_singular
, nquad
, 0x000000b4, "Lit quad with singular world matrix"},
3941 {&mat_transf
, rotatedquad
, 0x000000ff, "Lit quad with transformation matrix"},
3942 {&mat_nonaffine
, translatedquad
, 0x000000ff, "Lit quad with non-affine matrix"},
3947 IDirect3DDevice3
*device
;
3948 IDirectDrawSurface4
*rt
;
3949 IDirect3DViewport3
*viewport
;
3950 IDirect3DMaterial3
*material
;
3951 IDirect3DLight
*light
;
3952 D3DMATERIALHANDLE mat_handle
;
3953 D3DLIGHT2 light_desc
;
3955 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
3956 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
3961 window
= create_window();
3962 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3964 skip("Failed to create a 3D device, skipping test.\n");
3965 DestroyWindow(window
);
3969 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
3970 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
3972 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
3973 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3975 viewport
= create_viewport(device
, 0, 0, 640, 480);
3976 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
3977 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3979 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
3980 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3982 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
3983 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
3984 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
3985 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
3986 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
3987 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
3988 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
3989 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
3990 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
3991 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#x.\n", hr
);
3992 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
3993 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
3994 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
3995 ok(SUCCEEDED(hr
), "Failed to disable stencil buffer, hr %#x.\n", hr
);
3996 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
3997 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
3999 hr
= IDirect3DDevice3_BeginScene(device
);
4000 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4002 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
4003 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4004 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4005 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
4007 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4009 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4010 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
4011 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4013 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4015 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4016 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4017 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4019 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4021 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4022 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
4023 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4025 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4027 hr
= IDirect3DDevice3_EndScene(device
);
4028 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4030 color
= get_surface_color(rt
, 160, 360);
4031 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
4032 color
= get_surface_color(rt
, 160, 120);
4033 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
4034 color
= get_surface_color(rt
, 480, 360);
4035 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x.\n", color
);
4036 color
= get_surface_color(rt
, 480, 120);
4037 ok(color
== 0x00ffff00, "Lit quad with normals has color 0x%08x.\n", color
);
4039 material
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4040 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4041 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4042 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4043 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4045 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4046 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
4047 memset(&light_desc
, 0, sizeof(light_desc
));
4048 light_desc
.dwSize
= sizeof(light_desc
);
4049 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
4050 U1(light_desc
.dcvColor
).r
= 1.0f
;
4051 U2(light_desc
.dcvColor
).g
= 1.0f
;
4052 U3(light_desc
.dcvColor
).b
= 1.0f
;
4053 U4(light_desc
.dcvColor
).a
= 1.0f
;
4054 U3(light_desc
.dvDirection
).z
= 1.0f
;
4055 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4056 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4057 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4058 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
4060 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4061 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4063 hr
= IDirect3DDevice3_BeginScene(device
);
4064 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4066 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, nquad
,
4068 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4070 hr
= IDirect3DDevice3_EndScene(device
);
4071 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4073 color
= get_surface_color(rt
, 320, 240);
4074 ok(color
== 0x00000000, "Lit quad with no light has color 0x%08x.\n", color
);
4076 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
4077 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4078 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4080 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4082 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
4083 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
4085 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4086 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4088 hr
= IDirect3DDevice3_BeginScene(device
);
4089 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4091 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
4093 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4095 hr
= IDirect3DDevice3_EndScene(device
);
4096 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4098 color
= get_surface_color(rt
, 320, 240);
4099 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
4102 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4103 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
4104 IDirect3DLight_Release(light
);
4105 destroy_material(material
);
4106 IDirect3DViewport3_Release(viewport
);
4107 IDirectDrawSurface4_Release(rt
);
4108 refcount
= IDirect3DDevice3_Release(device
);
4109 ok(!refcount
, "Device has %u references left.\n", refcount
);
4110 IDirect3D3_Release(d3d
);
4111 DestroyWindow(window
);
4114 static void test_specular_lighting(void)
4116 static const unsigned int vertices_side
= 5;
4117 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
4118 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
4119 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4120 static D3DMATRIX mat
=
4122 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4123 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4124 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4125 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4127 static D3DLIGHT2 directional
=
4130 D3DLIGHT_DIRECTIONAL
,
4131 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4132 {{0.0f
}, {0.0f
}, {0.0f
}},
4133 {{0.0f
}, {0.0f
}, {1.0f
}},
4139 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4140 {{0.0f
}, {0.0f
}, {0.0f
}},
4141 {{0.0f
}, {0.0f
}, {0.0f
}},
4150 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4151 {{0.0f
}, {0.0f
}, {0.0f
}},
4152 {{0.0f
}, {0.0f
}, {1.0f
}},
4156 M_PI
/ 12.0f
, M_PI
/ 3.0f
4161 D3DLIGHT_PARALLELPOINT
,
4162 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4163 {{0.5f
}, {0.0f
}, {-1.0f
}},
4164 {{0.0f
}, {0.0f
}, {0.0f
}},
4170 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4171 {{-1.1f
}, {0.0f
}, {1.1f
}},
4172 {{0.0f
}, {0.0f
}, {0.0f
}},
4181 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4182 {{0.0f
}, {0.0f
}, {0.1f
}},
4183 {{0.0f
}, {0.0f
}, {0.0f
}},
4188 static const struct expected_color
4193 expected_directional
[] =
4195 {160, 120, 0x003c3c3c},
4196 {320, 120, 0x00717171},
4197 {480, 120, 0x003c3c3c},
4198 {160, 240, 0x00717171},
4199 {320, 240, 0x00ffffff},
4200 {480, 240, 0x00717171},
4201 {160, 360, 0x003c3c3c},
4202 {320, 360, 0x00717171},
4203 {480, 360, 0x003c3c3c},
4207 {160, 120, 0x00000000},
4208 {320, 120, 0x00090909},
4209 {480, 120, 0x00000000},
4210 {160, 240, 0x00090909},
4211 {320, 240, 0x00fafafa},
4212 {480, 240, 0x00090909},
4213 {160, 360, 0x00000000},
4214 {320, 360, 0x00090909},
4215 {480, 360, 0x00000000},
4219 {160, 120, 0x00000000},
4220 {320, 120, 0x00020202},
4221 {480, 120, 0x00000000},
4222 {160, 240, 0x00020202},
4223 {320, 240, 0x00fafafa},
4224 {480, 240, 0x00020202},
4225 {160, 360, 0x00000000},
4226 {320, 360, 0x00020202},
4227 {480, 360, 0x00000000},
4229 expected_parallelpoint
[] =
4231 {160, 120, 0x00050505},
4232 {320, 120, 0x002c2c2c},
4233 {480, 120, 0x006e6e6e},
4234 {160, 240, 0x00090909},
4235 {320, 240, 0x00717171},
4236 {480, 240, 0x00ffffff},
4237 {160, 360, 0x00050505},
4238 {320, 360, 0x002c2c2c},
4239 {480, 360, 0x006e6e6e},
4241 expected_point_side
[] =
4243 {160, 120, 0x00000000},
4244 {320, 120, 0x00000000},
4245 {480, 120, 0x00000000},
4246 {160, 240, 0x00000000},
4247 {320, 240, 0x00000000},
4248 {480, 240, 0x00000000},
4249 {160, 360, 0x00000000},
4250 {320, 360, 0x00000000},
4251 {480, 360, 0x00000000},
4253 expected_point_far
[] =
4255 {160, 120, 0x00000000},
4256 {320, 120, 0x00000000},
4257 {480, 120, 0x00000000},
4258 {160, 240, 0x00000000},
4259 {320, 240, 0x00ffffff},
4260 {480, 240, 0x00000000},
4261 {160, 360, 0x00000000},
4262 {320, 360, 0x00000000},
4263 {480, 360, 0x00000000},
4269 float specular_power
;
4270 const struct expected_color
*expected
;
4271 unsigned int expected_count
;
4275 /* D3DRENDERSTATE_LOCALVIEWER does not exist in D3D < 7 (the behavior is
4276 * the one you get on newer D3D versions with it set as TRUE). */
4277 {&directional
, FALSE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4278 {&directional
, TRUE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4279 {&point
, TRUE
, 30.0f
, expected_point
, ARRAY_SIZE(expected_point
)},
4280 {&spot
, TRUE
, 30.0f
, expected_spot
, ARRAY_SIZE(expected_spot
)},
4281 {¶llelpoint
, TRUE
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
4282 {&point_side
, TRUE
, 0.0f
, expected_point_side
, ARRAY_SIZE(expected_point_side
)},
4283 {&point_far
, TRUE
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
4286 IDirect3DDevice3
*device
;
4287 IDirectDrawSurface4
*rt
;
4288 IDirect3DViewport3
*viewport
;
4289 IDirect3DMaterial3
*material
;
4290 IDirect3DLight
*light
;
4291 D3DMATERIALHANDLE mat_handle
;
4296 unsigned int i
, j
, x
, y
;
4299 struct vec3 position
;
4304 window
= create_window();
4305 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4307 skip("Failed to create a 3D device, skipping test.\n");
4308 DestroyWindow(window
);
4312 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
4313 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
4314 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
4316 for (x
= 0; x
< vertices_side
; ++x
)
4318 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4319 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4320 quad
[i
].position
.z
= 1.0f
;
4321 quad
[i
].normal
.x
= 0.0f
;
4322 quad
[i
].normal
.y
= 0.0f
;
4323 quad
[i
++].normal
.z
= -1.0f
;
4326 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
4328 for (x
= 0; x
< (vertices_side
- 1); ++x
)
4330 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4331 indices
[i
++] = y
* vertices_side
+ x
;
4332 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4333 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4334 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4335 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
4339 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4340 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
4342 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4343 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4345 viewport
= create_viewport(device
, 0, 0, 640, 480);
4346 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4347 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4349 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4350 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
4351 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4352 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
4353 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4354 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
4355 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
4356 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
4357 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4358 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
4359 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4360 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
4362 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4363 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
4364 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4365 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
4367 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
4368 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
4370 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4372 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
4373 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
4374 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4376 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
4377 ok(SUCCEEDED(hr
), "Failed to set local viewer state, hr %#x.\n", hr
);
4379 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
4380 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4381 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
4382 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4383 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4385 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4386 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4388 hr
= IDirect3DDevice3_BeginScene(device
);
4389 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4391 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
4392 vertices_side
* vertices_side
, indices
, indices_count
, 0);
4393 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4395 hr
= IDirect3DDevice3_EndScene(device
);
4396 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4398 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
4400 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
4401 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
4402 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
4403 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
4404 tests
[i
].expected
[j
].y
, color
, i
);
4407 destroy_material(material
);
4410 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4411 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
4412 IDirect3DLight_Release(light
);
4413 IDirect3DViewport3_Release(viewport
);
4414 IDirectDrawSurface4_Release(rt
);
4415 refcount
= IDirect3DDevice3_Release(device
);
4416 ok(!refcount
, "Device has %u references left.\n", refcount
);
4417 IDirect3D3_Release(d3d
);
4418 DestroyWindow(window
);
4419 HeapFree(GetProcessHeap(), 0, indices
);
4420 HeapFree(GetProcessHeap(), 0, quad
);
4423 static void test_clear_rect_count(void)
4425 IDirectDrawSurface4
*rt
;
4426 IDirect3DDevice3
*device
;
4430 IDirect3DViewport3
*viewport
;
4431 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4433 window
= create_window();
4434 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4436 skip("Failed to create a 3D device, skipping test.\n");
4437 DestroyWindow(window
);
4441 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4442 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4444 viewport
= create_viewport(device
, 0, 0, 640, 480);
4445 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4446 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
4447 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00ffffff, 0.0f
, 0);
4448 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4449 hr
= IDirect3DViewport3_Clear2(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
, 0x00ff0000, 0.0f
, 0);
4450 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4451 hr
= IDirect3DViewport3_Clear2(viewport
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
4452 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4453 hr
= IDirect3DViewport3_Clear2(viewport
, 1, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
4454 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4456 color
= get_surface_color(rt
, 320, 240);
4457 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4458 "Got unexpected color 0x%08x.\n", color
);
4460 IDirect3DViewport3_Release(viewport
);
4461 IDirectDrawSurface4_Release(rt
);
4462 IDirect3DDevice3_Release(device
);
4463 DestroyWindow(window
);
4466 static BOOL
test_mode_restored(IDirectDraw4
*ddraw
, HWND window
)
4468 DDSURFACEDESC2 ddsd1
, ddsd2
;
4471 memset(&ddsd1
, 0, sizeof(ddsd1
));
4472 ddsd1
.dwSize
= sizeof(ddsd1
);
4473 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd1
);
4474 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4476 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4477 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4478 hr
= set_display_mode(ddraw
, 640, 480);
4479 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4480 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4481 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4483 memset(&ddsd2
, 0, sizeof(ddsd2
));
4484 ddsd2
.dwSize
= sizeof(ddsd2
);
4485 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd2
);
4486 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4487 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
4488 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
4490 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4493 static void test_coop_level_versions(void)
4499 IDirectDrawSurface
*surface
;
4500 IDirectDraw4
*ddraw4
;
4503 window
= create_window();
4504 ddraw4
= create_ddraw();
4505 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4506 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4507 restored
= test_mode_restored(ddraw4
, window
);
4508 ok(restored
, "Display mode not restored in new ddraw object\n");
4510 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4511 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4512 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4514 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4515 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4516 restored
= test_mode_restored(ddraw4
, window
);
4517 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4519 /* A successful one does */
4520 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4521 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4522 restored
= test_mode_restored(ddraw4
, window
);
4523 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4525 IDirectDraw_Release(ddraw
);
4526 IDirectDraw4_Release(ddraw4
);
4528 ddraw4
= create_ddraw();
4529 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4530 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4531 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4533 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4534 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4535 restored
= test_mode_restored(ddraw4
, window
);
4536 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4538 IDirectDraw_Release(ddraw
);
4539 IDirectDraw4_Release(ddraw4
);
4541 /* A failing call does not restore the ddraw2+ behavior */
4542 ddraw4
= create_ddraw();
4543 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4544 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4545 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4547 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4548 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4549 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4550 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4551 restored
= test_mode_restored(ddraw4
, window
);
4552 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4554 IDirectDraw_Release(ddraw
);
4555 IDirectDraw4_Release(ddraw4
);
4557 /* Neither does a sequence of successful calls with the new interface */
4558 ddraw4
= create_ddraw();
4559 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4560 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4561 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4563 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4564 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4565 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4566 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4567 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4568 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4570 restored
= test_mode_restored(ddraw4
, window
);
4571 ok(!restored
, "Display mode restored after ddraw1-ddraw4 SetCooperativeLevel() call sequence\n");
4572 IDirectDraw_Release(ddraw
);
4573 IDirectDraw4_Release(ddraw4
);
4575 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4576 ddraw4
= create_ddraw();
4577 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4578 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4579 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4581 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4582 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4584 memset(&ddsd
, 0, sizeof(ddsd
));
4585 ddsd
.dwSize
= sizeof(ddsd
);
4586 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4587 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4588 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4589 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4590 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
4591 IDirectDrawSurface_Release(surface
);
4592 restored
= test_mode_restored(ddraw4
, window
);
4593 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4595 IDirectDraw_Release(ddraw
);
4596 IDirectDraw4_Release(ddraw4
);
4597 DestroyWindow(window
);
4600 static void test_lighting_interface_versions(void)
4602 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4603 IDirect3DMaterial3
*emissive
;
4604 IDirect3DViewport3
*viewport
;
4605 IDirect3DDevice3
*device
;
4606 IDirectDrawSurface4
*rt
;
4610 D3DMATERIALHANDLE mat_handle
;
4614 static D3DVERTEX quad
[] =
4616 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4617 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4618 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4619 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4622 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
4625 struct vec3 position
;
4627 DWORD diffuse
, specular
;
4631 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4632 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4633 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4634 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4637 static D3DLVERTEX lquad
[] =
4639 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4640 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4641 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4642 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4645 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
4648 struct vec3 position
;
4649 DWORD diffuse
, specular
;
4650 struct vec2 texcoord
;
4654 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4655 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4656 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4657 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4660 static D3DTLVERTEX tlquad
[] =
4662 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4663 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4664 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4665 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4672 DWORD d3drs_lighting
, d3drs_specular
;
4678 /* Lighting is enabled when all of these conditions are met:
4679 * 1) No pretransformed position(D3DFVF_XYZRHW)
4680 * 2) Normals are available (D3DFVF_NORMAL)
4681 * 3) D3DDP_DONOTLIGHT is not set.
4683 * D3DRENDERSTATE_LIGHTING is ignored, it is not defined
4684 * in this d3d version */
4687 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
4688 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
4689 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4690 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4691 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
4692 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
4693 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4694 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4697 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x0000ff00},
4698 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
4699 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4700 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4701 /* The specular color in the vertex is ignored because
4702 * D3DRENDERSTATE_COLORVERTEX is not enabled */
4703 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x0000ff00},
4704 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
4705 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4706 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4709 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
4710 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
4711 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4712 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4713 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
4714 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
4715 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4716 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4719 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
4720 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x00ff0000},
4721 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4722 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4723 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
4724 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x00ff8080},
4725 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4726 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4729 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
4730 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
4731 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4732 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4733 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
4734 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
4735 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4736 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4739 window
= create_window();
4740 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4742 skip("Failed to create a 3D device, skipping test.\n");
4743 DestroyWindow(window
);
4747 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4748 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4750 viewport
= create_viewport(device
, 0, 0, 640, 480);
4751 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4752 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4754 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4755 hr
= IDirect3DMaterial3_GetHandle(emissive
, device
, &mat_handle
);
4756 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
4757 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4758 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4759 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
4760 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
4762 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
4763 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
4764 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected FALSE.\n", rs
);
4766 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4768 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
4769 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4771 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
4772 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
4773 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4774 tests
[i
].d3drs_specular
);
4775 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
4777 hr
= IDirect3DDevice3_BeginScene(device
);
4778 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4779 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4780 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4781 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4782 hr
= IDirect3DDevice3_EndScene(device
);
4783 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4785 color
= get_surface_color(rt
, 320, 240);
4786 ok(compare_color(color
, tests
[i
].color
, 1),
4787 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4788 color
, tests
[i
].color
, i
);
4791 destroy_material(emissive
);
4792 IDirectDrawSurface4_Release(rt
);
4793 ref
= IDirect3DDevice3_Release(device
);
4794 ok(ref
== 0, "Device not properly released, refcount %u.\n", ref
);
4795 DestroyWindow(window
);
4801 IDirectDraw4
*ddraw
;
4804 } activateapp_testdata
;
4806 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4808 if (message
== WM_ACTIVATEAPP
)
4810 if (activateapp_testdata
.ddraw
)
4813 activateapp_testdata
.received
= FALSE
;
4814 hr
= IDirectDraw4_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4815 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4816 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
4817 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4819 activateapp_testdata
.received
= TRUE
;
4822 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4825 static void test_coop_level_activateapp(void)
4827 IDirectDraw4
*ddraw
;
4831 DDSURFACEDESC2 ddsd
;
4832 IDirectDrawSurface4
*surface
;
4834 ddraw
= create_ddraw();
4835 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4837 wc
.lpfnWndProc
= activateapp_test_proc
;
4838 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4839 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4841 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4842 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4844 /* Exclusive with window already active. */
4845 SetForegroundWindow(window
);
4846 activateapp_testdata
.received
= FALSE
;
4847 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4848 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4849 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4850 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4851 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4853 /* Exclusive with window not active. */
4854 SetForegroundWindow(GetDesktopWindow());
4855 activateapp_testdata
.received
= FALSE
;
4856 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4857 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4858 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4859 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4860 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4862 /* Normal with window not active, then exclusive with the same window. */
4863 SetForegroundWindow(GetDesktopWindow());
4864 activateapp_testdata
.received
= FALSE
;
4865 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4866 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4867 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4868 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4869 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4870 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4871 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4872 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4874 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4875 SetForegroundWindow(GetDesktopWindow());
4876 activateapp_testdata
.received
= FALSE
;
4877 activateapp_testdata
.ddraw
= ddraw
;
4878 activateapp_testdata
.window
= window
;
4879 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4880 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4881 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4882 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4883 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4884 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4886 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4887 * succeeding. Another switch to exclusive and back to normal is needed to release the
4888 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4889 * WM_ACTIVATEAPP messages. */
4890 activateapp_testdata
.ddraw
= NULL
;
4891 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4892 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4893 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4894 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4896 /* Setting DDSCL_NORMAL with recursive invocation. */
4897 SetForegroundWindow(GetDesktopWindow());
4898 activateapp_testdata
.received
= FALSE
;
4899 activateapp_testdata
.ddraw
= ddraw
;
4900 activateapp_testdata
.window
= window
;
4901 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4902 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4903 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4904 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4906 /* DDraw is in exclusive mode now. */
4907 memset(&ddsd
, 0, sizeof(ddsd
));
4908 ddsd
.dwSize
= sizeof(ddsd
);
4909 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4910 U5(ddsd
).dwBackBufferCount
= 1;
4911 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4912 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4913 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4914 IDirectDrawSurface4_Release(surface
);
4916 /* Recover again, just to be sure. */
4917 activateapp_testdata
.ddraw
= NULL
;
4918 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4919 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4920 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4921 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4923 DestroyWindow(window
);
4924 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4925 IDirectDraw4_Release(ddraw
);
4928 static void test_texturemanage(void)
4930 IDirectDraw4
*ddraw
;
4932 DDSURFACEDESC2 ddsd
;
4933 IDirectDrawSurface4
*surface
;
4935 DDCAPS hal_caps
, hel_caps
;
4936 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
4939 DWORD caps_in
, caps2_in
;
4941 DWORD caps_out
, caps2_out
;
4945 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4947 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4949 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4951 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4953 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
4954 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
4955 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
4956 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
4957 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
4958 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
4959 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
4960 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
4962 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4964 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4966 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4968 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4970 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4972 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4974 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
4975 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
4976 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
4977 DDSCAPS_SYSTEMMEMORY
, 0},
4980 ddraw
= create_ddraw();
4981 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4982 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4983 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4985 memset(&hal_caps
, 0, sizeof(hal_caps
));
4986 hal_caps
.dwSize
= sizeof(hal_caps
);
4987 memset(&hel_caps
, 0, sizeof(hel_caps
));
4988 hel_caps
.dwSize
= sizeof(hel_caps
);
4989 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
4990 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
4991 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
4993 skip("Managed textures not supported, skipping managed texture test.\n");
4994 IDirectDraw4_Release(ddraw
);
4998 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5000 memset(&ddsd
, 0, sizeof(ddsd
));
5001 ddsd
.dwSize
= sizeof(ddsd
);
5002 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5003 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
5004 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
5008 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5009 ok(hr
== tests
[i
].hr
, "Got unexpected, hr %#x, case %u.\n", hr
, i
);
5013 memset(&ddsd
, 0, sizeof(ddsd
));
5014 ddsd
.dwSize
= sizeof(ddsd
);
5015 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5016 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5018 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
5019 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5020 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
5021 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
5022 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5023 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
5025 IDirectDrawSurface4_Release(surface
);
5028 IDirectDraw4_Release(ddraw
);
5031 #define SUPPORT_DXT1 0x01
5032 #define SUPPORT_DXT2 0x02
5033 #define SUPPORT_DXT3 0x04
5034 #define SUPPORT_DXT4 0x08
5035 #define SUPPORT_DXT5 0x10
5036 #define SUPPORT_YUY2 0x20
5037 #define SUPPORT_UYVY 0x40
5039 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5041 DWORD
*supported_fmts
= ctx
;
5043 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
5044 return DDENUMRET_OK
;
5046 switch (fmt
->dwFourCC
)
5048 case MAKEFOURCC('D','X','T','1'):
5049 *supported_fmts
|= SUPPORT_DXT1
;
5051 case MAKEFOURCC('D','X','T','2'):
5052 *supported_fmts
|= SUPPORT_DXT2
;
5054 case MAKEFOURCC('D','X','T','3'):
5055 *supported_fmts
|= SUPPORT_DXT3
;
5057 case MAKEFOURCC('D','X','T','4'):
5058 *supported_fmts
|= SUPPORT_DXT4
;
5060 case MAKEFOURCC('D','X','T','5'):
5061 *supported_fmts
|= SUPPORT_DXT5
;
5063 case MAKEFOURCC('Y','U','Y','2'):
5064 *supported_fmts
|= SUPPORT_YUY2
;
5066 case MAKEFOURCC('U','Y','V','Y'):
5067 *supported_fmts
|= SUPPORT_UYVY
;
5073 return DDENUMRET_OK
;
5076 static void test_block_formats_creation(void)
5078 HRESULT hr
, expect_hr
;
5079 unsigned int i
, j
, w
, h
;
5081 IDirectDraw4
*ddraw
;
5083 IDirect3DDevice3
*device
;
5084 IDirectDrawSurface4
*surface
;
5085 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
5086 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
5087 DDSURFACEDESC2 ddsd
;
5096 unsigned int block_width
;
5097 unsigned int block_height
;
5098 unsigned int block_size
;
5099 BOOL create_size_checked
, overlay
;
5103 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
5104 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
5105 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
5106 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
5107 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
5108 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
5109 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
5119 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
5120 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
5122 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
5123 * Other hw / drivers successfully create those surfaces. Ignore them, this
5124 * suggests that no game uses this, otherwise Nvidia would support it. */
5126 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
5127 "videomemory texture", FALSE
5130 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
5131 "videomemory overlay", TRUE
5134 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
5135 "systemmemory texture", FALSE
5138 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
5139 "managed texture", FALSE
5151 enum size_type size_type
;
5157 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5158 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5159 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5160 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5161 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5162 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5163 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
5164 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5165 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
5166 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
5167 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5168 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5169 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5170 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5173 window
= create_window();
5174 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5176 skip("Failed to create a 3D device, skipping test.\n");
5177 DestroyWindow(window
);
5181 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5182 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5183 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5184 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5185 IDirect3D3_Release(d3d
);
5187 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
,
5189 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5191 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
5192 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5193 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
5194 num_fourcc_codes
* sizeof(*fourcc_codes
));
5197 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
5198 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5199 for (i
= 0; i
< num_fourcc_codes
; i
++)
5201 for (j
= 0; j
< ARRAY_SIZE(formats
); j
++)
5203 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
5204 supported_overlay_fmts
|= formats
[j
].support_flag
;
5207 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
5209 memset(&hal_caps
, 0, sizeof(hal_caps
));
5210 hal_caps
.dwSize
= sizeof(hal_caps
);
5211 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
5212 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5214 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
5216 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5218 for (j
= 0; j
< ARRAY_SIZE(types
); j
++)
5222 if (formats
[i
].overlay
!= types
[j
].overlay
5223 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
5226 if (formats
[i
].overlay
)
5227 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
5229 support
= supported_fmts
& formats
[i
].support_flag
;
5231 for (w
= 1; w
<= 8; w
++)
5233 for (h
= 1; h
<= 8; h
++)
5235 BOOL block_aligned
= TRUE
;
5238 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
5239 block_aligned
= FALSE
;
5241 memset(&ddsd
, 0, sizeof(ddsd
));
5242 ddsd
.dwSize
= sizeof(ddsd
);
5243 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5244 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
5245 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
5246 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5247 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5248 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5252 /* TODO: Handle power of two limitations. I cannot test the pow2
5253 * behavior on windows because I have no hardware that doesn't at
5254 * least support np2_conditional. There's probably no HW that
5255 * supports DXTN textures but no conditional np2 textures. */
5256 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
5257 expect_hr
= DDERR_INVALIDPARAMS
;
5258 else if (formats
[i
].create_size_checked
&& !block_aligned
)
5260 expect_hr
= DDERR_INVALIDPARAMS
;
5261 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
5267 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5270 "Got unexpected hr %#x for format %s, resource type %s, size %ux%u, expected %#x.\n",
5271 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
5274 IDirectDrawSurface4_Release(surface
);
5279 if (formats
[i
].overlay
)
5282 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
5284 memset(&ddsd
, 0, sizeof(ddsd
));
5285 ddsd
.dwSize
= sizeof(ddsd
);
5286 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
5287 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
5289 switch (user_mem_tests
[j
].size_type
)
5291 case SIZE_TYPE_ZERO
:
5292 U1(ddsd
).dwLinearSize
= 0;
5295 case SIZE_TYPE_PITCH
:
5296 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
5299 case SIZE_TYPE_SIZE
:
5300 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
5303 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
5305 ddsd
.lpSurface
= mem
;
5306 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5307 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5308 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5312 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5313 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#x, format %s.\n", j
, hr
, formats
[i
].name
);
5318 memset(&ddsd
, 0, sizeof(ddsd
));
5319 ddsd
.dwSize
= sizeof(ddsd
);
5320 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5321 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", j
, hr
);
5322 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
5323 "Test %u: Got unexpected flags %#x.\n", j
, ddsd
.dwFlags
);
5324 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
5325 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#x.\n",
5326 j
, U1(ddsd
).dwLinearSize
);
5328 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
5329 "Test %u: Got unexpected linear size %#x, expected %#x.\n",
5330 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
5331 IDirectDrawSurface4_Release(surface
);
5335 HeapFree(GetProcessHeap(), 0, mem
);
5337 IDirectDraw4_Release(ddraw
);
5338 IDirect3DDevice3_Release(device
);
5339 DestroyWindow(window
);
5342 struct format_support_check
5344 const DDPIXELFORMAT
*format
;
5348 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5350 struct format_support_check
*format
= ctx
;
5352 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
5354 format
->supported
= TRUE
;
5355 return DDENUMRET_CANCEL
;
5358 return DDENUMRET_OK
;
5361 static void test_unsupported_formats(void)
5364 BOOL expect_success
;
5366 IDirectDraw4
*ddraw
;
5368 IDirect3DDevice3
*device
;
5369 IDirectDrawSurface4
*surface
;
5370 DDSURFACEDESC2 ddsd
;
5372 DWORD expected_caps
;
5383 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
5384 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
5390 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5391 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
5395 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
5397 window
= create_window();
5398 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5400 skip("Failed to create a 3D device, skipping test.\n");
5401 DestroyWindow(window
);
5405 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5406 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5407 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5408 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5409 IDirect3D3_Release(d3d
);
5411 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5413 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
5414 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
5415 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5417 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
5419 memset(&ddsd
, 0, sizeof(ddsd
));
5420 ddsd
.dwSize
= sizeof(ddsd
);
5421 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5422 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
5425 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
5427 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
5428 expect_success
= FALSE
;
5430 expect_success
= TRUE
;
5432 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5433 ok(SUCCEEDED(hr
) == expect_success
,
5434 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
5435 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
5439 memset(&ddsd
, 0, sizeof(ddsd
));
5440 ddsd
.dwSize
= sizeof(ddsd
);
5441 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5442 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5444 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
5445 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5446 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
5447 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5448 else if (check
.supported
)
5449 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5451 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5453 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
5454 "Expected capability %#x, format %s, input cap %#x.\n",
5455 expected_caps
, formats
[i
].name
, caps
[j
]);
5457 IDirectDrawSurface4_Release(surface
);
5461 IDirectDraw4_Release(ddraw
);
5462 IDirect3DDevice3_Release(device
);
5463 DestroyWindow(window
);
5466 static void test_rt_caps(void)
5468 PALETTEENTRY palette_entries
[256];
5469 IDirectDrawPalette
*palette
;
5470 IDirectDraw4
*ddraw
;
5471 DDPIXELFORMAT z_fmt
;
5478 static const DDPIXELFORMAT p8_fmt
=
5480 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5481 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
5486 const DDPIXELFORMAT
*pf
;
5489 HRESULT create_device_hr
;
5490 HRESULT set_rt_hr
, alternative_set_rt_hr
;
5496 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5497 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5504 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5505 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5512 DDSCAPS_OFFSCREENPLAIN
,
5513 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5520 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5521 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5522 D3DERR_SURFACENOTINVIDMEM
,
5528 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5529 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5536 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5537 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5545 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5553 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5560 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5561 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5562 D3DERR_SURFACENOTINVIDMEM
,
5568 DDSCAPS_SYSTEMMEMORY
,
5569 DDSCAPS_SYSTEMMEMORY
,
5577 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5584 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5586 DDERR_NOPALETTEATTACHED
,
5592 DDSCAPS_OFFSCREENPLAIN
,
5593 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5600 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5601 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5602 DDERR_NOPALETTEATTACHED
,
5608 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5609 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5616 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
5617 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5619 DDERR_INVALIDPIXELFORMAT
,
5624 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5625 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5627 DDERR_INVALIDPIXELFORMAT
,
5633 DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5640 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5641 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5643 DDERR_INVALIDPIXELFORMAT
,
5648 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5649 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5656 window
= create_window();
5657 ddraw
= create_ddraw();
5658 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5659 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5660 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5662 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
5664 skip("D3D interface is not available, skipping test.\n");
5668 memset(&z_fmt
, 0, sizeof(z_fmt
));
5669 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
5670 if (FAILED(hr
) || !z_fmt
.dwSize
)
5672 skip("No depth buffer formats available, skipping test.\n");
5673 IDirect3D3_Release(d3d
);
5677 memset(palette_entries
, 0, sizeof(palette_entries
));
5678 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
5679 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5681 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5683 IDirectDrawSurface4
*surface
, *rt
, *expected_rt
, *tmp
;
5684 DDSURFACEDESC2 surface_desc
;
5685 IDirect3DDevice3
*device
;
5687 memset(&surface_desc
, 0, sizeof(surface_desc
));
5688 surface_desc
.dwSize
= sizeof(surface_desc
);
5689 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5690 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5691 if (test_data
[i
].pf
)
5693 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5694 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
5696 surface_desc
.dwWidth
= 640;
5697 surface_desc
.dwHeight
= 480;
5698 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5699 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
5700 i
, test_data
[i
].caps_in
, hr
);
5702 memset(&surface_desc
, 0, sizeof(surface_desc
));
5703 surface_desc
.dwSize
= sizeof(surface_desc
);
5704 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
5705 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5706 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
5707 "Test %u: Got unexpected caps %#x, expected %#x.\n",
5708 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5710 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5711 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
5712 i
, hr
, test_data
[i
].create_device_hr
);
5715 if (hr
== DDERR_NOPALETTEATTACHED
)
5717 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
5718 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
5719 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5720 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
5721 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5723 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5725 IDirectDrawSurface4_Release(surface
);
5727 memset(&surface_desc
, 0, sizeof(surface_desc
));
5728 surface_desc
.dwSize
= sizeof(surface_desc
);
5729 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5730 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5731 surface_desc
.dwWidth
= 640;
5732 surface_desc
.dwHeight
= 480;
5733 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5734 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
5736 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5737 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
5740 memset(&surface_desc
, 0, sizeof(surface_desc
));
5741 surface_desc
.dwSize
= sizeof(surface_desc
);
5742 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5743 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5744 if (test_data
[i
].pf
)
5746 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5747 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
5749 surface_desc
.dwWidth
= 640;
5750 surface_desc
.dwHeight
= 480;
5751 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
5752 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
5753 i
, test_data
[i
].caps_in
, hr
);
5755 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
5756 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
5757 "Test %u: Got unexpected hr %#x, expected %#x.\n",
5758 i
, hr
, test_data
[i
].set_rt_hr
);
5759 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
5762 expected_rt
= surface
;
5764 hr
= IDirect3DDevice3_GetRenderTarget(device
, &tmp
);
5765 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
5766 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
5768 IDirectDrawSurface4_Release(tmp
);
5769 IDirectDrawSurface4_Release(rt
);
5770 refcount
= IDirect3DDevice3_Release(device
);
5771 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
5772 refcount
= IDirectDrawSurface4_Release(surface
);
5773 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
5776 IDirectDrawPalette_Release(palette
);
5777 IDirect3D3_Release(d3d
);
5780 refcount
= IDirectDraw4_Release(ddraw
);
5781 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5782 DestroyWindow(window
);
5785 static void test_primary_caps(void)
5787 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5788 IDirectDrawSurface4
*surface
;
5789 DDSURFACEDESC2 surface_desc
;
5790 IDirectDraw4
*ddraw
;
5800 DWORD back_buffer_count
;
5808 DDSCAPS_PRIMARYSURFACE
,
5811 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
5815 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
5822 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
5829 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
5836 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
5843 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
5850 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5857 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5864 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5866 DDERR_NOEXCLUSIVEMODE
,
5870 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5871 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5877 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5878 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5881 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
5884 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5885 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
5891 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5892 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
5899 window
= create_window();
5900 ddraw
= create_ddraw();
5901 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5903 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5905 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
5906 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5908 memset(&surface_desc
, 0, sizeof(surface_desc
));
5909 surface_desc
.dwSize
= sizeof(surface_desc
);
5910 surface_desc
.dwFlags
= DDSD_CAPS
;
5911 if (test_data
[i
].back_buffer_count
!= ~0u)
5912 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5913 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5914 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5915 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5916 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
5920 memset(&surface_desc
, 0, sizeof(surface_desc
));
5921 surface_desc
.dwSize
= sizeof(surface_desc
);
5922 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
5923 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5924 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5925 "Test %u: Got unexpected caps %#x, expected %#x.\n",
5926 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5928 IDirectDrawSurface4_Release(surface
);
5931 refcount
= IDirectDraw4_Release(ddraw
);
5932 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5933 DestroyWindow(window
);
5936 static void test_surface_lock(void)
5938 IDirectDraw4
*ddraw
;
5939 IDirect3D3
*d3d
= NULL
;
5940 IDirectDrawSurface4
*surface
;
5944 DDSURFACEDESC2 ddsd
;
5946 DDPIXELFORMAT z_fmt
;
5956 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5958 "videomemory offscreenplain"
5961 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5963 "systemmemory offscreenplain"
5966 DDSCAPS_PRIMARYSURFACE
,
5971 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5973 "videomemory texture"
5976 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5978 "opaque videomemory texture"
5981 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5983 "systemmemory texture"
5987 DDSCAPS2_TEXTUREMANAGE
,
5992 DDSCAPS2_D3DTEXTUREMANAGE
,
5997 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
5998 "opaque managed texture"
6002 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6003 "opaque managed texture"
6006 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6017 window
= create_window();
6018 ddraw
= create_ddraw();
6019 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6020 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6021 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6023 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
6025 skip("D3D interface is not available, skipping test.\n");
6029 memset(&z_fmt
, 0, sizeof(z_fmt
));
6030 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
6031 if (FAILED(hr
) || !z_fmt
.dwSize
)
6033 skip("No depth buffer formats available, skipping test.\n");
6037 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6039 memset(&ddsd
, 0, sizeof(ddsd
));
6040 ddsd
.dwSize
= sizeof(ddsd
);
6041 ddsd
.dwFlags
= DDSD_CAPS
;
6042 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6044 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6048 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
6050 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
6051 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
6053 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6054 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6056 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6057 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6059 memset(&ddsd
, 0, sizeof(ddsd
));
6060 ddsd
.dwSize
= sizeof(ddsd
);
6061 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6062 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6065 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6066 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6069 memset(&ddsd
, 0, sizeof(ddsd
));
6070 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6071 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
6073 IDirectDrawSurface4_Release(surface
);
6078 IDirect3D3_Release(d3d
);
6079 refcount
= IDirectDraw4_Release(ddraw
);
6080 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6081 DestroyWindow(window
);
6084 static void test_surface_discard(void)
6086 IDirect3DDevice3
*device
;
6088 IDirectDraw4
*ddraw
;
6091 DDSURFACEDESC2 ddsd
;
6092 IDirectDrawSurface4
*surface
, *target
;
6101 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6102 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6103 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6104 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6105 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
6106 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6107 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
6108 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6112 window
= create_window();
6113 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6115 skip("Failed to create a 3D device, skipping test.\n");
6116 DestroyWindow(window
);
6119 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
6120 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6121 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
6122 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6123 hr
= IDirect3DDevice3_GetRenderTarget(device
, &target
);
6124 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6126 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6130 memset(&ddsd
, 0, sizeof(ddsd
));
6131 ddsd
.dwSize
= sizeof(ddsd
);
6132 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6133 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6134 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6137 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6138 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#x, case %u.\n", hr
, i
);
6140 memset(&ddsd
, 0, sizeof(ddsd
));
6141 ddsd
.dwSize
= sizeof(ddsd
);
6142 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6143 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6144 addr
= ddsd
.lpSurface
;
6145 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6146 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6148 memset(&ddsd
, 0, sizeof(ddsd
));
6149 ddsd
.dwSize
= sizeof(ddsd
);
6150 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6151 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6152 discarded
= ddsd
.lpSurface
!= addr
;
6153 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6154 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6156 hr
= IDirectDrawSurface4_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
6157 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
6159 memset(&ddsd
, 0, sizeof(ddsd
));
6160 ddsd
.dwSize
= sizeof(ddsd
);
6161 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6162 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6163 discarded
|= ddsd
.lpSurface
!= addr
;
6164 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6165 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6167 IDirectDrawSurface4_Release(surface
);
6169 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
6170 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
6171 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
6174 IDirectDrawSurface4_Release(target
);
6175 IDirectDraw4_Release(ddraw
);
6176 IDirect3D3_Release(d3d
);
6177 IDirect3DDevice3_Release(device
);
6178 DestroyWindow(window
);
6181 static void fill_surface(IDirectDrawSurface4
*surface
, D3DCOLOR color
)
6183 DDSURFACEDESC2 surface_desc
= {sizeof(surface_desc
)};
6188 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6189 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6191 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
6193 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* surface_desc
.lPitch
);
6194 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
6200 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6201 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6204 static void test_flip(void)
6206 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6207 IDirectDrawSurface4
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
6208 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
6209 DDSURFACEDESC2 surface_desc
;
6210 BOOL sysmem_primary
;
6211 IDirectDraw4
*ddraw
;
6212 DWORD expected_caps
;
6226 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
6227 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
6228 {"TEXTURE", DDSCAPS_TEXTURE
},
6231 window
= create_window();
6232 ddraw
= create_ddraw();
6233 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6235 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6236 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6238 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6240 /* Creating a flippable texture induces a BSoD on some versions of the
6241 * Intel graphics driver. At least Intel GMA 950 with driver version
6242 * 6.14.10.4926 on Windows XP SP3 is affected. */
6243 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
6245 win_skip("Skipping flippable texture test.\n");
6249 memset(&surface_desc
, 0, sizeof(surface_desc
));
6250 surface_desc
.dwSize
= sizeof(surface_desc
);
6251 surface_desc
.dwFlags
= DDSD_CAPS
;
6252 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6253 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6254 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6255 surface_desc
.dwWidth
= 512;
6256 surface_desc
.dwHeight
= 512;
6257 U5(surface_desc
).dwBackBufferCount
= 3;
6258 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6259 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6261 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
6262 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6263 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6264 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6266 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
6267 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
6268 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6269 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6271 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
6272 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6273 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
6274 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6278 memset(&surface_desc
, 0, sizeof(surface_desc
));
6279 surface_desc
.dwSize
= sizeof(surface_desc
);
6280 hr
= IDirectDrawSurface4_GetSurfaceDesc(frontbuffer
, &surface_desc
);
6281 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6282 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6283 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6284 expected_caps
|= DDSCAPS_VISIBLE
;
6285 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6286 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6287 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
6289 hr
= IDirectDrawSurface4_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
6290 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6291 memset(&surface_desc
, 0, sizeof(surface_desc
));
6292 surface_desc
.dwSize
= sizeof(surface_desc
);
6293 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer1
, &surface_desc
);
6294 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6295 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6296 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6297 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
6298 expected_caps
|= DDSCAPS_BACKBUFFER
;
6299 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6300 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6302 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
6303 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6304 memset(&surface_desc
, 0, sizeof(surface_desc
));
6305 surface_desc
.dwSize
= sizeof(surface_desc
);
6306 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer2
, &surface_desc
);
6307 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6308 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6309 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6310 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
6311 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6312 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6314 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
6315 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6316 memset(&surface_desc
, 0, sizeof(surface_desc
));
6317 surface_desc
.dwSize
= sizeof(surface_desc
);
6318 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer3
, &surface_desc
);
6319 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6320 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6321 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6322 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6323 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6325 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
6326 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6327 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
6328 test_data
[i
].name
, surface
, frontbuffer
);
6329 IDirectDrawSurface4_Release(surface
);
6331 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
6332 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6333 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6334 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6335 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6336 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6337 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6339 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6340 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6341 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6342 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6343 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6344 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
6345 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
6347 memset(&surface_desc
, 0, sizeof(surface_desc
));
6348 surface_desc
.dwSize
= sizeof(surface_desc
);
6349 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6350 surface_desc
.ddsCaps
.dwCaps
= 0;
6351 surface_desc
.dwWidth
= 640;
6352 surface_desc
.dwHeight
= 480;
6353 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6354 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6355 hr
= IDirectDrawSurface4_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
6356 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6357 IDirectDrawSurface4_Release(surface
);
6359 hr
= IDirectDrawSurface4_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
6360 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6361 hr
= IDirectDrawSurface4_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
6362 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6363 hr
= IDirectDrawSurface4_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
6364 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6365 hr
= IDirectDrawSurface4_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
6366 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6368 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
6369 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
6370 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
6371 fill_surface(backbuffer1
, 0xffff0000);
6372 fill_surface(backbuffer2
, 0xff00ff00);
6373 fill_surface(backbuffer3
, 0xff0000ff);
6375 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6376 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6377 color
= get_surface_color(backbuffer1
, 320, 240);
6378 /* The testbot seems to just copy the contents of one surface to all the
6379 * others, instead of properly flipping. */
6380 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6381 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6382 color
= get_surface_color(backbuffer2
, 320, 240);
6383 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6384 fill_surface(backbuffer3
, 0xffff0000);
6386 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6387 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6388 color
= get_surface_color(backbuffer1
, 320, 240);
6389 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6390 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6391 color
= get_surface_color(backbuffer2
, 320, 240);
6392 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6393 fill_surface(backbuffer3
, 0xff00ff00);
6395 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6396 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6397 color
= get_surface_color(backbuffer1
, 320, 240);
6398 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6399 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6400 color
= get_surface_color(backbuffer2
, 320, 240);
6401 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6402 fill_surface(backbuffer3
, 0xff0000ff);
6404 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
6405 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6406 color
= get_surface_color(backbuffer2
, 320, 240);
6407 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6408 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6409 color
= get_surface_color(backbuffer3
, 320, 240);
6410 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6411 fill_surface(backbuffer1
, 0xffff0000);
6413 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
6414 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6415 color
= get_surface_color(backbuffer1
, 320, 240);
6416 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6417 color
= get_surface_color(backbuffer3
, 320, 240);
6418 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6419 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6420 fill_surface(backbuffer2
, 0xff00ff00);
6422 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
6423 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6424 color
= get_surface_color(backbuffer1
, 320, 240);
6425 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6426 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6427 color
= get_surface_color(backbuffer2
, 320, 240);
6428 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6430 IDirectDrawSurface4_Release(backbuffer3
);
6431 IDirectDrawSurface4_Release(backbuffer2
);
6432 IDirectDrawSurface4_Release(backbuffer1
);
6433 IDirectDrawSurface4_Release(frontbuffer
);
6436 refcount
= IDirectDraw4_Release(ddraw
);
6437 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6438 DestroyWindow(window
);
6441 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
6443 memset(ddsd
, 0, sizeof(*ddsd
));
6444 ddsd
->dwSize
= sizeof(*ddsd
);
6447 static void test_set_surface_desc(void)
6449 IDirectDraw4
*ddraw
;
6452 DDSURFACEDESC2 ddsd
;
6453 IDirectDrawSurface4
*surface
;
6463 invalid_caps_tests
[] =
6465 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
6466 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
6467 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
6468 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
6469 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
6472 window
= create_window();
6473 ddraw
= create_ddraw();
6474 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6475 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6476 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6479 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6482 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6483 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6484 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6485 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6486 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6487 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6488 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6490 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6491 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6494 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6495 ddsd
.lpSurface
= data
;
6496 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6497 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6499 /* Redundantly setting the same lpSurface is not an error. */
6500 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6501 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6502 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6503 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6504 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6505 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
6507 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6508 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6509 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6510 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
6511 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6512 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6515 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6516 ddsd
.lpSurface
= data
;
6517 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 1);
6518 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
6520 ddsd
.lpSurface
= NULL
;
6521 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6522 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
6524 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, NULL
, 0);
6525 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
6527 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6528 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6529 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6530 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6531 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6533 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
6534 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6535 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
6537 ddsd
.dwFlags
= DDSD_CAPS
;
6538 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6539 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6541 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
6542 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
6543 ddsd
.lpSurface
= data
;
6544 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6545 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6546 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6547 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6548 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6549 ddsd
.ddsCaps
.dwCaps
= 0;
6550 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
6551 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6552 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6554 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6555 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6556 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6557 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6558 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6560 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
6562 ddsd
.dwFlags
= DDSD_HEIGHT
;
6564 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6565 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
6567 ddsd
.lpSurface
= data
;
6568 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
6569 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6570 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6573 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6574 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
6577 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6578 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
6579 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6580 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6582 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0 */
6584 ddsd
.dwFlags
= DDSD_PITCH
;
6585 U1(ddsd
).lPitch
= 8 * 4;
6586 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6587 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
6589 ddsd
.dwFlags
= DDSD_WIDTH
;
6591 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6592 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
6594 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
6595 ddsd
.lpSurface
= data
;
6596 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6597 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
6599 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
6600 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6601 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
6603 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6604 U1(ddsd
).lPitch
= 16 * 4;
6606 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6607 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6610 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6611 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6612 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6613 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6614 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
6616 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
6618 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
6619 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6620 U1(ddsd
).lPitch
= 4 * 4;
6621 ddsd
.lpSurface
= data
;
6622 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6623 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6625 U1(ddsd
).lPitch
= 4;
6626 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6627 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6629 U1(ddsd
).lPitch
= 16 * 4 + 1;
6630 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6631 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6633 U1(ddsd
).lPitch
= 16 * 4 + 3;
6634 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6635 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6637 U1(ddsd
).lPitch
= -4;
6638 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6639 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
6641 U1(ddsd
).lPitch
= 16 * 4;
6642 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6643 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6646 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6647 U1(ddsd
).lPitch
= 0;
6649 ddsd
.lpSurface
= data
;
6650 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6651 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
6653 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6654 U1(ddsd
).lPitch
= 16 * 4;
6656 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6657 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
6659 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
6660 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
6661 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6662 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6663 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6664 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6665 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6666 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6667 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6668 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
6670 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6671 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6672 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6674 /* Can't set color keys. */
6676 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
6677 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
6678 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
6679 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6680 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6682 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
6683 ddsd
.lpSurface
= data
;
6684 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6685 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6687 IDirectDrawSurface4_Release(surface
);
6689 /* SetSurfaceDesc needs systemmemory surfaces.
6691 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
6692 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
6695 ddsd
.dwFlags
= DDSD_CAPS
;
6696 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
6697 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
6698 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6700 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6703 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6704 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6705 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6706 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6707 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6708 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6711 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6712 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
6715 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
6716 invalid_caps_tests
[i
].name
);
6721 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6722 ddsd
.lpSurface
= data
;
6723 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6724 if (invalid_caps_tests
[i
].supported
)
6726 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6730 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6731 invalid_caps_tests
[i
].name
, hr
);
6733 /* Check priority of error conditions. */
6734 ddsd
.dwFlags
= DDSD_WIDTH
;
6735 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6736 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6737 invalid_caps_tests
[i
].name
, hr
);
6740 IDirectDrawSurface4_Release(surface
);
6744 ref
= IDirectDraw4_Release(ddraw
);
6745 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6746 DestroyWindow(window
);
6749 static void test_user_memory_getdc(void)
6751 IDirectDraw4
*ddraw
;
6754 DDSURFACEDESC2 ddsd
;
6755 IDirectDrawSurface4
*surface
;
6764 window
= create_window();
6765 ddraw
= create_ddraw();
6766 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6768 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6769 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6772 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6775 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6776 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6777 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6778 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6779 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6780 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6781 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6782 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6783 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6785 memset(data
, 0xaa, sizeof(data
));
6787 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6788 ddsd
.lpSurface
= data
;
6789 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6790 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6792 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
6793 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6794 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
6795 ok(!!bitmap
, "Failed to get bitmap.\n");
6796 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
6797 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
6798 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
6799 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
6800 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
6801 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
6802 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6804 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
6805 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
6807 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
6808 ddsd
.lpSurface
= data
;
6811 U1(ddsd
).lPitch
= sizeof(*data
);
6812 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6813 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6815 memset(data
, 0xaa, sizeof(data
));
6816 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
6817 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6818 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
6819 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
6820 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
6821 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6823 for (y
= 0; y
< 4; y
++)
6825 for (x
= 0; x
< 4; x
++)
6827 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
6828 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
6831 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
6835 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
6837 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
6839 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
6841 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
6844 IDirectDrawSurface4_Release(surface
);
6845 ref
= IDirectDraw4_Release(ddraw
);
6846 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6847 DestroyWindow(window
);
6850 static void test_sysmem_overlay(void)
6852 IDirectDraw4
*ddraw
;
6855 DDSURFACEDESC2 ddsd
;
6856 IDirectDrawSurface4
*surface
;
6859 window
= create_window();
6860 ddraw
= create_ddraw();
6861 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6863 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6864 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6867 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6870 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
6871 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6872 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6873 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6874 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6875 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6876 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6877 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6878 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
6880 ref
= IDirectDraw4_Release(ddraw
);
6881 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6882 DestroyWindow(window
);
6885 static void test_primary_palette(void)
6887 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
6888 IDirectDrawSurface4
*primary
, *backbuffer
;
6889 PALETTEENTRY palette_entries
[256];
6890 IDirectDrawPalette
*palette
, *tmp
;
6891 DDSURFACEDESC2 surface_desc
;
6892 IDirectDraw4
*ddraw
;
6898 window
= create_window();
6899 ddraw
= create_ddraw();
6900 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6901 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6903 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6904 IDirectDraw4_Release(ddraw
);
6905 DestroyWindow(window
);
6908 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6909 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6911 memset(&surface_desc
, 0, sizeof(surface_desc
));
6912 surface_desc
.dwSize
= sizeof(surface_desc
);
6913 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6914 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6915 U5(surface_desc
).dwBackBufferCount
= 1;
6916 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6917 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6918 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
6919 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
6921 memset(palette_entries
, 0, sizeof(palette_entries
));
6922 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
6923 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6924 refcount
= get_refcount((IUnknown
*)palette
);
6925 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6927 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6928 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6929 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6931 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
6932 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6934 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
6935 * and is generally somewhat broken with respect to 8 bpp / palette
6937 if (SUCCEEDED(IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
)))
6939 win_skip("Broken palette handling detected, skipping tests.\n");
6940 IDirectDrawPalette_Release(tmp
);
6941 IDirectDrawPalette_Release(palette
);
6942 /* The Windows 8 testbot keeps extra references to the primary and
6943 * backbuffer while in 8 bpp mode. */
6944 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
6945 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6949 refcount
= get_refcount((IUnknown
*)palette
);
6950 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6952 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6953 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6954 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
6955 "Got unexpected palette caps %#x.\n", palette_caps
);
6957 hr
= IDirectDrawSurface4_SetPalette(primary
, NULL
);
6958 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6959 refcount
= get_refcount((IUnknown
*)palette
);
6960 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6962 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6963 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6964 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6966 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
6967 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6968 refcount
= get_refcount((IUnknown
*)palette
);
6969 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6971 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
6972 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
6973 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
6974 IDirectDrawPalette_Release(tmp
);
6975 hr
= IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
);
6976 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6978 refcount
= IDirectDrawPalette_Release(palette
);
6979 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6980 refcount
= IDirectDrawPalette_Release(palette
);
6981 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6983 /* Note that this only seems to work when the palette is attached to the
6984 * primary surface. When attached to a regular surface, attempting to get
6985 * the palette here will cause an access violation. */
6986 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
6987 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6989 hr
= IDirectDrawSurface4_IsLost(primary
);
6990 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6992 memset(&surface_desc
, 0, sizeof(surface_desc
));
6993 surface_desc
.dwSize
= sizeof(surface_desc
);
6994 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
6995 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6996 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6997 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6998 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
6999 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7001 hr
= set_display_mode(ddraw
, 640, 480);
7002 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
7004 memset(&surface_desc
, 0, sizeof(surface_desc
));
7005 surface_desc
.dwSize
= sizeof(surface_desc
);
7006 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7007 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7008 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7009 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7010 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
7011 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
7012 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7014 hr
= IDirectDrawSurface4_IsLost(primary
);
7015 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7016 hr
= IDirectDrawSurface4_Restore(primary
);
7017 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
7018 hr
= IDirectDrawSurface4_IsLost(primary
);
7019 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7021 memset(&surface_desc
, 0, sizeof(surface_desc
));
7022 surface_desc
.dwSize
= sizeof(surface_desc
);
7023 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7024 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7025 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7026 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7027 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
7028 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
7029 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7032 refcount
= IDirectDrawSurface4_Release(backbuffer
);
7033 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7034 refcount
= IDirectDrawSurface4_Release(primary
);
7035 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7036 refcount
= IDirectDraw4_Release(ddraw
);
7037 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7038 DestroyWindow(window
);
7041 static HRESULT WINAPI
surface_counter(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
7043 UINT
*surface_count
= context
;
7046 IDirectDrawSurface_Release(surface
);
7048 return DDENUMRET_OK
;
7051 static void test_surface_attachment(void)
7053 IDirectDrawSurface4
*surface1
, *surface2
, *surface3
, *surface4
;
7054 IDirectDrawSurface
*surface1v1
, *surface2v1
;
7055 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7056 DDSURFACEDESC2 surface_desc
;
7057 IDirectDraw4
*ddraw
;
7063 window
= create_window();
7064 ddraw
= create_ddraw();
7065 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7066 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7067 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7069 memset(&surface_desc
, 0, sizeof(surface_desc
));
7070 surface_desc
.dwSize
= sizeof(surface_desc
);
7071 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
7072 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7073 U2(surface_desc
).dwMipMapCount
= 3;
7074 surface_desc
.dwWidth
= 128;
7075 surface_desc
.dwHeight
= 128;
7076 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7077 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7079 hr
= IDirectDrawSurface4_GetAttachedSurface(surface1
, &caps
, &surface2
);
7080 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7081 hr
= IDirectDrawSurface4_GetAttachedSurface(surface2
, &caps
, &surface3
);
7082 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7083 hr
= IDirectDrawSurface4_GetAttachedSurface(surface3
, &caps
, &surface4
);
7084 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7087 IDirectDrawSurface4_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
7088 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7090 IDirectDrawSurface4_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
7091 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7093 IDirectDrawSurface4_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
7094 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
7096 memset(&surface_desc
, 0, sizeof(surface_desc
));
7097 surface_desc
.dwSize
= sizeof(surface_desc
);
7098 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7099 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7100 surface_desc
.dwWidth
= 16;
7101 surface_desc
.dwHeight
= 16;
7102 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7103 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7105 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7106 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7107 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7108 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7109 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7110 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7111 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7112 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7113 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7114 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7115 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7116 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7118 IDirectDrawSurface4_Release(surface4
);
7120 memset(&surface_desc
, 0, sizeof(surface_desc
));
7121 surface_desc
.dwSize
= sizeof(surface_desc
);
7122 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7123 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7124 surface_desc
.dwWidth
= 16;
7125 surface_desc
.dwHeight
= 16;
7126 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7127 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7129 if (SUCCEEDED(hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
)))
7131 skip("Running on refrast, skipping some tests.\n");
7132 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface4
);
7133 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7137 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7138 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7139 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7140 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7141 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7142 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7143 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7144 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7145 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7146 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7147 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7150 IDirectDrawSurface4_Release(surface4
);
7151 IDirectDrawSurface4_Release(surface3
);
7152 IDirectDrawSurface4_Release(surface2
);
7153 IDirectDrawSurface4_Release(surface1
);
7155 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7156 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7158 /* Try a single primary and two offscreen plain surfaces. */
7159 memset(&surface_desc
, 0, sizeof(surface_desc
));
7160 surface_desc
.dwSize
= sizeof(surface_desc
);
7161 surface_desc
.dwFlags
= DDSD_CAPS
;
7162 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7163 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7164 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7166 memset(&surface_desc
, 0, sizeof(surface_desc
));
7167 surface_desc
.dwSize
= sizeof(surface_desc
);
7168 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7169 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7170 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7171 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7172 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7173 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7175 memset(&surface_desc
, 0, sizeof(surface_desc
));
7176 surface_desc
.dwSize
= sizeof(surface_desc
);
7177 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7178 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7179 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7180 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7181 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7182 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7184 /* This one has a different size. */
7185 memset(&surface_desc
, 0, sizeof(surface_desc
));
7186 surface_desc
.dwSize
= sizeof(surface_desc
);
7187 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7188 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7189 surface_desc
.dwWidth
= 128;
7190 surface_desc
.dwHeight
= 128;
7191 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7192 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7194 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7195 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7196 /* Try the reverse without detaching first. */
7197 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7198 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7199 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7200 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7202 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7203 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7204 /* Try to detach reversed. */
7205 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7206 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7207 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface1
);
7208 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7210 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface3
);
7211 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7212 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface3
);
7213 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7215 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7216 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7217 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7218 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7220 IDirectDrawSurface4_Release(surface4
);
7221 IDirectDrawSurface4_Release(surface3
);
7222 IDirectDrawSurface4_Release(surface2
);
7223 IDirectDrawSurface4_Release(surface1
);
7225 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
7226 memset(&surface_desc
, 0, sizeof(surface_desc
));
7227 surface_desc
.dwSize
= sizeof(surface_desc
);
7228 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7229 surface_desc
.dwWidth
= 64;
7230 surface_desc
.dwHeight
= 64;
7231 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
7232 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7233 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
7234 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
7235 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
7236 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
7237 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
7238 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7239 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7240 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7241 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7243 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7244 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
7245 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
7246 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
7247 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7248 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7250 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
7251 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7252 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
7253 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7255 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7256 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7257 refcount
= get_refcount((IUnknown
*)surface2
);
7258 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7259 refcount
= get_refcount((IUnknown
*)surface2v1
);
7260 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7261 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7262 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7263 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7264 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7265 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7266 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7268 /* Attaching while already attached to other surface. */
7269 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface2
);
7270 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7271 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface3
, 0, surface2
);
7272 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7273 IDirectDrawSurface4_Release(surface3
);
7275 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7276 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7277 refcount
= get_refcount((IUnknown
*)surface2
);
7278 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7279 refcount
= get_refcount((IUnknown
*)surface2v1
);
7280 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7282 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
7283 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7284 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7285 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7286 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7287 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7288 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7289 refcount
= IDirectDrawSurface4_Release(surface2
);
7290 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7291 refcount
= IDirectDrawSurface4_Release(surface1
);
7292 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7294 /* Automatic detachment on release. */
7295 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7296 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7297 refcount
= get_refcount((IUnknown
*)surface2v1
);
7298 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7299 refcount
= IDirectDrawSurface_Release(surface1v1
);
7300 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7301 refcount
= IDirectDrawSurface_Release(surface2v1
);
7302 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7303 refcount
= IDirectDraw4_Release(ddraw
);
7304 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7305 DestroyWindow(window
);
7308 static void test_private_data(void)
7310 IDirectDraw4
*ddraw
;
7311 IDirectDrawSurface4
*surface
, *surface2
;
7312 DDSURFACEDESC2 surface_desc
;
7313 ULONG refcount
, refcount2
, refcount3
;
7315 DWORD size
= sizeof(ptr
);
7318 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7319 DWORD data
[] = {1, 2, 3, 4};
7321 static const GUID ddraw_private_data_test_guid
=
7326 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
7328 static const GUID ddraw_private_data_test_guid2
=
7333 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
7336 window
= create_window();
7337 ddraw
= create_ddraw();
7338 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7339 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7340 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7342 reset_ddsd(&surface_desc
);
7343 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
7344 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
7345 surface_desc
.dwHeight
= 4;
7346 surface_desc
.dwWidth
= 4;
7347 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7348 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7350 /* NULL pointers are not valid, but don't cause a crash. */
7351 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
7352 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
7353 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7354 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
7355 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7356 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
7357 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7359 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
7360 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7361 0, DDSPD_IUNKNOWNPOINTER
);
7362 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7363 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7364 5, DDSPD_IUNKNOWNPOINTER
);
7365 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7366 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7367 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
7368 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7370 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
7371 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
7372 * erases the old content and returns an error. This behavior has
7373 * been fixed in d3d8 and d3d9. Unless an application is found
7374 * that depends on this we don't care about this behavior. */
7375 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7376 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7377 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7378 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7379 0, DDSPD_IUNKNOWNPOINTER
);
7380 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7382 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7383 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7384 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7385 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7387 refcount
= get_refcount((IUnknown
*)ddraw
);
7388 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7389 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7390 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7391 refcount2
= get_refcount((IUnknown
*)ddraw
);
7392 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7394 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7395 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7396 refcount2
= get_refcount((IUnknown
*)ddraw
);
7397 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7399 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7400 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7401 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7402 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
7403 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
7404 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7405 refcount2
= get_refcount((IUnknown
*)ddraw
);
7406 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7408 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7409 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7410 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7411 size
= 2 * sizeof(ptr
);
7412 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7413 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7414 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7415 refcount2
= get_refcount(ptr
);
7416 /* Object is NOT addref'ed by the getter. */
7417 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
7418 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7420 ptr
= (IUnknown
*)0xdeadbeef;
7422 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7423 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7424 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7425 size
= 2 * sizeof(ptr
);
7426 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7427 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7428 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %u.\n", size
);
7430 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7431 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7432 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7433 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7434 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
7435 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7437 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
7438 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7439 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7440 ok(size
== 0xdeadbabe, "Got unexpected size %u.\n", size
);
7441 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7442 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7444 refcount3
= IDirectDrawSurface4_Release(surface
);
7445 ok(!refcount3
, "Got unexpected refcount %u.\n", refcount3
);
7447 /* Destroying the surface frees the reference held on the private data. It also frees
7448 * the reference the surface is holding on its creating object. */
7449 refcount2
= get_refcount((IUnknown
*)ddraw
);
7450 ok(refcount2
== refcount
- 1, "Got unexpected refcount %u.\n", refcount2
);
7452 memset(&hal_caps
, 0, sizeof(hal_caps
));
7453 hal_caps
.dwSize
= sizeof(hal_caps
);
7454 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
7455 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7456 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7458 reset_ddsd(&surface_desc
);
7459 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
7460 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7461 surface_desc
.dwHeight
= 4;
7462 surface_desc
.dwWidth
= 4;
7463 U2(surface_desc
).dwMipMapCount
= 2;
7464 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7465 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7466 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7467 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
7469 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
7470 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7471 hr
= IDirectDrawSurface4_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7472 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7474 IDirectDrawSurface4_Release(surface2
);
7475 IDirectDrawSurface4_Release(surface
);
7478 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
7480 refcount
= IDirectDraw4_Release(ddraw
);
7481 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7482 DestroyWindow(window
);
7485 static void test_pixel_format(void)
7487 HWND window
, window2
= NULL
;
7488 HDC hdc
, hdc2
= NULL
;
7490 int format
, test_format
;
7491 PIXELFORMATDESCRIPTOR pfd
;
7492 IDirectDraw4
*ddraw
= NULL
;
7493 IDirectDrawClipper
*clipper
= NULL
;
7494 DDSURFACEDESC2 ddsd
;
7495 IDirectDrawSurface4
*primary
= NULL
;
7499 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7500 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7503 skip("Failed to create window\n");
7507 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7508 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7510 hdc
= GetDC(window
);
7513 skip("Failed to get DC\n");
7518 hdc2
= GetDC(window2
);
7520 gl
= LoadLibraryA("opengl32.dll");
7521 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
7523 format
= GetPixelFormat(hdc
);
7524 ok(format
== 0, "new window has pixel format %d\n", format
);
7526 ZeroMemory(&pfd
, sizeof(pfd
));
7527 pfd
.nSize
= sizeof(pfd
);
7529 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
7530 pfd
.iPixelType
= PFD_TYPE_RGBA
;
7531 pfd
.iLayerType
= PFD_MAIN_PLANE
;
7532 format
= ChoosePixelFormat(hdc
, &pfd
);
7535 skip("no pixel format available\n");
7539 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7541 skip("failed to set pixel format\n");
7545 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7547 skip("failed to set pixel format on second window\n");
7550 ReleaseDC(window2
, hdc2
);
7555 ddraw
= create_ddraw();
7556 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7558 test_format
= GetPixelFormat(hdc
);
7559 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7561 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7564 skip("Failed to set cooperative level, hr %#x.\n", hr
);
7568 test_format
= GetPixelFormat(hdc
);
7569 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7573 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
7574 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
7575 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
7576 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
7578 test_format
= GetPixelFormat(hdc
);
7579 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7581 test_format
= GetPixelFormat(hdc2
);
7582 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7585 memset(&ddsd
, 0, sizeof(ddsd
));
7586 ddsd
.dwSize
= sizeof(ddsd
);
7587 ddsd
.dwFlags
= DDSD_CAPS
;
7588 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7590 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7591 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
7593 test_format
= GetPixelFormat(hdc
);
7594 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7598 test_format
= GetPixelFormat(hdc2
);
7599 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7604 hr
= IDirectDrawSurface4_SetClipper(primary
, clipper
);
7605 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
7607 test_format
= GetPixelFormat(hdc
);
7608 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7610 test_format
= GetPixelFormat(hdc2
);
7611 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7614 memset(&fx
, 0, sizeof(fx
));
7615 fx
.dwSize
= sizeof(fx
);
7616 hr
= IDirectDrawSurface4_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7617 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
7619 test_format
= GetPixelFormat(hdc
);
7620 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7624 test_format
= GetPixelFormat(hdc2
);
7625 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7629 if (primary
) IDirectDrawSurface4_Release(primary
);
7630 if (clipper
) IDirectDrawClipper_Release(clipper
);
7631 if (ddraw
) IDirectDraw4_Release(ddraw
);
7632 if (gl
) FreeLibrary(gl
);
7633 if (hdc
) ReleaseDC(window
, hdc
);
7634 if (hdc2
) ReleaseDC(window2
, hdc2
);
7635 if (window
) DestroyWindow(window
);
7636 if (window2
) DestroyWindow(window2
);
7639 static void test_create_surface_pitch(void)
7641 IDirectDrawSurface4
*surface
;
7642 DDSURFACEDESC2 surface_desc
;
7643 IDirectDraw4
*ddraw
;
7663 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7665 DDSD_PITCH
, 0x100, 0x100},
7666 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7667 DDSD_PITCH
, 0x104, DD_OK
,
7668 DDSD_PITCH
, 0x100, 0x100},
7669 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7670 DDSD_PITCH
, 0x0f8, DD_OK
,
7671 DDSD_PITCH
, 0x100, 0x100},
7672 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7673 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7675 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7677 DDSD_PITCH
, 0x100, 0x0fc},
7679 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7680 DDSD_PITCH
, 0x104, DD_OK
,
7681 DDSD_PITCH
, 0x100, 0x0fc},
7682 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7683 DDSD_PITCH
, 0x0f8, DD_OK
,
7684 DDSD_PITCH
, 0x100, 0x0fc},
7685 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7686 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
7687 DDSD_PITCH
, 0x100, 0x0fc},
7688 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7689 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
7691 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7692 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
7693 DDSD_PITCH
, 0x100, 0x100},
7695 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7696 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
7698 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7699 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
7700 DDSD_PITCH
, 0x0fc, 0x0fc},
7701 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7702 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
7704 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7705 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
7707 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7708 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
7711 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7712 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
7713 DDSD_PITCH
, 0x100, 0x100},
7714 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7715 0, 0, DDERR_INVALIDCAPS
,
7717 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7719 DDSD_PITCH
, 0x100, 0 },
7720 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7721 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7723 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7724 0, 0, DDERR_INVALIDCAPS
,
7727 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7729 DDSD_PITCH
, 0x100, 0 },
7730 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7731 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
7732 DDSD_PITCH
, 0x100, 0 },
7734 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
7736 window
= create_window();
7737 ddraw
= create_ddraw();
7738 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7739 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7740 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7742 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
7744 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7746 memset(&surface_desc
, 0, sizeof(surface_desc
));
7747 surface_desc
.dwSize
= sizeof(surface_desc
);
7748 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
7749 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7750 surface_desc
.dwWidth
= 63;
7751 surface_desc
.dwHeight
= 63;
7752 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
7753 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7754 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7755 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7756 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7757 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7758 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7759 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7760 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
7762 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
7763 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
7764 surface_desc
.lpSurface
= mem
;
7765 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7767 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
7769 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
7773 memset(&surface_desc
, 0, sizeof(surface_desc
));
7774 surface_desc
.dwSize
= sizeof(surface_desc
);
7775 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
7776 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7777 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
7778 "Test %u: Got unexpected flags %#x, expected %#x.\n",
7779 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
7780 /* The pitch for textures seems to be implementation specific. */
7781 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
7783 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
7784 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
7785 "Test %u: Got unexpected pitch %u, expected %u.\n",
7786 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
7788 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
7789 "Test %u: Got unexpected pitch %u, expected %u.\n",
7790 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
7792 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
7794 IDirectDrawSurface4_Release(surface
);
7797 HeapFree(GetProcessHeap(), 0, mem
);
7798 refcount
= IDirectDraw4_Release(ddraw
);
7799 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7800 DestroyWindow(window
);
7803 static void test_mipmap(void)
7805 IDirectDrawSurface4
*surface
, *surface2
;
7806 DDSURFACEDESC2 surface_desc
;
7807 IDirectDraw4
*ddraw
;
7812 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7821 DWORD mipmap_count_in
;
7823 DWORD mipmap_count_out
;
7827 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
7828 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
7829 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
7830 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
7831 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
7832 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
7835 window
= create_window();
7836 ddraw
= create_ddraw();
7837 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7838 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7839 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7841 memset(&hal_caps
, 0, sizeof(hal_caps
));
7842 hal_caps
.dwSize
= sizeof(hal_caps
);
7843 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
7844 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7845 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7847 skip("Mipmapped textures not supported, skipping tests.\n");
7848 IDirectDraw4_Release(ddraw
);
7849 DestroyWindow(window
);
7853 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7855 memset(&surface_desc
, 0, sizeof(surface_desc
));
7856 surface_desc
.dwSize
= sizeof(surface_desc
);
7857 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
7858 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7859 surface_desc
.dwWidth
= tests
[i
].width
;
7860 surface_desc
.dwHeight
= tests
[i
].height
;
7861 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
7862 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
7863 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7864 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7868 memset(&surface_desc
, 0, sizeof(surface_desc
));
7869 surface_desc
.dwSize
= sizeof(surface_desc
);
7870 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
7871 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7872 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7873 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
7874 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
7875 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
7877 if (U2(surface_desc
).dwMipMapCount
> 1)
7879 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7880 ok(SUCCEEDED(hr
), "Test %u: Failed to get attached surface, hr %#x.\n", i
, hr
);
7882 memset(&surface_desc
, 0, sizeof(surface_desc
));
7883 surface_desc
.dwSize
= sizeof(surface_desc
);
7884 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
7885 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
7886 memset(&surface_desc
, 0, sizeof(surface_desc
));
7887 surface_desc
.dwSize
= sizeof(surface_desc
);
7888 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &surface_desc
, 0, NULL
);
7889 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
7890 IDirectDrawSurface4_Unlock(surface2
, NULL
);
7891 IDirectDrawSurface4_Unlock(surface
, NULL
);
7893 IDirectDrawSurface4_Release(surface2
);
7896 IDirectDrawSurface4_Release(surface
);
7899 refcount
= IDirectDraw4_Release(ddraw
);
7900 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7901 DestroyWindow(window
);
7904 static void test_palette_complex(void)
7906 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
7907 DDSURFACEDESC2 surface_desc
;
7908 IDirectDraw4
*ddraw
;
7909 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
7913 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7915 PALETTEENTRY palette_entries
[256];
7921 window
= create_window();
7922 ddraw
= create_ddraw();
7923 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7924 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7925 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7927 memset(&hal_caps
, 0, sizeof(hal_caps
));
7928 hal_caps
.dwSize
= sizeof(hal_caps
);
7929 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
7930 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7931 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7933 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
7934 IDirectDraw4_Release(ddraw
);
7935 DestroyWindow(window
);
7939 memset(&surface_desc
, 0, sizeof(surface_desc
));
7940 surface_desc
.dwSize
= sizeof(surface_desc
);
7941 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7942 surface_desc
.dwWidth
= 128;
7943 surface_desc
.dwHeight
= 128;
7944 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7945 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7946 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7947 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
7948 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7949 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7951 memset(palette_entries
, 0, sizeof(palette_entries
));
7952 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7953 palette_entries
, &palette
, NULL
);
7954 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7956 memset(palette_entries
, 0, sizeof(palette_entries
));
7957 palette_entries
[1].peRed
= 0xff;
7958 palette_entries
[1].peGreen
= 0x80;
7959 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7960 palette_entries
, &palette_mipmap
, NULL
);
7961 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7963 palette2
= (void *)0xdeadbeef;
7964 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
7965 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
7966 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
7967 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
7968 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7969 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
7970 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
7971 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
7972 IDirectDrawPalette_Release(palette2
);
7975 IDirectDrawSurface4_AddRef(mipmap
);
7976 for (i
= 0; i
< 7; ++i
)
7978 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7979 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
7980 palette2
= (void *)0xdeadbeef;
7981 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
7982 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
7983 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
7985 hr
= IDirectDrawSurface4_SetPalette(tmp
, palette_mipmap
);
7986 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
7988 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
7989 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
7990 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
7991 IDirectDrawPalette_Release(palette2
);
7993 hr
= IDirectDrawSurface4_GetDC(tmp
, &dc
);
7994 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
7995 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7996 ok(count
== 1, "Expected count 1, got %u.\n", count
);
7997 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
7998 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
7999 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
8000 hr
= IDirectDrawSurface4_ReleaseDC(tmp
, dc
);
8001 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
8003 IDirectDrawSurface4_Release(mipmap
);
8007 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
8008 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8009 IDirectDrawSurface4_Release(mipmap
);
8010 refcount
= IDirectDrawSurface4_Release(surface
);
8011 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8012 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
8013 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8014 refcount
= IDirectDrawPalette_Release(palette
);
8015 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8017 refcount
= IDirectDraw4_Release(ddraw
);
8018 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8019 DestroyWindow(window
);
8022 static void test_p8_blit(void)
8024 IDirectDrawSurface4
*src
, *dst
, *dst_p8
;
8025 DDSURFACEDESC2 surface_desc
;
8026 IDirectDraw4
*ddraw
;
8027 IDirectDrawPalette
*palette
, *palette2
;
8031 PALETTEENTRY palette_entries
[256];
8035 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
8036 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
8037 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
8038 static const D3DCOLOR expected
[] =
8040 0x00101010, 0x00010101, 0x00020202, 0x00030303,
8041 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
8045 window
= create_window();
8046 ddraw
= create_ddraw();
8047 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8048 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8049 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8050 is_warp
= ddraw_is_warp(ddraw
);
8052 memset(palette_entries
, 0, sizeof(palette_entries
));
8053 palette_entries
[1].peGreen
= 0xff;
8054 palette_entries
[2].peBlue
= 0xff;
8055 palette_entries
[3].peFlags
= 0xff;
8056 palette_entries
[4].peRed
= 0xff;
8057 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8058 palette_entries
, &palette
, NULL
);
8059 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8060 palette_entries
[1].peBlue
= 0xff;
8061 palette_entries
[2].peGreen
= 0xff;
8062 palette_entries
[3].peRed
= 0xff;
8063 palette_entries
[4].peFlags
= 0x0;
8064 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8065 palette_entries
, &palette2
, NULL
);
8066 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8068 memset(&surface_desc
, 0, sizeof(surface_desc
));
8069 surface_desc
.dwSize
= sizeof(surface_desc
);
8070 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8071 surface_desc
.dwWidth
= 8;
8072 surface_desc
.dwHeight
= 1;
8073 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8074 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8075 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8076 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8077 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
8078 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8079 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
8080 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8081 hr
= IDirectDrawSurface4_SetPalette(dst_p8
, palette2
);
8082 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8084 memset(&surface_desc
, 0, sizeof(surface_desc
));
8085 surface_desc
.dwSize
= sizeof(surface_desc
);
8086 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8087 surface_desc
.dwWidth
= 8;
8088 surface_desc
.dwHeight
= 1;
8089 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8090 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8091 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8092 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8093 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8094 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8095 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8096 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8097 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
8098 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8100 memset(&surface_desc
, 0, sizeof(surface_desc
));
8101 surface_desc
.dwSize
= sizeof(surface_desc
);
8102 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8103 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
8104 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
8105 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
8106 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
8108 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8109 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8110 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
8111 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8112 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8114 hr
= IDirectDrawSurface4_SetPalette(src
, palette
);
8115 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8116 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
8117 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
8118 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
8119 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
8120 "Failed to blit, hr %#x.\n", hr
);
8124 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
8126 color
= get_surface_color(dst
, x
, 0);
8127 todo_wine
ok(compare_color(color
, expected
[x
], 0),
8128 "Pixel %u: Got color %#x, expected %#x.\n",
8129 x
, color
, expected
[x
]);
8133 memset(&fx
, 0, sizeof(fx
));
8134 fx
.dwSize
= sizeof(fx
);
8135 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
8136 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
8137 hr
= IDirectDrawSurface4_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
8138 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8140 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
8141 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8142 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
8143 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
8144 * for example) also works as expected.
8146 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
8147 * the display mode set to P8 doesn't help either. */
8148 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
8149 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
8150 "Got unexpected P8 color key blit result.\n");
8151 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8152 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8154 IDirectDrawSurface4_Release(src
);
8155 IDirectDrawSurface4_Release(dst
);
8156 IDirectDrawSurface4_Release(dst_p8
);
8157 IDirectDrawPalette_Release(palette
);
8158 IDirectDrawPalette_Release(palette2
);
8160 refcount
= IDirectDraw4_Release(ddraw
);
8161 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8162 DestroyWindow(window
);
8165 static void test_material(void)
8167 D3DMATERIALHANDLE mat_handle
, tmp
;
8168 IDirect3DMaterial3
*material
;
8169 IDirect3DViewport3
*viewport
;
8170 IDirect3DDevice3
*device
;
8171 IDirectDrawSurface4
*rt
;
8181 struct vec3 position
;
8187 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8188 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8189 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8190 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8194 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8195 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8196 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8197 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8203 D3DCOLOR expected_color
;
8207 {quad1
, TRUE
, 0x0000ff00},
8208 {quad2
, TRUE
, 0x0000ff00},
8209 {quad1
, FALSE
, 0x00ffffff},
8210 {quad2
, FALSE
, 0x00ff0000},
8212 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8214 window
= create_window();
8215 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
8217 skip("Failed to create a 3D device, skipping test.\n");
8218 DestroyWindow(window
);
8222 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
8223 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8225 viewport
= create_viewport(device
, 0, 0, 640, 480);
8226 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
8227 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
8229 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
8230 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8231 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8233 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8234 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8235 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8236 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8237 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8238 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8239 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8240 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8241 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
8242 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8243 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8244 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8245 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8247 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8249 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
8250 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
8251 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8253 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
8254 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8256 hr
= IDirect3DDevice3_BeginScene(device
);
8257 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8258 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
8259 D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
, test_data
[i
].data
, 4, 0);
8260 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8261 hr
= IDirect3DDevice3_EndScene(device
);
8262 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8263 color
= get_surface_color(rt
, 320, 240);
8264 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
8265 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
8268 destroy_material(material
);
8269 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8270 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8271 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8273 hr
= IDirect3DViewport3_SetBackground(viewport
, mat_handle
);
8274 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
8275 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8276 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8277 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8278 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8279 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8280 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8281 color
= get_surface_color(rt
, 320, 240);
8282 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8284 hr
= IDirect3DViewport3_SetBackground(viewport
, 0);
8285 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8286 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8287 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8288 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8289 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8290 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8291 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8292 color
= get_surface_color(rt
, 320, 240);
8293 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8295 destroy_viewport(device
, viewport
);
8296 viewport
= create_viewport(device
, 0, 0, 640, 480);
8298 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8299 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8300 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8301 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
8302 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8303 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8304 color
= get_surface_color(rt
, 320, 240);
8305 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
8307 destroy_viewport(device
, viewport
);
8308 destroy_material(material
);
8309 IDirectDrawSurface4_Release(rt
);
8310 refcount
= IDirect3DDevice3_Release(device
);
8311 ok(!refcount
, "Device has %u references left.\n", refcount
);
8312 DestroyWindow(window
);
8315 static void test_palette_gdi(void)
8317 IDirectDrawSurface4
*surface
, *primary
;
8318 DDSURFACEDESC2 surface_desc
;
8319 IDirectDraw4
*ddraw
;
8320 IDirectDrawPalette
*palette
, *palette2
;
8324 PALETTEENTRY palette_entries
[256];
8330 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8331 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8332 * not the point of this test. */
8333 static const RGBQUAD expected1
[] =
8335 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8336 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8338 static const RGBQUAD expected2
[] =
8340 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8341 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8343 static const RGBQUAD expected3
[] =
8345 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8346 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8348 HPALETTE ddraw_palette_handle
;
8349 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8350 RGBQUAD rgbquad
[255];
8351 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8353 window
= create_window();
8354 ddraw
= create_ddraw();
8355 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8356 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8357 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8359 memset(&surface_desc
, 0, sizeof(surface_desc
));
8360 surface_desc
.dwSize
= sizeof(surface_desc
);
8361 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8362 surface_desc
.dwWidth
= 16;
8363 surface_desc
.dwHeight
= 16;
8364 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8365 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8366 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8367 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8368 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8369 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8371 /* Avoid colors from the Windows default palette. */
8372 memset(palette_entries
, 0, sizeof(palette_entries
));
8373 palette_entries
[1].peRed
= 0x01;
8374 palette_entries
[2].peGreen
= 0x02;
8375 palette_entries
[3].peBlue
= 0x03;
8376 palette_entries
[4].peRed
= 0x13;
8377 palette_entries
[4].peGreen
= 0x14;
8378 palette_entries
[4].peBlue
= 0x15;
8379 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8380 palette_entries
, &palette
, NULL
);
8381 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8383 /* If there is no palette assigned and the display mode is not 8 bpp, some
8384 * drivers refuse to create a DC while others allow it. If a DC is created,
8385 * the DIB color table is uninitialized and contains random colors. No error
8386 * is generated when trying to read pixels and random garbage is returned.
8388 * The most likely explanation is that if the driver creates a DC, it (or
8389 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8390 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8391 * contains uninitialized garbage. See comments below for the P8 case. */
8393 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8394 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8395 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8396 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8397 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8398 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8399 "Got unexpected palette %p, expected %p.\n",
8400 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8402 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8403 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8404 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8406 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8407 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8408 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8409 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8411 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8413 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8414 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8415 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8418 /* Update the palette while the DC is in use. This does not modify the DC. */
8419 palette_entries
[4].peRed
= 0x23;
8420 palette_entries
[4].peGreen
= 0x24;
8421 palette_entries
[4].peBlue
= 0x25;
8422 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8423 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
8425 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8426 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8427 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8428 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8429 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8430 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8432 /* Neither does re-setting the palette. */
8433 hr
= IDirectDrawSurface4_SetPalette(surface
, NULL
);
8434 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8435 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8436 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8438 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8439 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8440 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8441 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8442 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8443 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8445 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8446 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8448 /* Refresh the DC. This updates the palette. */
8449 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8450 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8451 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8452 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8453 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8455 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8456 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8457 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8458 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8460 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8462 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8463 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8464 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8466 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8467 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8469 refcount
= IDirectDrawSurface4_Release(surface
);
8470 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8472 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8473 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8474 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8476 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8477 IDirectDrawPalette_Release(palette
);
8478 IDirectDraw4_Release(ddraw
);
8479 DestroyWindow(window
);
8482 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8484 memset(&surface_desc
, 0, sizeof(surface_desc
));
8485 surface_desc
.dwSize
= sizeof(surface_desc
);
8486 surface_desc
.dwFlags
= DDSD_CAPS
;
8487 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8488 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8489 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8491 memset(&fx
, 0, sizeof(fx
));
8492 fx
.dwSize
= sizeof(fx
);
8493 U5(fx
).dwFillColor
= 3;
8494 SetRect(&r
, 0, 0, 319, 479);
8495 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8496 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8497 SetRect(&r
, 320, 0, 639, 479);
8498 U5(fx
).dwFillColor
= 4;
8499 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8500 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8502 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
8503 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8504 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
8505 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8507 color
= GetPixel(dc
, 160, 240);
8508 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8509 color
= GetPixel(dc
, 480, 240);
8510 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8512 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8513 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8514 "Got unexpected palette %p, expected %p.\n",
8515 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8516 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8518 /* The primary uses the system palette. In exclusive mode, the system palette matches
8519 * the ddraw palette attached to the primary, so the result is what you would expect
8520 * from a regular surface. Tests for the interaction between the ddraw palette and
8521 * the system palette are not included pending an application that depends on this.
8522 * The relation between those causes problems on Windows Vista and newer for games
8523 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8524 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8525 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8526 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8528 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8529 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8530 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8531 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8533 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8535 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8536 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8537 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8539 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
8540 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8542 memset(&surface_desc
, 0, sizeof(surface_desc
));
8543 surface_desc
.dwSize
= sizeof(surface_desc
);
8544 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8545 surface_desc
.dwWidth
= 16;
8546 surface_desc
.dwHeight
= 16;
8547 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8548 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8549 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8551 /* Here the offscreen surface appears to use the primary's palette,
8552 * but in all likelihood it is actually the system palette. */
8553 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8554 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8555 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8556 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8557 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8559 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8560 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8561 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8562 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8564 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8566 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8567 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8568 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8570 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8571 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8573 /* On real hardware a change to the primary surface's palette applies immediately,
8574 * even on device contexts from offscreen surfaces that do not have their own
8575 * palette. On the testbot VMs this is not the case. Don't test this until we
8576 * know of an application that depends on this. */
8578 memset(palette_entries
, 0, sizeof(palette_entries
));
8579 palette_entries
[1].peBlue
= 0x40;
8580 palette_entries
[2].peRed
= 0x40;
8581 palette_entries
[3].peGreen
= 0x40;
8582 palette_entries
[4].peRed
= 0x12;
8583 palette_entries
[4].peGreen
= 0x34;
8584 palette_entries
[4].peBlue
= 0x56;
8585 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8586 palette_entries
, &palette2
, NULL
);
8587 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8588 hr
= IDirectDrawSurface4_SetPalette(surface
, palette2
);
8589 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8591 /* A palette assigned to the offscreen surface overrides the primary / system
8593 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8594 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8595 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8596 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8597 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
8599 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
8600 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8601 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8602 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
8604 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8606 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8607 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8608 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8610 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8611 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8613 refcount
= IDirectDrawSurface4_Release(surface
);
8614 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8616 /* The Windows 8 testbot keeps extra references to the primary and
8617 * backbuffer while in 8 bpp mode. */
8618 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
8619 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8621 refcount
= IDirectDrawSurface4_Release(primary
);
8622 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8623 refcount
= IDirectDrawPalette_Release(palette2
);
8624 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8625 refcount
= IDirectDrawPalette_Release(palette
);
8626 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8627 refcount
= IDirectDraw4_Release(ddraw
);
8628 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8629 DestroyWindow(window
);
8632 static void test_palette_alpha(void)
8634 IDirectDrawSurface4
*surface
;
8635 DDSURFACEDESC2 surface_desc
;
8636 IDirectDraw4
*ddraw
;
8637 IDirectDrawPalette
*palette
;
8641 PALETTEENTRY palette_entries
[256];
8646 BOOL attach_allowed
;
8651 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
8652 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
8653 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
8656 window
= create_window();
8657 ddraw
= create_ddraw();
8658 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8659 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8661 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8662 IDirectDraw4_Release(ddraw
);
8663 DestroyWindow(window
);
8666 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8667 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8669 memset(palette_entries
, 0, sizeof(palette_entries
));
8670 palette_entries
[1].peFlags
= 0x42;
8671 palette_entries
[2].peFlags
= 0xff;
8672 palette_entries
[3].peFlags
= 0x80;
8673 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
8674 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8676 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8677 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8678 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8679 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8680 palette_entries
[0].peFlags
);
8681 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8682 palette_entries
[1].peFlags
);
8683 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8684 palette_entries
[2].peFlags
);
8685 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8686 palette_entries
[3].peFlags
);
8688 IDirectDrawPalette_Release(palette
);
8690 memset(palette_entries
, 0, sizeof(palette_entries
));
8691 palette_entries
[1].peFlags
= 0x42;
8692 palette_entries
[1].peRed
= 0xff;
8693 palette_entries
[2].peFlags
= 0xff;
8694 palette_entries
[3].peFlags
= 0x80;
8695 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
8696 palette_entries
, &palette
, NULL
);
8697 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8699 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8700 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8701 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8702 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8703 palette_entries
[0].peFlags
);
8704 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8705 palette_entries
[1].peFlags
);
8706 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8707 palette_entries
[2].peFlags
);
8708 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8709 palette_entries
[3].peFlags
);
8711 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
8713 memset(&surface_desc
, 0, sizeof(surface_desc
));
8714 surface_desc
.dwSize
= sizeof(surface_desc
);
8715 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
8716 surface_desc
.dwWidth
= 128;
8717 surface_desc
.dwHeight
= 128;
8718 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8719 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8720 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8722 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8723 if (test_data
[i
].attach_allowed
)
8724 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8726 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8734 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8735 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8736 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8737 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
8738 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
8739 rgbquad
.rgbRed
, test_data
[i
].name
);
8740 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
8741 rgbquad
.rgbGreen
, test_data
[i
].name
);
8742 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
8743 rgbquad
.rgbBlue
, test_data
[i
].name
);
8744 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
8745 rgbquad
.rgbReserved
, test_data
[i
].name
);
8746 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8747 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8749 IDirectDrawSurface4_Release(surface
);
8752 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8753 memset(&surface_desc
, 0, sizeof(surface_desc
));
8754 surface_desc
.dwSize
= sizeof(surface_desc
);
8755 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8756 surface_desc
.dwWidth
= 128;
8757 surface_desc
.dwHeight
= 128;
8758 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8759 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8760 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8761 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8762 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8763 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8764 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8765 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8766 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8767 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8768 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
8769 IDirectDrawSurface4_Release(surface
);
8771 /* The Windows 8 testbot keeps extra references to the primary
8772 * while in 8 bpp mode. */
8773 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
8774 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8776 refcount
= IDirectDrawPalette_Release(palette
);
8777 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8778 refcount
= IDirectDraw4_Release(ddraw
);
8779 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8780 DestroyWindow(window
);
8783 static void test_vb_writeonly(void)
8785 IDirect3DDevice3
*device
;
8787 IDirect3DVertexBuffer
*buffer
;
8790 D3DVERTEXBUFFERDESC desc
;
8792 static const struct vec4 quad
[] =
8794 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
8795 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
8796 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
8797 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
8800 window
= create_window();
8801 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
8803 skip("Failed to create a 3D device, skipping test.\n");
8804 DestroyWindow(window
);
8808 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
8809 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
8811 memset(&desc
, 0, sizeof(desc
));
8812 desc
.dwSize
= sizeof(desc
);
8813 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
8814 desc
.dwFVF
= D3DFVF_XYZRHW
;
8815 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
8816 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
8817 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
8819 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
8820 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8821 memcpy(ptr
, quad
, sizeof(quad
));
8822 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8823 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8825 hr
= IDirect3DDevice3_BeginScene(device
);
8826 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8827 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
8828 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8829 hr
= IDirect3DDevice3_EndScene(device
);
8830 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8832 hr
= IDirect3DVertexBuffer_Lock(buffer
, 0, &ptr
, NULL
);
8833 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8834 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8835 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8836 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8838 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
8839 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8840 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8841 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8842 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8844 IDirect3DVertexBuffer_Release(buffer
);
8845 IDirect3D3_Release(d3d
);
8846 IDirect3DDevice3_Release(device
);
8847 DestroyWindow(window
);
8850 static void test_lost_device(void)
8852 IDirectDrawSurface4
*surface
;
8853 DDSURFACEDESC2 surface_desc
;
8854 HWND window1
, window2
;
8855 IDirectDraw4
*ddraw
;
8860 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8861 0, 0, 640, 480, 0, 0, 0, 0);
8862 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8863 0, 0, 640, 480, 0, 0, 0, 0);
8864 ddraw
= create_ddraw();
8865 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8866 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8867 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8869 memset(&surface_desc
, 0, sizeof(surface_desc
));
8870 surface_desc
.dwSize
= sizeof(surface_desc
);
8871 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8872 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8873 U5(surface_desc
).dwBackBufferCount
= 1;
8874 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8875 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8877 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8878 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8879 hr
= IDirectDrawSurface4_IsLost(surface
);
8880 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8881 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8882 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8884 ret
= SetForegroundWindow(GetDesktopWindow());
8885 ok(ret
, "Failed to set foreground window.\n");
8886 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8887 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8888 hr
= IDirectDrawSurface4_IsLost(surface
);
8889 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8890 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8891 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8893 ret
= SetForegroundWindow(window1
);
8894 ok(ret
, "Failed to set foreground window.\n");
8895 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8896 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8897 hr
= IDirectDrawSurface4_IsLost(surface
);
8898 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8899 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8900 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8902 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
8903 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8904 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8905 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8906 hr
= IDirectDrawSurface4_IsLost(surface
);
8907 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8908 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8909 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8911 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8912 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8913 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8914 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8915 hr
= IDirectDrawSurface4_IsLost(surface
);
8916 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8917 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8918 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8920 /* Trying to restore the primary will crash, probably because flippable
8921 * surfaces can't exist in DDSCL_NORMAL. */
8922 IDirectDrawSurface4_Release(surface
);
8923 memset(&surface_desc
, 0, sizeof(surface_desc
));
8924 surface_desc
.dwSize
= sizeof(surface_desc
);
8925 surface_desc
.dwFlags
= DDSD_CAPS
;
8926 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8927 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8928 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8930 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8931 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8932 hr
= IDirectDrawSurface4_IsLost(surface
);
8933 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8935 ret
= SetForegroundWindow(GetDesktopWindow());
8936 ok(ret
, "Failed to set foreground window.\n");
8937 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8938 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8939 hr
= IDirectDrawSurface4_IsLost(surface
);
8940 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8942 ret
= SetForegroundWindow(window1
);
8943 ok(ret
, "Failed to set foreground window.\n");
8944 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8945 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8946 hr
= IDirectDrawSurface4_IsLost(surface
);
8947 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8949 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8950 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8951 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8952 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8953 hr
= IDirectDrawSurface4_IsLost(surface
);
8954 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8956 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
8957 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8958 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8959 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8960 hr
= IDirectDrawSurface4_IsLost(surface
);
8961 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8963 IDirectDrawSurface4_Release(surface
);
8964 memset(&surface_desc
, 0, sizeof(surface_desc
));
8965 surface_desc
.dwSize
= sizeof(surface_desc
);
8966 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8967 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8968 U5(surface_desc
).dwBackBufferCount
= 1;
8969 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8970 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8972 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8973 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8974 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8975 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8976 hr
= IDirectDrawSurface4_IsLost(surface
);
8977 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8978 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8979 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8981 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8982 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8983 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8984 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8985 hr
= IDirectDrawSurface4_IsLost(surface
);
8986 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8987 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8988 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8990 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8991 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8992 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8993 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8994 hr
= IDirectDrawSurface4_IsLost(surface
);
8995 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8996 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8997 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8999 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
9000 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9001 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9002 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9003 hr
= IDirectDrawSurface4_IsLost(surface
);
9004 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9005 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9006 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9008 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9009 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9010 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9011 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9012 hr
= IDirectDrawSurface4_IsLost(surface
);
9013 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9014 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9015 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9017 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9018 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9019 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9020 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9021 hr
= IDirectDrawSurface4_IsLost(surface
);
9022 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9023 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9024 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9026 IDirectDrawSurface4_Release(surface
);
9027 refcount
= IDirectDraw4_Release(ddraw
);
9028 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9029 DestroyWindow(window2
);
9030 DestroyWindow(window1
);
9033 static void test_surface_desc_lock(void)
9035 IDirectDrawSurface4
*surface
;
9036 DDSURFACEDESC2 surface_desc
;
9037 IDirectDraw4
*ddraw
;
9042 window
= create_window();
9043 ddraw
= create_ddraw();
9044 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9045 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9046 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9048 memset(&surface_desc
, 0, sizeof(surface_desc
));
9049 surface_desc
.dwSize
= sizeof(surface_desc
);
9050 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9051 surface_desc
.dwWidth
= 16;
9052 surface_desc
.dwHeight
= 16;
9053 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9054 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9055 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9057 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9058 surface_desc
.dwSize
= sizeof(surface_desc
);
9059 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9060 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9061 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9063 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9064 surface_desc
.dwSize
= sizeof(surface_desc
);
9065 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9066 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9067 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9068 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9069 surface_desc
.dwSize
= sizeof(surface_desc
);
9070 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9071 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9072 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9073 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9074 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9076 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9077 surface_desc
.dwSize
= sizeof(surface_desc
);
9078 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9079 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9080 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9082 IDirectDrawSurface4_Release(surface
);
9083 refcount
= IDirectDraw4_Release(ddraw
);
9084 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9085 DestroyWindow(window
);
9088 static void test_texturemapblend(void)
9090 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9091 static RECT rect
= {0, 0, 64, 128};
9092 IDirectDrawSurface4
*surface
, *rt
;
9093 IDirect3DViewport3
*viewport
;
9094 DDSURFACEDESC2 surface_desc
;
9095 IDirect3DTexture2
*texture
;
9096 IDirect3DDevice3
*device
;
9097 IDirectDraw4
*ddraw
;
9108 struct vec4 position
;
9110 struct vec2 texcoord
;
9114 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 0.0f
}},
9115 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 1.0f
}},
9116 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 0.0f
}},
9117 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 1.0f
}},
9118 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 0.0f
}},
9119 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 1.0f
}},
9120 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 0.0f
}},
9121 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 1.0f
}},
9125 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 0.0f
}},
9126 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 1.0f
}},
9127 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 0.0f
}},
9128 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 1.0f
}},
9129 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 0.0f
}},
9130 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 1.0f
}},
9131 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 0.0f
}},
9132 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 1.0f
}},
9135 window
= create_window();
9136 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9138 skip("Failed to create a 3D device, skipping test.\n");
9139 DestroyWindow(window
);
9143 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9144 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9145 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9146 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9147 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9148 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9150 viewport
= create_viewport(device
, 0, 0, 640, 480);
9151 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9152 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
9154 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture
9157 * The vertex alpha is completely ignored in this case, so case 1 and 2
9158 * combined are not a D3DTOP_MODULATE with texture alpha = 0xff in case 2
9159 * (no alpha in texture). */
9160 memset(&surface_desc
, 0, sizeof(surface_desc
));
9161 surface_desc
.dwSize
= sizeof(surface_desc
);
9162 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9163 surface_desc
.dwHeight
= 128;
9164 surface_desc
.dwWidth
= 128;
9165 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9166 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9167 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9168 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9169 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9170 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9171 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9172 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9173 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9174 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9176 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9177 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9178 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9179 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9181 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9182 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9184 memset(&fx
, 0, sizeof(fx
));
9185 fx
.dwSize
= sizeof(fx
);
9186 U5(fx
).dwFillColor
= 0xff0000ff;
9187 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9188 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9189 U5(fx
).dwFillColor
= 0x800000ff;
9190 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9191 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9193 /* Note that the ddraw1 version of this test runs tests 1-3 with
9194 * D3DRENDERSTATE_COLORKEYENABLE enabled, whereas this version only runs
9195 * test 4 with color keying on. Because no color key is set on the texture
9196 * this should not result in different behavior. */
9197 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9198 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9199 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9200 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9201 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9202 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9203 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9204 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9205 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9206 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9207 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9208 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9210 hr
= IDirect3DDevice3_BeginScene(device
);
9211 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9212 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9213 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9214 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9215 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9216 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9217 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9218 hr
= IDirect3DDevice3_EndScene(device
);
9219 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9221 color
= get_surface_color(rt
, 5, 5);
9222 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9223 color
= get_surface_color(rt
, 400, 5);
9224 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9225 color
= get_surface_color(rt
, 5, 245);
9226 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9227 color
= get_surface_color(rt
, 400, 245);
9228 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9230 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9231 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9232 IDirect3DTexture2_Release(texture
);
9233 refcount
= IDirectDrawSurface4_Release(surface
);
9234 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9236 /* Test alpha with texture that has no alpha channel - alpha should be
9237 * taken from diffuse vertex color. */
9238 memset(&surface_desc
, 0, sizeof(surface_desc
));
9239 surface_desc
.dwSize
= sizeof(surface_desc
);
9240 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9241 surface_desc
.dwHeight
= 128;
9242 surface_desc
.dwWidth
= 128;
9243 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9244 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9245 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9246 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9247 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9248 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9249 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9251 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9252 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9254 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9255 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9256 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9257 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9259 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9260 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9262 U5(fx
).dwFillColor
= 0xff0000ff;
9263 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9264 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9265 U5(fx
).dwFillColor
= 0x800000ff;
9266 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9267 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9269 hr
= IDirect3DDevice3_BeginScene(device
);
9270 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9271 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9272 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9273 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9274 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9275 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9276 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9277 hr
= IDirect3DDevice3_EndScene(device
);
9278 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9280 color
= get_surface_color(rt
, 5, 5);
9281 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9282 color
= get_surface_color(rt
, 400, 5);
9283 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9284 color
= get_surface_color(rt
, 5, 245);
9285 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9286 color
= get_surface_color(rt
, 400, 245);
9287 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9289 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9290 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9291 IDirect3DTexture2_Release(texture
);
9292 refcount
= IDirectDrawSurface4_Release(surface
);
9293 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9295 /* Test RGB - should multiply color components from diffuse vertex color
9297 memset(&surface_desc
, 0, sizeof(surface_desc
));
9298 surface_desc
.dwSize
= sizeof(surface_desc
);
9299 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9300 surface_desc
.dwHeight
= 128;
9301 surface_desc
.dwWidth
= 128;
9302 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9303 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9304 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9305 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9306 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9307 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9308 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9309 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9310 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9311 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9313 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9314 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9315 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9316 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9318 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9319 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9321 U5(fx
).dwFillColor
= 0x00ffffff;
9322 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9323 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9324 U5(fx
).dwFillColor
= 0x00ffff80;
9325 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9326 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9328 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9329 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9331 hr
= IDirect3DDevice3_BeginScene(device
);
9332 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9333 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9334 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[0], 4, 0);
9335 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9336 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9337 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[4], 4, 0);
9338 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9339 hr
= IDirect3DDevice3_EndScene(device
);
9340 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9342 color
= get_surface_color(rt
, 5, 5);
9343 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9344 color
= get_surface_color(rt
, 400, 5);
9345 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9346 color
= get_surface_color(rt
, 5, 245);
9347 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9348 color
= get_surface_color(rt
, 400, 245);
9349 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9351 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9352 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9353 IDirect3DTexture2_Release(texture
);
9354 refcount
= IDirectDrawSurface4_Release(surface
);
9355 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9357 /* Test alpha again, now with color keyed texture (colorkey emulation in
9358 * wine can interfere). */
9359 memset(&surface_desc
, 0, sizeof(surface_desc
));
9360 surface_desc
.dwSize
= sizeof(surface_desc
);
9361 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9362 surface_desc
.dwHeight
= 128;
9363 surface_desc
.dwWidth
= 128;
9364 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9365 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9366 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9367 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
9368 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
9369 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9370 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
9372 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9373 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9375 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9376 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9377 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9378 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9380 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9381 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9383 U5(fx
).dwFillColor
= 0xf800;
9384 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9385 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9386 U5(fx
).dwFillColor
= 0x001f;
9387 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9388 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9390 ckey
.dwColorSpaceLowValue
= 0x001f;
9391 ckey
.dwColorSpaceHighValue
= 0x001f;
9392 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9393 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9395 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9396 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9397 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9398 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9400 hr
= IDirect3DDevice3_BeginScene(device
);
9401 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9402 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9403 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9404 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9405 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9406 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9407 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9408 hr
= IDirect3DDevice3_EndScene(device
);
9409 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9411 color
= get_surface_color(rt
, 5, 5);
9412 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9413 color
= get_surface_color(rt
, 400, 5);
9414 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9415 color
= get_surface_color(rt
, 5, 245);
9416 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9417 color
= get_surface_color(rt
, 400, 245);
9418 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9420 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9421 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9422 IDirect3DTexture2_Release(texture
);
9423 refcount
= IDirectDrawSurface4_Release(surface
);
9424 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9426 destroy_viewport(device
, viewport
);
9427 IDirectDrawSurface4_Release(rt
);
9428 IDirect3DDevice3_Release(device
);
9429 IDirect3D3_Release(d3d
);
9430 refcount
= IDirectDraw4_Release(ddraw
);
9431 ok(!refcount
, "Ddraw object not properly released, refcount %u.\n", refcount
);
9432 DestroyWindow(window
);
9435 static void test_signed_formats(void)
9438 IDirect3DDevice3
*device
;
9440 IDirectDraw4
*ddraw
;
9441 IDirectDrawSurface4
*surface
, *rt
;
9442 IDirect3DTexture2
*texture
;
9443 IDirect3DViewport3
*viewport
;
9444 DDSURFACEDESC2 surface_desc
;
9447 D3DCOLOR color
, expected_color
;
9451 struct vec3 position
;
9452 struct vec2 texcoord
;
9456 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
9457 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
9458 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
9459 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
9461 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
9462 * of these values. */
9463 static const USHORT content_v8u8
[4][4] =
9465 {0x0000, 0x7f7f, 0x8880, 0x0000},
9466 {0x0080, 0x8000, 0x7f00, 0x007f},
9467 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
9468 {0x4444, 0xc0c0, 0xa066, 0x22e0},
9470 static const DWORD content_x8l8v8u8
[4][4] =
9472 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
9473 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
9474 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
9475 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
9477 static const USHORT content_l6v5u5
[4][4] =
9479 {0x0000, 0xfdef, 0x0230, 0xfc00},
9480 {0x0010, 0x0200, 0x01e0, 0x000f},
9481 {0x4067, 0x53b9, 0x0421, 0xffff},
9482 {0x8108, 0x0318, 0xc28c, 0x909c},
9487 const void *content
;
9490 unsigned int slop
, slop_broken
;
9491 DDPIXELFORMAT format
;
9496 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
9498 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
9499 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
9503 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
9505 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
9506 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
9510 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
9512 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
9513 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
9517 /* No V16U16 or Q8W8V8U8 support in ddraw. */
9519 static const D3DCOLOR expected_colors
[4][4] =
9521 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
9522 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
9523 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
9524 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
9526 unsigned int i
, width
, x
, y
;
9527 D3DDEVICEDESC device_desc
, hel_desc
;
9529 window
= create_window();
9530 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9532 skip("Failed to create a 3D device, skipping test.\n");
9533 DestroyWindow(window
);
9537 memset(&device_desc
, 0, sizeof(device_desc
));
9538 device_desc
.dwSize
= sizeof(device_desc
);
9539 memset(&hel_desc
, 0, sizeof(hel_desc
));
9540 hel_desc
.dwSize
= sizeof(hel_desc
);
9541 hr
= IDirect3DDevice3_GetCaps(device
, &device_desc
, &hel_desc
);
9542 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
9543 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
9545 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
9549 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9550 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9551 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9552 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9553 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9554 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9556 memset(&surface_desc
, 0, sizeof(surface_desc
));
9557 surface_desc
.dwSize
= sizeof(surface_desc
);
9558 hr
= IDirectDrawSurface4_GetSurfaceDesc(rt
, &surface_desc
);
9559 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9560 viewport
= create_viewport(device
, 0, 0, surface_desc
.dwWidth
, surface_desc
.dwHeight
);
9561 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9562 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
9563 U1(clear_rect
).x1
= 0;
9564 U2(clear_rect
).y1
= 0;
9565 U3(clear_rect
).x2
= surface_desc
.dwWidth
;
9566 U4(clear_rect
).y2
= surface_desc
.dwHeight
;
9568 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9569 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9571 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
9572 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
9573 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9574 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
9575 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9576 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
9577 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9578 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
9579 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9581 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
9583 for (width
= 1; width
< 5; width
+= 3)
9585 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
9586 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9588 memset(&surface_desc
, 0, sizeof(surface_desc
));
9589 surface_desc
.dwSize
= sizeof(surface_desc
);
9590 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
9591 surface_desc
.dwWidth
= width
;
9592 surface_desc
.dwHeight
= 4;
9593 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
9594 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
9595 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9598 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
9601 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9603 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9604 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x, format %s.\n",
9605 hr
, formats
[i
].name
);
9606 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9607 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9608 IDirect3DTexture2_Release(texture
);
9610 memset(&surface_desc
, 0, sizeof(surface_desc
));
9611 surface_desc
.dwSize
= sizeof(surface_desc
);
9612 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9613 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9614 for (y
= 0; y
< 4; y
++)
9616 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
9617 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
9618 width
* formats
[i
].pixel_size
);
9620 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9621 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9623 hr
= IDirect3DDevice3_BeginScene(device
);
9624 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9625 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9626 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
9627 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9628 hr
= IDirect3DDevice3_EndScene(device
);
9629 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9631 for (y
= 0; y
< 4; y
++)
9633 for (x
= 0; x
< width
; x
++)
9635 expected_color
= expected_colors
[y
][x
];
9636 if (!formats
[i
].blue
)
9637 expected_color
|= 0x000000ff;
9639 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
9640 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
9641 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
9642 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
9643 expected_color
, color
, formats
[i
].name
, x
, y
);
9647 IDirectDrawSurface4_Release(surface
);
9651 destroy_viewport(device
, viewport
);
9652 IDirectDrawSurface4_Release(rt
);
9653 IDirectDraw4_Release(ddraw
);
9654 IDirect3D3_Release(d3d
);
9657 refcount
= IDirect3DDevice3_Release(device
);
9658 ok(!refcount
, "Device has %u references left.\n", refcount
);
9659 DestroyWindow(window
);
9662 static void test_color_fill(void)
9665 IDirect3DDevice3
*device
;
9667 IDirectDraw4
*ddraw
;
9668 IDirectDrawSurface4
*surface
, *surface2
;
9669 DDSURFACEDESC2 surface_desc
;
9670 DDPIXELFORMAT z_fmt
;
9675 RECT rect
= {5, 5, 7, 7};
9677 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
9682 HRESULT colorfill_hr
, depthfill_hr
;
9687 DDPIXELFORMAT format
;
9692 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9693 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9695 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9696 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9700 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
9701 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9703 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9704 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9708 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
9709 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9711 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9712 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9716 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
9717 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9719 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9720 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9724 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
9725 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
9727 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9728 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9732 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
9733 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9734 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9737 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
9738 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
9739 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9742 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9743 * different afterwards. DX9+ GPUs set one of the two luminance values
9744 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9745 * value they set. r200 (dx8) just sets the entire block to the clear
9747 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9748 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9750 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9751 {0}, {0}, {0}, {0}, {0}
9755 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9756 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9758 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9759 {0}, {0}, {0}, {0}, {0}
9763 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
9764 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9766 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9767 {0}, {0}, {0}, {0}, {0}
9771 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
9772 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9774 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9775 {0}, {0}, {0}, {0}, {0}
9779 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
9780 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
9782 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9783 {0}, {0}, {0}, {0}, {0}
9787 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
9788 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
9790 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9791 {0}, {0}, {0}, {0}, {0}
9795 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
9796 * surface works, presumably because it is handled by the runtime instead of
9798 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9799 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
9801 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9802 {8}, {0}, {0}, {0}, {0}
9806 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
9807 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
9809 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9810 {8}, {0}, {0}, {0}, {0}
9822 {SRCCOPY
, "SRCCOPY", DD_OK
},
9823 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9824 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9825 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9826 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9827 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9828 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9829 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9830 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9831 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9832 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9833 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9834 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9835 {BLACKNESS
, "BLACKNESS", DD_OK
},
9836 {WHITENESS
, "WHITENESS", DD_OK
},
9837 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9840 window
= create_window();
9841 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9843 skip("Failed to create a 3D device, skipping test.\n");
9844 DestroyWindow(window
);
9848 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9849 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9850 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9851 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9853 memset(&z_fmt
, 0, sizeof(z_fmt
));
9854 IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
9856 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
9858 IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
9859 if (!(supported_fmts
& SUPPORT_DXT1
))
9860 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
9862 IDirect3D3_Release(d3d
);
9864 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9865 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9866 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
9867 num_fourcc_codes
* sizeof(*fourcc_codes
));
9870 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9871 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9872 for (i
= 0; i
< num_fourcc_codes
; i
++)
9874 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9875 supported_fmts
|= SUPPORT_YUY2
;
9876 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9877 supported_fmts
|= SUPPORT_UYVY
;
9879 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
9881 memset(&hal_caps
, 0, sizeof(hal_caps
));
9882 hal_caps
.dwSize
= sizeof(hal_caps
);
9883 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
9884 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9886 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9887 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9889 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9891 DWORD expected_broken
= tests
[i
].result
;
9893 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9894 memset(&fx
, 0, sizeof(fx
));
9895 fx
.dwSize
= sizeof(fx
);
9896 U5(fx
).dwFillColor
= 0xdeadbeef;
9898 memset(&surface_desc
, 0, sizeof(surface_desc
));
9899 surface_desc
.dwSize
= sizeof(surface_desc
);
9900 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9901 surface_desc
.dwWidth
= 64;
9902 surface_desc
.dwHeight
= 64;
9903 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
9904 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9905 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
9907 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
9909 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
9911 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
9913 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9916 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9921 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
9922 /* Some drivers seem to convert depth values incorrectly or not at
9923 * all. Affects at least AMD PALM, 8.17.10.1247. */
9924 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9929 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
9930 f
= ceilf(log2f(expected
+ 1.0f
));
9931 g
= (f
+ 1.0f
) / 2.0f
;
9933 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9934 expected_broken
*= 0x01010101;
9938 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9939 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9941 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9942 todo_wine_if (tests
[i
].format
.dwFourCC
)
9943 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9944 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9946 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9947 todo_wine_if (tests
[i
].format
.dwFourCC
)
9948 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9949 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9951 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9953 memset(&surface_desc
, 0, sizeof(surface_desc
));
9954 surface_desc
.dwSize
= sizeof(surface_desc
);
9955 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9956 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9957 color
= surface_desc
.lpSurface
;
9958 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9959 *color
, tests
[i
].result
, tests
[i
].name
);
9960 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9961 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9964 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9965 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9966 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9967 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9968 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9969 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9971 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9973 memset(&surface_desc
, 0, sizeof(surface_desc
));
9974 surface_desc
.dwSize
= sizeof(surface_desc
);
9975 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9976 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9977 color
= surface_desc
.lpSurface
;
9978 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
9979 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
9980 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9981 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
9982 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9983 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9986 U5(fx
).dwFillColor
= 0xdeadbeef;
9987 fx
.dwROP
= BLACKNESS
;
9988 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9989 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
9990 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9991 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
9992 U5(fx
).dwFillColor
, tests
[i
].name
);
9994 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9996 memset(&surface_desc
, 0, sizeof(surface_desc
));
9997 surface_desc
.dwSize
= sizeof(surface_desc
);
9998 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9999 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10000 color
= surface_desc
.lpSurface
;
10001 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
10002 *color
, tests
[i
].name
);
10003 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10004 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10007 fx
.dwROP
= WHITENESS
;
10008 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10009 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
10010 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10011 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
10012 U5(fx
).dwFillColor
, tests
[i
].name
);
10014 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10016 memset(&surface_desc
, 0, sizeof(surface_desc
));
10017 surface_desc
.dwSize
= sizeof(surface_desc
);
10018 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10019 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10020 color
= surface_desc
.lpSurface
;
10021 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
10022 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
10023 *color
, tests
[i
].name
);
10024 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10025 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10028 IDirectDrawSurface4_Release(surface
);
10031 memset(&fx
, 0, sizeof(fx
));
10032 fx
.dwSize
= sizeof(fx
);
10033 U5(fx
).dwFillColor
= 0xdeadbeef;
10034 fx
.dwROP
= WHITENESS
;
10036 memset(&surface_desc
, 0, sizeof(surface_desc
));
10037 surface_desc
.dwSize
= sizeof(surface_desc
);
10038 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10039 surface_desc
.dwWidth
= 64;
10040 surface_desc
.dwHeight
= 64;
10041 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10042 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10043 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10044 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10045 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10046 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10047 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10048 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10049 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10050 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10051 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10054 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
10055 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10056 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
10057 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10059 /* Unused source rectangle. */
10060 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10061 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10062 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10063 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10065 /* Unused source surface. */
10066 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10067 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10068 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10069 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10070 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10071 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10072 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10073 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10075 /* Inverted destination or source rectangle. */
10076 SetRect(&rect
, 5, 7, 7, 5);
10077 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10078 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10079 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10080 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10081 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10082 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10083 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10084 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10085 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10086 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10088 /* Negative rectangle. */
10089 SetRect(&rect
, -1, -1, 5, 5);
10090 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10091 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10092 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10093 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10094 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10095 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10096 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10097 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10098 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10099 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10101 /* Out of bounds rectangle. */
10102 SetRect(&rect
, 0, 0, 65, 65);
10103 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10104 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10105 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10106 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10108 /* Combine multiple flags. */
10109 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10110 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10111 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10112 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10113 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10114 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10116 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
10118 fx
.dwROP
= rops
[i
].rop
;
10119 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10120 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
10123 IDirectDrawSurface4_Release(surface2
);
10124 IDirectDrawSurface4_Release(surface
);
10129 memset(&surface_desc
, 0, sizeof(surface_desc
));
10130 surface_desc
.dwSize
= sizeof(surface_desc
);
10131 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10132 surface_desc
.dwWidth
= 64;
10133 surface_desc
.dwHeight
= 64;
10134 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
10135 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10136 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10137 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10138 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10139 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10142 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
10143 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10145 /* Unused source rectangle. */
10146 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10147 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10149 /* Unused source surface. */
10150 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10151 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10152 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10153 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10155 /* Inverted destination or source rectangle. */
10156 SetRect(&rect
, 5, 7, 7, 5);
10157 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10158 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10159 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10160 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10161 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10162 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10163 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10164 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10166 /* Negative rectangle. */
10167 SetRect(&rect
, -1, -1, 5, 5);
10168 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10169 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10170 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10171 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10172 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10173 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10174 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10175 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10177 /* Out of bounds rectangle. */
10178 SetRect(&rect
, 0, 0, 65, 65);
10179 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10180 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10182 /* Combine multiple flags. */
10183 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10184 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10186 IDirectDrawSurface4_Release(surface2
);
10187 IDirectDrawSurface4_Release(surface
);
10190 IDirectDraw4_Release(ddraw
);
10191 refcount
= IDirect3DDevice3_Release(device
);
10192 ok(!refcount
, "Device has %u references left.\n", refcount
);
10193 DestroyWindow(window
);
10196 static void test_texcoordindex(void)
10201 struct vec2 texcoord1
;
10202 struct vec2 texcoord2
;
10203 struct vec2 texcoord3
;
10207 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10208 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
10209 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10210 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
10212 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
10213 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10214 IDirect3DDevice3
*device
;
10216 IDirectDraw4
*ddraw
;
10217 IDirectDrawSurface4
*rt
;
10218 IDirect3DViewport3
*viewport
;
10221 IDirectDrawSurface4
*surface1
, *surface2
;
10222 IDirect3DTexture2
*texture1
, *texture2
;
10223 DDSURFACEDESC2 surface_desc
;
10228 window
= create_window();
10229 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10231 skip("Failed to create a 3D device, skipping test.\n");
10232 DestroyWindow(window
);
10236 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10237 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10238 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10239 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10240 IDirect3D3_Release(d3d
);
10242 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10243 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10245 memset(&surface_desc
, 0, sizeof(surface_desc
));
10246 surface_desc
.dwSize
= sizeof(surface_desc
);
10247 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10248 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10249 surface_desc
.dwWidth
= 2;
10250 surface_desc
.dwHeight
= 2;
10251 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10252 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10253 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10254 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10255 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10256 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10257 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10258 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
10259 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10260 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10261 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10263 memset(&surface_desc
, 0, sizeof(surface_desc
));
10264 surface_desc
.dwSize
= sizeof(surface_desc
);
10265 hr
= IDirectDrawSurface4_Lock(surface1
, 0, &surface_desc
, 0, NULL
);
10266 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10267 ptr
= surface_desc
.lpSurface
;
10268 ptr
[0] = 0xff000000;
10269 ptr
[1] = 0xff00ff00;
10270 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10271 ptr
[0] = 0xff0000ff;
10272 ptr
[1] = 0xff00ffff;
10273 hr
= IDirectDrawSurface4_Unlock(surface1
, NULL
);
10274 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10276 memset(&surface_desc
, 0, sizeof(surface_desc
));
10277 surface_desc
.dwSize
= sizeof(surface_desc
);
10278 hr
= IDirectDrawSurface4_Lock(surface2
, 0, &surface_desc
, 0, NULL
);
10279 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10280 ptr
= surface_desc
.lpSurface
;
10281 ptr
[0] = 0xff000000;
10282 ptr
[1] = 0xff0000ff;
10283 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10284 ptr
[0] = 0xffff0000;
10285 ptr
[1] = 0xffff00ff;
10286 hr
= IDirectDrawSurface4_Unlock(surface2
, 0);
10287 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10289 viewport
= create_viewport(device
, 0, 0, 640, 480);
10290 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10291 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
10293 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirect3DTexture2
, (void **)&texture1
);
10294 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10295 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirect3DTexture2
, (void **)&texture2
);
10296 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10297 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture1
);
10298 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10299 hr
= IDirect3DDevice3_SetTexture(device
, 1, texture2
);
10300 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10301 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10302 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10303 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10304 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10305 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10306 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10307 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
10308 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10309 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10310 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10311 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
10312 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10313 hr
= IDirect3DDevice3_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
10314 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10316 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
10317 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10318 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
10319 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10321 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10322 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10324 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10325 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10327 hr
= IDirect3DDevice3_BeginScene(device
);
10328 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10329 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10330 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10331 hr
= IDirect3DDevice3_EndScene(device
);
10332 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10334 color
= get_surface_color(rt
, 160, 120);
10335 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10336 color
= get_surface_color(rt
, 480, 120);
10337 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10338 color
= get_surface_color(rt
, 160, 360);
10339 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
10340 color
= get_surface_color(rt
, 480, 360);
10341 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
10343 /* D3DTSS_TEXTURETRANSFORMFLAGS was introduced in D3D7, can't test it here. */
10345 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
10346 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10348 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10349 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10351 hr
= IDirect3DDevice3_BeginScene(device
);
10352 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10353 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10354 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10355 hr
= IDirect3DDevice3_EndScene(device
);
10356 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10358 color
= get_surface_color(rt
, 160, 120);
10359 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10360 color
= get_surface_color(rt
, 480, 120);
10361 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10362 color
= get_surface_color(rt
, 160, 360);
10363 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
10364 color
= get_surface_color(rt
, 480, 360);
10365 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
10367 IDirect3DTexture2_Release(texture2
);
10368 IDirect3DTexture2_Release(texture1
);
10369 IDirectDrawSurface4_Release(surface2
);
10370 IDirectDrawSurface4_Release(surface1
);
10372 destroy_viewport(device
, viewport
);
10374 IDirectDrawSurface4_Release(rt
);
10375 IDirectDraw_Release(ddraw
);
10376 refcount
= IDirect3DDevice3_Release(device
);
10377 ok(!refcount
, "Device has %u references left.\n", refcount
);
10378 DestroyWindow(window
);
10381 static void test_colorkey_precision(void)
10386 struct vec2 texcoord
;
10390 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10391 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
10392 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10393 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
10395 IDirect3DDevice3
*device
;
10397 IDirectDraw4
*ddraw
;
10398 IDirectDrawSurface4
*rt
;
10399 IDirect3DViewport3
*viewport
;
10402 IDirectDrawSurface4
*src
, *dst
, *texture
;
10403 IDirect3DTexture2
*d3d_texture
;
10404 DDSURFACEDESC2 surface_desc
, lock_desc
;
10410 DWORD data
[4] = {0}, color_mask
;
10411 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10412 BOOL is_nvidia
, is_warp
;
10413 static const struct
10415 unsigned int max
, shift
, bpp
, clear
;
10423 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10425 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10426 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10431 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10433 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10434 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10439 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10441 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10442 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10447 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10449 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10450 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10455 window
= create_window();
10456 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10458 skip("Failed to create a 3D device, skipping test.\n");
10459 DestroyWindow(window
);
10463 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10464 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10465 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10466 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10467 IDirect3D3_Release(d3d
);
10468 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10469 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10471 is_nvidia
= ddraw_is_nvidia(ddraw
);
10472 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10473 * (color key doesn't match although the values are equal), and a false
10474 * positive when the color key is 0 and the texture contains the value 1.
10475 * I don't want to mark this broken unconditionally since this would
10476 * essentially disable the test on Windows. Also on random occasions
10477 * 254 == 255 and 255 != 255.*/
10478 is_warp
= ddraw_is_warp(ddraw
);
10480 viewport
= create_viewport(device
, 0, 0, 640, 480);
10481 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10482 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
10484 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10485 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
10486 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10487 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10488 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
10489 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
10490 /* Multiply the texture read result with 0, that way the result color if the key doesn't
10491 * match is constant. In theory color keying works without reading the texture result
10492 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
10494 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
10495 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10496 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10497 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10498 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
10499 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10500 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
10501 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10503 memset(&fx
, 0, sizeof(fx
));
10504 fx
.dwSize
= sizeof(fx
);
10505 memset(&lock_desc
, 0, sizeof(lock_desc
));
10506 lock_desc
.dwSize
= sizeof(lock_desc
);
10508 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
10510 if (is_nvidia
&& tests
[t
].skip_nv
)
10512 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
10516 memset(&surface_desc
, 0, sizeof(surface_desc
));
10517 surface_desc
.dwSize
= sizeof(surface_desc
);
10518 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10519 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10520 surface_desc
.dwWidth
= 4;
10521 surface_desc
.dwHeight
= 1;
10522 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
10523 /* Windows XP (at least with the r200 driver, other drivers untested) produces
10524 * garbage when doing color keyed texture->texture blits. */
10525 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
10526 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10527 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
10528 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10530 U5(fx
).dwFillColor
= tests
[t
].clear
;
10531 /* On the w8 testbot (WARP driver) the blit result has different values in the
10533 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
10534 | U3(tests
[t
].fmt
).dwGBitMask
10535 | U4(tests
[t
].fmt
).dwBBitMask
;
10537 for (c
= 0; c
<= tests
[t
].max
; ++c
)
10539 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
10540 * texture after it has been set once... */
10541 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
10542 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10543 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10544 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10545 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
10546 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10547 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
10548 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10549 hr
= IDirect3DDevice3_SetTexture(device
, 0, d3d_texture
);
10550 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10552 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10553 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
10555 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10556 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10557 switch (tests
[t
].bpp
)
10560 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10561 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10562 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10563 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
10567 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10568 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10569 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10570 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
10573 hr
= IDirectDrawSurface4_Unlock(src
, 0);
10574 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10575 hr
= IDirectDrawSurface4_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
10576 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10578 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10579 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10580 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
10581 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10583 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
10584 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10586 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
10587 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10588 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10589 switch (tests
[t
].bpp
)
10592 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10593 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10594 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10595 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10599 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10600 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10601 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10602 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10605 hr
= IDirectDrawSurface4_Unlock(dst
, 0);
10606 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10610 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10611 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
10613 if (data
[3] == tests
[t
].clear
)
10615 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
10616 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
10617 * even when a different surface is used. The blit itself doesn't draw anything,
10618 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
10619 * never be masked out by the key.
10621 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
10622 * test is disabled entirely.
10624 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
10625 * terrible on WARP. */
10626 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
10627 IDirect3DTexture2_Release(d3d_texture
);
10628 IDirectDrawSurface4_Release(texture
);
10629 IDirectDrawSurface4_Release(src
);
10630 IDirectDrawSurface4_Release(dst
);
10635 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10636 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
10638 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10639 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
10641 if (c
== tests
[t
].max
)
10642 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10643 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
10645 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10646 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
10648 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
10649 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10651 hr
= IDirect3DDevice3_BeginScene(device
);
10652 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10653 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
10654 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10655 hr
= IDirect3DDevice3_EndScene(device
);
10656 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10658 color
= get_surface_color(rt
, 80, 240);
10660 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10661 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10662 color
, tests
[t
].name
, c
);
10664 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10665 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10666 color
, tests
[t
].name
, c
);
10668 color
= get_surface_color(rt
, 240, 240);
10669 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10670 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10671 color
, tests
[t
].name
, c
);
10673 color
= get_surface_color(rt
, 400, 240);
10674 if (c
== tests
[t
].max
)
10675 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10676 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10677 color
, tests
[t
].name
, c
);
10679 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10680 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10681 color
, tests
[t
].name
, c
);
10683 IDirect3DTexture2_Release(d3d_texture
);
10684 IDirectDrawSurface4_Release(texture
);
10686 IDirectDrawSurface4_Release(src
);
10687 IDirectDrawSurface4_Release(dst
);
10691 destroy_viewport(device
, viewport
);
10692 IDirectDrawSurface4_Release(rt
);
10693 IDirectDraw4_Release(ddraw
);
10694 refcount
= IDirect3DDevice3_Release(device
);
10695 ok(!refcount
, "Device has %u references left.\n", refcount
);
10696 DestroyWindow(window
);
10699 static void test_range_colorkey(void)
10701 IDirectDraw4
*ddraw
;
10704 IDirectDrawSurface4
*surface
;
10705 DDSURFACEDESC2 surface_desc
;
10709 window
= create_window();
10710 ddraw
= create_ddraw();
10711 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10712 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10713 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10715 memset(&surface_desc
, 0, sizeof(surface_desc
));
10716 surface_desc
.dwSize
= sizeof(surface_desc
);
10717 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
10718 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10719 surface_desc
.dwWidth
= 1;
10720 surface_desc
.dwHeight
= 1;
10721 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10722 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10723 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10724 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10725 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10726 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
10728 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
10729 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10730 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10731 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10732 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10734 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10735 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10736 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10737 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10739 /* Same for DDSCAPS_OFFSCREENPLAIN. */
10740 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10741 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10742 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10743 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10744 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10746 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10747 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10748 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10749 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10751 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10752 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10753 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10754 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10756 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
10757 ckey
.dwColorSpaceLowValue
= 0x00000000;
10758 ckey
.dwColorSpaceHighValue
= 0x00000001;
10759 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10760 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10762 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10763 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10764 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10765 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10767 ckey
.dwColorSpaceLowValue
= 0x00000001;
10768 ckey
.dwColorSpaceHighValue
= 0x00000000;
10769 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10770 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10772 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10773 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10774 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10775 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10777 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
10778 ckey
.dwColorSpaceLowValue
= 0x00000000;
10779 ckey
.dwColorSpaceHighValue
= 0x00000000;
10780 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10781 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10783 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
10784 ckey
.dwColorSpaceLowValue
= 0x00000001;
10785 ckey
.dwColorSpaceHighValue
= 0x00000000;
10786 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10787 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10788 ckey
.dwColorSpaceLowValue
= 0x00000000;
10789 ckey
.dwColorSpaceHighValue
= 0x00000001;
10790 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10791 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10792 /* Range destination keys don't work either. */
10793 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
10794 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10796 /* Just to show it's not because of A, R, and G having equal values. */
10797 ckey
.dwColorSpaceLowValue
= 0x00000000;
10798 ckey
.dwColorSpaceHighValue
= 0x01010101;
10799 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10800 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10802 /* None of these operations modified the key. */
10803 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10804 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10805 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10806 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10808 IDirectDrawSurface4_Release(surface
),
10809 refcount
= IDirectDraw4_Release(ddraw
);
10810 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10811 DestroyWindow(window
);
10814 static void test_shademode(void)
10816 IDirect3DVertexBuffer
*vb_strip
, *vb_list
, *buffer
;
10817 IDirect3DViewport3
*viewport
;
10818 IDirect3DDevice3
*device
;
10819 D3DVERTEXBUFFERDESC desc
;
10820 IDirectDrawSurface4
*rt
;
10821 DWORD color0
, color1
;
10828 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10829 static const struct
10831 struct vec3 position
;
10836 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10837 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10838 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10839 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
10843 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10844 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10845 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10847 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10848 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10849 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
10851 static const struct
10855 DWORD color0
, color1
;
10859 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
10860 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10861 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10862 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10863 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
10864 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10867 window
= create_window();
10868 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10870 skip("Failed to create a 3D device, skipping test.\n");
10871 DestroyWindow(window
);
10875 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10876 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
10877 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10878 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10880 viewport
= create_viewport(device
, 0, 0, 640, 480);
10881 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10882 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10884 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10885 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
10887 memset(&desc
, 0, sizeof(desc
));
10888 desc
.dwSize
= sizeof(desc
);
10889 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
10890 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
10891 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
10892 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0, NULL
);
10893 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
10894 hr
= IDirect3DVertexBuffer_Lock(vb_strip
, 0, &data
, NULL
);
10895 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
10896 memcpy(data
, quad_strip
, sizeof(quad_strip
));
10897 hr
= IDirect3DVertexBuffer_Unlock(vb_strip
);
10898 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10900 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
10901 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0, NULL
);
10902 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
10903 hr
= IDirect3DVertexBuffer_Lock(vb_list
, 0, &data
, NULL
);
10904 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
10905 memcpy(data
, quad_list
, sizeof(quad_list
));
10906 hr
= IDirect3DVertexBuffer_Unlock(vb_list
);
10907 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10909 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10910 * the color fixups we have to do for FLAT shading will be dependent on that. */
10912 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10914 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
10915 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10917 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10918 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
10920 hr
= IDirect3DDevice3_BeginScene(device
);
10921 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10922 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
10923 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
10924 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
10925 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10926 hr
= IDirect3DDevice3_EndScene(device
);
10927 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10929 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10930 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10932 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10933 * each triangle. This requires EXT_provoking_vertex or similar
10934 * functionality being available. */
10935 /* PHONG should be the same as GOURAUD, since no hardware implements
10937 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10938 i
, color0
, tests
[i
].color0
);
10939 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10940 i
, color1
, tests
[i
].color1
);
10943 IDirect3DVertexBuffer_Release(vb_strip
);
10944 IDirect3DVertexBuffer_Release(vb_list
);
10945 destroy_viewport(device
, viewport
);
10946 IDirectDrawSurface4_Release(rt
);
10947 IDirect3D3_Release(d3d
);
10948 refcount
= IDirect3DDevice3_Release(device
);
10949 ok(!refcount
, "Device has %u references left.\n", refcount
);
10950 DestroyWindow(window
);
10953 static void test_lockrect_invalid(void)
10956 IDirectDraw4
*ddraw
;
10957 IDirectDrawSurface4
*surface
;
10960 DDSURFACEDESC2 surface_desc
;
10962 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10963 static RECT valid
[] =
10968 {120, 60, 128, 68},
10969 {60, 120, 68, 128},
10971 static RECT invalid
[] =
10973 {68, 60, 60, 68}, /* left > right */
10974 {60, 68, 68, 60}, /* top > bottom */
10975 {-8, 60, 0, 68}, /* left < surface */
10976 {60, -8, 68, 0}, /* top < surface */
10977 {-16, 60, -8, 68}, /* right < surface */
10978 {60, -16, 68, -8}, /* bottom < surface */
10979 {60, 60, 136, 68}, /* right > surface */
10980 {60, 60, 68, 136}, /* bottom > surface */
10981 {136, 60, 144, 68}, /* left > surface */
10982 {60, 136, 68, 144}, /* top > surface */
10984 static const struct
10992 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10993 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10994 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", DDERR_INVALIDPARAMS
},
10995 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", DDERR_INVALIDPARAMS
},
10996 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", DDERR_INVALIDPARAMS
},
10999 window
= create_window();
11000 ddraw
= create_ddraw();
11001 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11002 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11003 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11005 memset(&hal_caps
, 0, sizeof(hal_caps
));
11006 hal_caps
.dwSize
= sizeof(hal_caps
);
11007 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
11008 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
11009 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
11010 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
11012 skip("Required surface types not supported, skipping test.\n");
11016 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
11018 memset(&surface_desc
, 0, sizeof(surface_desc
));
11019 surface_desc
.dwSize
= sizeof(surface_desc
);
11020 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11021 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
11022 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
11023 surface_desc
.dwWidth
= 128;
11024 surface_desc
.dwHeight
= 128;
11025 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11026 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11027 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11028 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
11029 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
11030 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
11032 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11033 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11035 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
11036 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
11038 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
11040 RECT
*rect
= &valid
[i
];
11042 memset(&surface_desc
, 0, sizeof(surface_desc
));
11043 surface_desc
.dwSize
= sizeof(surface_desc
);
11045 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11046 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
11047 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11049 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11050 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11053 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
11055 RECT
*rect
= &invalid
[i
];
11057 memset(&surface_desc
, 1, sizeof(surface_desc
));
11058 surface_desc
.dwSize
= sizeof(surface_desc
);
11060 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11061 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
11062 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11065 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11066 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11069 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
11072 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11073 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
11074 hr
, resources
[r
].name
);
11075 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11076 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
11077 hr
, resources
[r
].name
);
11078 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11079 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11081 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11082 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
11083 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11084 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
11085 wine_dbgstr_rect(&valid
[0]), hr
);
11087 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
11088 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
11090 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11091 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11093 IDirectDrawSurface4_Release(surface
);
11097 IDirectDraw4_Release(ddraw
);
11098 DestroyWindow(window
);
11101 static void test_yv12_overlay(void)
11103 IDirectDrawSurface4
*src_surface
, *dst_surface
;
11104 RECT rect
= {13, 17, 14, 18};
11105 unsigned int offset
, y
;
11106 DDSURFACEDESC2 desc
;
11107 unsigned char *base
;
11108 IDirectDraw4
*ddraw
;
11112 window
= create_window();
11113 ddraw
= create_ddraw();
11114 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11115 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11116 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11118 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11120 skip("Failed to create a YV12 overlay, skipping test.\n");
11124 memset(&desc
, 0, sizeof(desc
));
11125 desc
.dwSize
= sizeof(desc
);
11126 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11127 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11129 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
11130 "Got unexpected flags %#x.\n", desc
.dwFlags
);
11131 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
11132 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
11133 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
11134 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
11135 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
11136 /* The overlay pitch seems to have 256 byte alignment. */
11137 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
11139 /* Fill the surface with some data for the blit test. */
11140 base
= desc
.lpSurface
;
11142 for (y
= 0; y
< desc
.dwHeight
; ++y
)
11144 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
11147 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
11149 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
11152 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
11154 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
11157 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11158 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11160 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
11161 * other block-based formats like DXT the entire Y channel is stored in
11162 * one big chunk of memory, followed by the chroma channels. So partial
11163 * locks do not really make sense. Show that they are allowed nevertheless
11164 * and the offset points into the luminance data. */
11165 hr
= IDirectDrawSurface4_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
11166 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11167 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
11168 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
11169 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
11170 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11171 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11173 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11175 /* Windows XP with a Radeon X1600 GPU refuses to create a second
11176 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
11177 skip("Failed to create a second YV12 surface, skipping blit test.\n");
11178 IDirectDrawSurface4_Release(src_surface
);
11182 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
11183 /* VMware rejects YV12 blits. This behavior has not been seen on real
11184 * hardware yet, so mark it broken. */
11185 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
11189 memset(&desc
, 0, sizeof(desc
));
11190 desc
.dwSize
= sizeof(desc
);
11191 hr
= IDirectDrawSurface4_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11192 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11194 base
= desc
.lpSurface
;
11195 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
11196 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
11197 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
11198 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
11199 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
11201 hr
= IDirectDrawSurface4_Unlock(dst_surface
, NULL
);
11202 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11205 IDirectDrawSurface4_Release(dst_surface
);
11206 IDirectDrawSurface4_Release(src_surface
);
11208 IDirectDraw4_Release(ddraw
);
11209 DestroyWindow(window
);
11212 static BOOL
dwm_enabled(void)
11216 if (!strcmp(winetest_platform
, "wine"))
11218 if (!pDwmIsCompositionEnabled
)
11220 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
11225 static void test_offscreen_overlay(void)
11227 IDirectDrawSurface4
*overlay
, *offscreen
, *primary
;
11228 DDSURFACEDESC2 surface_desc
;
11229 IDirectDraw4
*ddraw
;
11234 window
= create_window();
11235 ddraw
= create_ddraw();
11236 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11237 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11238 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11240 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11242 skip("Failed to create a UYVY overlay, skipping test.\n");
11246 memset(&surface_desc
, 0, sizeof(surface_desc
));
11247 surface_desc
.dwSize
= sizeof(surface_desc
);
11248 surface_desc
.dwFlags
= DDSD_CAPS
;
11249 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11250 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11251 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11253 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11254 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11255 * surface prevents this by disabling the dwm. */
11256 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11257 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11258 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11259 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11261 /* Try to overlay a NULL surface. */
11262 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
11263 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11264 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
11265 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11267 /* Try to overlay an offscreen surface. */
11268 memset(&surface_desc
, 0, sizeof(surface_desc
));
11269 surface_desc
.dwSize
= sizeof(surface_desc
);
11270 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11271 surface_desc
.dwWidth
= 64;
11272 surface_desc
.dwHeight
= 64;
11273 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11274 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11275 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11276 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
11277 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
11278 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
11279 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
11280 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
11281 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11282 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11284 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
11285 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
11286 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
11287 "Failed to update overlay, hr %#x.\n", hr
);
11289 /* Try to overlay the primary with a non-overlay surface. */
11290 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11291 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11292 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11293 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11295 IDirectDrawSurface4_Release(offscreen
);
11296 IDirectDrawSurface4_Release(primary
);
11297 IDirectDrawSurface4_Release(overlay
);
11299 IDirectDraw4_Release(ddraw
);
11300 DestroyWindow(window
);
11303 static void test_overlay_rect(void)
11305 IDirectDrawSurface4
*overlay
, *primary
= NULL
;
11306 DDSURFACEDESC2 surface_desc
;
11307 RECT rect
= {0, 0, 64, 64};
11308 IDirectDraw4
*ddraw
;
11314 window
= create_window();
11315 ddraw
= create_ddraw();
11316 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11317 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11318 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11320 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11322 skip("Failed to create a UYVY overlay, skipping test.\n");
11326 memset(&surface_desc
, 0, sizeof(surface_desc
));
11327 surface_desc
.dwSize
= sizeof(surface_desc
);
11328 surface_desc
.dwFlags
= DDSD_CAPS
;
11329 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11330 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11331 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11333 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11334 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11335 * surface prevents this by disabling the dwm. */
11336 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11337 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11338 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11339 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11341 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
11344 win_skip("Cannot disable DWM, skipping overlay test.\n");
11348 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
11349 * used. This is not true in Windows Vista and earlier, but changed in
11351 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11352 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11353 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11354 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11355 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11356 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11358 /* Show that the overlay position is the (top, left) coordinate of the
11359 * destination rectangle. */
11360 OffsetRect(&rect
, 32, 16);
11361 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11362 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11363 pos_x
= -1; pos_y
= -1;
11364 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11365 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11366 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
11367 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
11369 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
11370 * seen that the overlay overlays the whole primary(==screen). */
11371 hr2
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
11372 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
11373 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11374 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11375 if (SUCCEEDED(hr2
))
11377 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11378 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11382 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
11383 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
11386 /* The position cannot be retrieved when the overlay is not shown. */
11387 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
11388 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11389 pos_x
= -1; pos_y
= -1;
11390 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11391 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
11392 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11393 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11395 IDirectDrawSurface4_Release(overlay
);
11398 IDirectDrawSurface4_Release(primary
);
11399 IDirectDraw4_Release(ddraw
);
11400 DestroyWindow(window
);
11403 static void test_blt(void)
11405 IDirectDrawSurface4
*surface
, *rt
;
11406 DDSURFACEDESC2 surface_desc
;
11407 IDirect3DDevice3
*device
;
11408 IDirectDraw4
*ddraw
;
11423 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
11424 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
11425 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11426 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11427 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11428 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11429 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11430 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11431 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11432 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11435 window
= create_window();
11436 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11438 skip("Failed to create a 3D device, skipping test.\n");
11439 DestroyWindow(window
);
11443 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11444 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
11445 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
11446 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
11447 IDirect3D3_Release(d3d
);
11448 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11449 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11451 memset(&surface_desc
, 0, sizeof(surface_desc
));
11452 surface_desc
.dwSize
= sizeof(surface_desc
);
11453 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11454 surface_desc
.dwWidth
= 640;
11455 surface_desc
.dwHeight
= 480;
11456 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11457 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11458 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11460 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11461 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11463 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11464 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11466 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11468 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11469 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11470 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11472 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11473 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11474 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11476 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11477 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11478 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11480 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
11481 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11484 IDirectDrawSurface4_Release(surface
);
11485 IDirectDrawSurface4_Release(rt
);
11486 IDirectDraw4_Release(ddraw
);
11487 refcount
= IDirect3DDevice3_Release(device
);
11488 ok(!refcount
, "Device has %u references left.\n", refcount
);
11489 DestroyWindow(window
);
11492 static void test_blt_z_alpha(void)
11494 DWORD blt_flags
[] =
11498 DDBLT_ALPHADESTCONSTOVERRIDE
,
11499 DDBLT_ALPHADESTNEG
,
11500 DDBLT_ALPHADESTSURFACEOVERRIDE
,
11501 DDBLT_ALPHAEDGEBLEND
,
11504 DDBLT_ALPHASRCCONSTOVERRIDE
,
11506 DDBLT_ALPHASRCSURFACEOVERRIDE
,
11509 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
11510 DDBLT_ZBUFFERDESTOVERRIDE
,
11511 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
11512 DDBLT_ZBUFFERSRCOVERRIDE
,
11514 IDirectDrawSurface4
*src_surface
, *dst_surface
;
11515 DDSURFACEDESC2 surface_desc
;
11516 IDirectDraw4
*ddraw
;
11525 window
= create_window();
11526 ddraw
= create_ddraw();
11527 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11528 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11529 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11531 memset(&pf
, 0, sizeof(pf
));
11532 pf
.dwSize
= sizeof(pf
);
11533 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11534 U1(pf
).dwRGBBitCount
= 32;
11535 U2(pf
).dwRBitMask
= 0x00ff0000;
11536 U3(pf
).dwGBitMask
= 0x0000ff00;
11537 U4(pf
).dwBBitMask
= 0x000000ff;
11538 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
11540 memset(&surface_desc
, 0, sizeof(surface_desc
));
11541 surface_desc
.dwSize
= sizeof(surface_desc
);
11542 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11543 surface_desc
.dwWidth
= 64;
11544 surface_desc
.dwHeight
= 64;
11545 U4(surface_desc
).ddpfPixelFormat
= pf
;
11546 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11548 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11549 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
11550 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11551 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
11553 memset(&fx
, 0, sizeof(fx
));
11554 fx
.dwSize
= sizeof(fx
);
11555 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
11556 fx
.dwZDestConstBitDepth
= 32;
11557 U1(fx
).dwZDestConst
= 0x11111111;
11558 fx
.dwZSrcConstBitDepth
= 32;
11559 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
11560 fx
.dwAlphaEdgeBlendBitDepth
= 8;
11561 fx
.dwAlphaEdgeBlend
= 0x7f;
11562 fx
.dwAlphaDestConstBitDepth
= 8;
11563 U3(fx
).dwAlphaDestConst
= 0xdd;
11564 fx
.dwAlphaSrcConstBitDepth
= 8;
11565 U4(fx
).dwAlphaSrcConst
= 0x22;
11567 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
11569 fx
.dwFillColor
= 0x3300ff00;
11570 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11571 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11573 fx
.dwFillColor
= 0xccff0000;
11574 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11575 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11577 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
11578 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11580 color
= get_surface_color(dst_surface
, 32, 32);
11581 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
11584 IDirectDrawSurface4_Release(dst_surface
);
11585 IDirectDrawSurface4_Release(src_surface
);
11586 refcount
= IDirectDraw4_Release(ddraw
);
11587 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
11588 DestroyWindow(window
);
11591 static void test_color_clamping(void)
11593 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11594 static D3DMATRIX mat
=
11596 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11597 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11598 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11599 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11601 static struct vec3 quad
[] =
11603 {-1.0f
, -1.0f
, 0.1f
},
11604 {-1.0f
, 1.0f
, 0.1f
},
11605 { 1.0f
, -1.0f
, 0.1f
},
11606 { 1.0f
, 1.0f
, 0.1f
},
11608 IDirect3DViewport3
*viewport
;
11609 IDirect3DDevice3
*device
;
11610 IDirectDrawSurface4
*rt
;
11616 window
= create_window();
11617 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11619 skip("Failed to create a 3D device, skipping test.\n");
11620 DestroyWindow(window
);
11624 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11625 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11627 viewport
= create_viewport(device
, 0, 0, 640, 480);
11628 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
11629 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11631 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
11632 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11633 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
11634 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
11635 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
11636 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
11637 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
11638 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
11639 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
11640 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
11641 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
11642 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
11643 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
11644 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
11645 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
11646 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
11647 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
11648 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
11650 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
11651 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
11652 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
11653 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11654 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
11655 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11656 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
11657 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11658 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
11659 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11660 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
11661 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11662 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
11663 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11665 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
11666 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
11668 hr
= IDirect3DDevice3_BeginScene(device
);
11669 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11671 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
11672 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11674 hr
= IDirect3DDevice3_EndScene(device
);
11675 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11677 color
= get_surface_color(rt
, 320, 240);
11678 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
11680 destroy_viewport(device
, viewport
);
11681 IDirectDrawSurface4_Release(rt
);
11682 refcount
= IDirect3DDevice3_Release(device
);
11683 ok(!refcount
, "Device has %u references left.\n", refcount
);
11684 DestroyWindow(window
);
11687 static void test_getdc(void)
11689 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
11690 IDirectDrawSurface4
*surface
, *surface2
, *tmp
;
11691 DDSURFACEDESC2 surface_desc
, map_desc
;
11692 IDirectDraw4
*ddraw
;
11698 static const struct
11701 DDPIXELFORMAT format
;
11702 BOOL getdc_supported
;
11703 HRESULT alt_result
;
11707 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11708 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
11709 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11710 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
11711 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11712 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11713 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11714 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11715 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11716 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
11717 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11718 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11719 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11720 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11721 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11722 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
11723 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11724 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11725 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11726 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11727 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
11728 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
11729 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
11730 * This is not implemented in wine yet, so disable the test for now.
11731 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
11732 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
11733 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
11735 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
11736 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11737 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
11738 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
11739 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
11740 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11741 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
11742 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11743 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
11744 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11745 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
11746 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11747 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
11748 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11751 window
= create_window();
11752 ddraw
= create_ddraw();
11753 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11754 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11755 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11757 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11759 memset(&surface_desc
, 0, sizeof(surface_desc
));
11760 surface_desc
.dwSize
= sizeof(surface_desc
);
11761 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11762 surface_desc
.dwWidth
= 64;
11763 surface_desc
.dwHeight
= 64;
11764 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
11765 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11767 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11769 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11770 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
11771 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11773 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
11778 dc
= (void *)0x1234;
11779 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11780 if (test_data
[i
].getdc_supported
)
11781 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
11782 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11784 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11788 unsigned int width_bytes
;
11794 type
= GetObjectType(dc
);
11795 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11796 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
11797 type
= GetObjectType(bitmap
);
11798 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11800 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
11801 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
11802 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
11803 dib
.dsBm
.bmType
, test_data
[i
].name
);
11804 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11805 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
11806 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11807 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
11808 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
11809 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
11810 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
11811 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
11812 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
11813 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
11814 "Got unexpected bit count %d for format %s.\n",
11815 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
11816 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
11817 dib
.dsBm
.bmBits
, test_data
[i
].name
);
11819 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
11820 dib
.dsBmih
.biSize
, test_data
[i
].name
);
11821 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11822 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11823 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11824 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11825 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
11826 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
11827 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
11828 "Got unexpected bit count %u for format %s.\n",
11829 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
11830 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
11831 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
11832 "Got unexpected compression %#x for format %s.\n",
11833 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
11834 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
11835 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
11836 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
11837 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
11838 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
11839 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
11840 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
11841 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
11842 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
11843 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
11845 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11847 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
11848 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
11849 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
11850 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11851 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11852 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11856 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11857 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11858 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11860 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11861 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11863 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11864 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11868 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11871 IDirectDrawSurface4_Release(surface
);
11876 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11877 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
11878 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11880 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
11881 test_data
[i
].name
, hr
);
11885 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
11886 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11887 hr
= IDirectDrawSurface4_GetAttachedSurface(tmp
, &caps
, &surface2
);
11888 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11889 IDirectDrawSurface4_Release(tmp
);
11891 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11892 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11893 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11894 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11895 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11896 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11897 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11898 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11900 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11901 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11902 dc2
= (void *)0x1234;
11903 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
11904 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11905 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11906 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11907 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11908 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11909 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11911 map_desc
.dwSize
= sizeof(map_desc
);
11912 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11913 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11914 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11915 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11916 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11917 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11918 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11919 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11921 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11922 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11923 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11924 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11925 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11926 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11928 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11929 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11930 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11931 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11932 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11933 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11934 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11935 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11937 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11938 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11939 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc2
);
11940 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11941 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc2
);
11942 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11943 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11944 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11946 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11947 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11948 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
11949 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11950 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc2
);
11951 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11952 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11953 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11955 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11956 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11957 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11958 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11959 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11960 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11961 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11962 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11964 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11965 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11966 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11967 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11968 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11969 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11970 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11971 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11973 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11974 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11975 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11976 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11977 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11978 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11979 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11980 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11982 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11983 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11984 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11985 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11986 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11987 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11988 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11989 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11991 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11992 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11993 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11994 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11995 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11996 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11997 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11998 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12000 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12001 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12002 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
12003 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12004 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12005 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12006 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
12007 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12008 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12009 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12011 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12012 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12013 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12014 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12015 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12016 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12017 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12018 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12019 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12020 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12022 IDirectDrawSurface4_Release(surface2
);
12023 IDirectDrawSurface4_Release(surface
);
12026 IDirectDraw4_Release(ddraw
);
12027 DestroyWindow(window
);
12030 static void test_draw_primitive(void)
12032 static WORD indices
[] = {0, 1, 2, 3};
12033 static struct vec3 quad
[] =
12035 {-1.0f
, -1.0f
, 0.0f
},
12036 {-1.0f
, 1.0f
, 0.0f
},
12037 { 1.0f
, -1.0f
, 0.0f
},
12038 { 1.0f
, 1.0f
, 0.0f
},
12040 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
12041 IDirect3DViewport3
*viewport
;
12042 D3DVERTEXBUFFERDESC vb_desc
;
12043 IDirect3DVertexBuffer
*vb
;
12044 IDirect3DDevice3
*device
;
12051 window
= create_window();
12052 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12054 skip("Failed to create a 3D device, skipping test.\n");
12055 DestroyWindow(window
);
12059 viewport
= create_viewport(device
, 0, 0, 640, 480);
12060 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12061 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12063 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12064 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12066 memset(&vb_desc
, 0, sizeof(vb_desc
));
12067 vb_desc
.dwSize
= sizeof(vb_desc
);
12068 vb_desc
.dwFVF
= D3DFVF_XYZ
;
12069 vb_desc
.dwNumVertices
= 4;
12070 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
12071 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
12073 IDirect3D3_Release(d3d
);
12075 memset(&strided
, 0, sizeof(strided
));
12077 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
12078 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12079 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12080 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
12081 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12082 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12083 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12084 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
12085 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12086 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
12087 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12088 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
12089 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12091 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
12092 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12093 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12094 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
12095 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12096 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12097 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12099 strided
.position
.lpvData
= quad
;
12100 strided
.position
.dwStride
= sizeof(*quad
);
12101 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, &data
, NULL
);
12102 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
12103 memcpy(data
, quad
, sizeof(quad
));
12104 hr
= IDirect3DVertexBuffer_Unlock(vb
);
12105 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12107 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
12108 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12109 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12110 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
12111 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12112 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12113 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12114 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
12115 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12116 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
12117 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12118 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
12119 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12120 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
12121 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12122 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12123 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
12124 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12125 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12126 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12128 IDirect3DVertexBuffer_Release(vb
);
12129 destroy_viewport(device
, viewport
);
12130 refcount
= IDirect3DDevice3_Release(device
);
12131 ok(!refcount
, "Device has %u references left.\n", refcount
);
12132 DestroyWindow(window
);
12135 static void test_edge_antialiasing_blending(void)
12137 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12138 IDirectDrawSurface4
*offscreen
, *ds
;
12139 D3DDEVICEDESC hal_desc
, hel_desc
;
12140 IDirect3DViewport3
*viewport
;
12141 DDSURFACEDESC2 surface_desc
;
12142 IDirect3DDevice3
*device
;
12143 IDirectDraw4
*ddraw
;
12150 static D3DMATRIX mat
=
12152 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12153 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12154 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12155 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12159 struct vec3 position
;
12164 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12165 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12166 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12167 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12171 struct vec3 position
;
12176 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12177 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12178 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12179 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12182 window
= create_window();
12183 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12185 skip("Failed to create a 3D device.\n");
12186 DestroyWindow(window
);
12190 memset(&hal_desc
, 0, sizeof(hal_desc
));
12191 hal_desc
.dwSize
= sizeof(hal_desc
);
12192 memset(&hel_desc
, 0, sizeof(hel_desc
));
12193 hel_desc
.dwSize
= sizeof(hel_desc
);
12194 hr
= IDirect3DDevice3_GetCaps(device
, &hal_desc
, &hel_desc
);
12195 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
12196 trace("HAL line edge antialiasing support: %#x.\n",
12197 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12198 trace("HAL triangle edge antialiasing support: %#x.\n",
12199 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12200 trace("HEL line edge antialiasing support: %#x.\n",
12201 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12202 trace("HEL triangle edge antialiasing support: %#x.\n",
12203 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12205 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12206 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12207 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12208 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
12209 IDirect3D3_Release(d3d
);
12211 memset(&surface_desc
, 0, sizeof(surface_desc
));
12212 surface_desc
.dwSize
= sizeof(surface_desc
);
12213 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12214 surface_desc
.dwWidth
= 640;
12215 surface_desc
.dwHeight
= 480;
12216 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
12217 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12218 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12219 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12220 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12221 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12222 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12223 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12224 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
12226 ds
= get_depth_stencil(device
);
12227 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
12228 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
12229 IDirectDrawSurface_Release(ds
);
12231 hr
= IDirect3DDevice3_SetRenderTarget(device
, offscreen
, 0);
12232 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
12234 viewport
= create_viewport(device
, 0, 0, 640, 480);
12235 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12236 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12238 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12239 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12240 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12241 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
12242 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12243 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
12244 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
12245 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
12246 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12247 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
12248 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12249 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12250 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
12251 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
12252 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12253 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
12254 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12255 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
12257 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
12258 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
12259 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
12260 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
12261 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
12262 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
12264 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
12265 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
12266 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
12267 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12268 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
12269 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
12270 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
12271 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
12273 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12274 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12275 hr
= IDirect3DDevice3_BeginScene(device
);
12276 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12277 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12279 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12280 hr
= IDirect3DDevice3_EndScene(device
);
12281 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12282 color
= get_surface_color(offscreen
, 320, 240);
12283 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12285 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12286 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12287 hr
= IDirect3DDevice3_BeginScene(device
);
12288 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12289 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12291 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12292 hr
= IDirect3DDevice3_EndScene(device
);
12293 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12294 color
= get_surface_color(offscreen
, 320, 240);
12295 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12297 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
12298 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
12300 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12301 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12302 hr
= IDirect3DDevice3_BeginScene(device
);
12303 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12304 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12306 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12307 hr
= IDirect3DDevice3_EndScene(device
);
12308 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12309 color
= get_surface_color(offscreen
, 320, 240);
12310 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12312 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12313 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12314 hr
= IDirect3DDevice3_BeginScene(device
);
12315 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12316 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12318 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12319 hr
= IDirect3DDevice3_EndScene(device
);
12320 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12321 color
= get_surface_color(offscreen
, 320, 240);
12322 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12324 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
12325 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
12327 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12328 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12329 hr
= IDirect3DDevice3_BeginScene(device
);
12330 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12331 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12333 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12334 hr
= IDirect3DDevice3_EndScene(device
);
12335 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12336 color
= get_surface_color(offscreen
, 320, 240);
12337 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12339 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12340 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12341 hr
= IDirect3DDevice3_BeginScene(device
);
12342 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12343 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12345 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12346 hr
= IDirect3DDevice3_EndScene(device
);
12347 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12348 color
= get_surface_color(offscreen
, 320, 240);
12349 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12351 IDirectDrawSurface4_Release(offscreen
);
12352 IDirectDraw3_Release(ddraw
);
12353 destroy_viewport(device
, viewport
);
12354 refcount
= IDirect3DDevice3_Release(device
);
12355 ok(!refcount
, "Device has %u references left.\n", refcount
);
12356 DestroyWindow(window
);
12359 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
12360 * The stride is honored for navigating to the next vertex. 3 floats input position
12361 * are read, and 16 bytes extra vertex data are copied around. */
12362 struct transform_input
12364 float x
, y
, z
, unused1
; /* Position data, transformed. */
12365 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
12369 struct transform_output
12372 DWORD v1
, v2
, v3
, v4
;
12373 DWORD unused3
, unused4
;
12376 static void test_transform_vertices(void)
12378 IDirect3DDevice3
*device
;
12379 IDirectDrawSurface4
*rt
;
12384 IDirect3DViewport3
*viewport
;
12385 static struct transform_input position_tests
[] =
12387 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12388 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
12389 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
12390 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
12391 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
12392 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
12394 static struct transform_input cliptest
[] =
12396 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
12397 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
12398 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12399 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
12401 static struct transform_input offscreentest
[] =
12403 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12405 struct transform_output out
[ARRAY_SIZE(position_tests
)];
12406 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
12407 D3DTRANSFORMDATA transformdata
;
12408 static const D3DVIEWPORT vp_template
=
12410 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
12412 D3DVIEWPORT vp_data
=
12414 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
12416 D3DVIEWPORT2 vp2_data
;
12419 static D3DMATRIX mat_scale
=
12421 2.0f
, 0.0f
, 0.0f
, 0.0f
,
12422 0.0f
, 2.0f
, 0.0f
, 0.0f
,
12423 0.0f
, 0.0f
, 2.0f
, 0.0f
,
12424 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12428 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12429 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12430 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12431 1.0f
, 0.0f
, 0.0f
, 1.0f
,
12435 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12436 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12437 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12438 0.0f
, 1.0f
, 0.0f
, 1.0f
,
12442 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12443 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12444 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12445 0.0f
, 19.2f
, 0.0f
, 2.0f
,
12449 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12450 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12451 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12452 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12456 struct vec3 position
;
12461 {{-0.75f
, -0.5f
, 0.0f
}, 0xffff0000},
12462 {{-0.75f
, 0.25f
, 0.0f
}, 0xffff0000},
12463 {{ 0.5f
, -0.5f
, 0.0f
}, 0xffff0000},
12464 {{ 0.5f
, 0.25f
, 0.0f
}, 0xffff0000},
12466 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12468 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
12470 out
[i
].unused3
= 0xdeadbeef;
12471 out
[i
].unused4
= 0xcafecafe;
12474 window
= create_window();
12475 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12477 skip("Failed to create a 3D device.\n");
12478 DestroyWindow(window
);
12481 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12482 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12484 viewport
= create_viewport(device
, 0, 0, 256, 256);
12485 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12486 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12488 memset(&transformdata
, 0, sizeof(transformdata
));
12489 transformdata
.dwSize
= sizeof(transformdata
);
12490 transformdata
.lpIn
= position_tests
;
12491 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12492 transformdata
.lpOut
= out
;
12493 transformdata
.dwOutSize
= sizeof(out
[0]);
12494 transformdata
.lpHOut
= NULL
;
12496 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12497 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12498 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12499 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12501 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12503 static const struct vec4 cmp
[] =
12505 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
12506 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
12509 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12510 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12511 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12512 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
12513 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
12514 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
12515 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
12516 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
12519 vp_data
= vp_template
;
12520 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12521 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12522 offscreen
= 0xdeadbeef;
12523 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12524 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12525 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12526 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12528 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12530 static const struct vec4 cmp
[] =
12532 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
12533 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
12535 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12536 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12537 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12542 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12543 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12544 offscreen
= 0xdeadbeef;
12545 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12546 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12547 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12548 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12549 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12551 static const struct vec4 cmp
[] =
12553 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
12554 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12556 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12557 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12558 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12561 transformdata
.lpHOut
= out_h
;
12562 offscreen
= 0xdeadbeef;
12563 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12564 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12565 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12566 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12567 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12569 static const D3DHVERTEX cmp_h
[] =
12571 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
12572 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
12573 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
12575 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12576 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12577 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12578 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12579 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12580 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12582 /* No scheme has been found behind those return values. It seems to be
12583 * whatever data windows has when throwing the vertex away. Modify the
12584 * input test vertices to test this more. Depending on the input data
12585 * it can happen that the z coord gets written into y, or similar things. */
12588 static const struct vec4 cmp
[] =
12590 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
12591 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12593 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12594 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12595 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12599 transformdata
.lpIn
= cliptest
;
12600 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12601 offscreen
= 0xdeadbeef;
12602 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12603 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12604 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12605 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12606 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12608 static const DWORD flags
[] =
12611 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
12613 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
12615 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12618 vp_data
= vp_template
;
12619 vp_data
.dwWidth
= 10;
12620 vp_data
.dwHeight
= 480;
12621 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12622 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12623 offscreen
= 0xdeadbeef;
12624 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12625 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12626 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12627 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12628 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12630 static const DWORD flags
[] =
12633 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
12635 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
12637 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12640 vp_data
= vp_template
;
12641 vp_data
.dwWidth
= 256;
12642 vp_data
.dwHeight
= 256;
12643 vp_data
.dvScaleX
= 1;
12644 vp_data
.dvScaleY
= 1;
12645 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12646 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12647 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12648 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12649 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12650 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12651 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12653 static const DWORD flags
[] =
12660 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12663 /* Finally try to figure out how the DWORD dwOffscreen works.
12664 * It is a logical AND of the vertices' dwFlags members. */
12665 vp_data
= vp_template
;
12666 vp_data
.dwWidth
= 5;
12667 vp_data
.dwHeight
= 5;
12668 vp_data
.dvScaleX
= 10000.0f
;
12669 vp_data
.dvScaleY
= 10000.0f
;
12670 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12671 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12672 transformdata
.lpIn
= cliptest
;
12673 offscreen
= 0xdeadbeef;
12674 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12675 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12676 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12677 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12679 offscreen
= 0xdeadbeef;
12680 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12681 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12682 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12683 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12684 offscreen
= 0xdeadbeef;
12685 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12686 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12687 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12688 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12689 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
12690 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12691 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12692 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12694 transformdata
.lpIn
= cliptest
+ 1;
12695 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12696 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12697 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12698 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12700 transformdata
.lpIn
= cliptest
+ 2;
12701 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12702 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12703 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12704 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12705 offscreen
= 0xdeadbeef;
12706 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12707 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12708 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12709 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12711 transformdata
.lpIn
= cliptest
+ 3;
12712 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12713 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12714 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12715 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12717 transformdata
.lpIn
= offscreentest
;
12718 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
12719 vp_data
= vp_template
;
12720 vp_data
.dwWidth
= 257;
12721 vp_data
.dwHeight
= 257;
12722 vp_data
.dvScaleX
= 1.0f
;
12723 vp_data
.dvScaleY
= 1.0f
;
12724 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12725 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12726 offscreen
= 0xdeadbeef;
12727 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12728 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12729 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12730 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12732 vp_data
.dwWidth
= 256;
12733 vp_data
.dwHeight
= 256;
12734 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12735 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12736 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12737 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12738 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12739 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
12741 /* Test the effect of Matrices.
12743 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
12744 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
12745 * the view matrix and the +1's from the world and projection matrix. */
12748 vp_data
.dwWidth
= 256;
12749 vp_data
.dwHeight
= 256;
12750 vp_data
.dvScaleX
= 5.0f
;
12751 vp_data
.dvScaleY
= 5.0f
;
12752 vp_data
.dvMinZ
= 0.0f
;
12753 vp_data
.dvMaxZ
= 1.0f
;
12754 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12755 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12757 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
12758 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12759 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
12760 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12761 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
12762 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12764 transformdata
.lpIn
= position_tests
;
12765 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12766 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12767 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12768 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12770 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12772 static const struct vec4 cmp
[] =
12774 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
12775 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
12778 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12779 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12780 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12783 /* Invalid flags. */
12784 offscreen
= 0xdeadbeef;
12785 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12786 &transformdata
, 0, &offscreen
);
12787 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12788 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12790 /* NULL transform data. */
12791 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12792 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12793 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12794 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12795 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12796 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12797 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12798 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12800 /* NULL transform data and NULL dwOffscreen.
12802 * Valid transform data + NULL dwOffscreen -> crash. */
12803 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12804 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
12805 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12808 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12809 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12810 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12811 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12812 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12813 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12814 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12815 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12817 /* Invalid sizes. */
12818 offscreen
= 0xdeadbeef;
12819 transformdata
.dwSize
= sizeof(transformdata
) - 1;
12820 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12821 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12822 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12823 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12824 transformdata
.dwSize
= sizeof(transformdata
) + 1;
12825 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12826 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12827 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12828 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12830 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
12831 transformdata
.dwSize
= sizeof(transformdata
);
12832 transformdata
.lpIn
= NULL
;
12833 transformdata
.lpOut
= NULL
;
12834 offscreen
= 0xdeadbeef;
12835 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12836 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12837 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12838 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12840 /* Test how vertices are transformed during draws. */
12843 vp_data
.dwWidth
= 200;
12844 vp_data
.dwHeight
= 400;
12845 vp_data
.dvScaleX
= 20.0f
;
12846 vp_data
.dvScaleY
= 50.0f
;
12847 vp_data
.dvMinZ
= 0.0f
;
12848 vp_data
.dvMaxZ
= 1.0f
;
12849 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp_data
);
12850 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12851 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12852 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12854 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
12855 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12857 hr
= IDirect3DDevice3_BeginScene(device
);
12858 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12859 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12861 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12862 hr
= IDirect3DDevice3_EndScene(device
);
12863 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12865 color
= get_surface_color(rt
, 128, 143);
12866 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12867 color
= get_surface_color(rt
, 132, 143);
12868 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12869 color
= get_surface_color(rt
, 128, 147);
12870 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12871 color
= get_surface_color(rt
, 132, 147);
12872 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12874 color
= get_surface_color(rt
, 177, 217);
12875 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12876 color
= get_surface_color(rt
, 181, 217);
12877 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12878 color
= get_surface_color(rt
, 177, 221);
12879 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12880 color
= get_surface_color(rt
, 181, 221);
12881 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12883 /* Test D3DVIEWPORT2 behavior. */
12884 vp2_data
.dwSize
= sizeof(vp2_data
);
12887 vp2_data
.dwWidth
= 200;
12888 vp2_data
.dwHeight
= 400;
12889 vp2_data
.dvClipX
= -0.5f
;
12890 vp2_data
.dvClipY
= 4.0f
;
12891 vp2_data
.dvClipWidth
= 5.0f
;
12892 vp2_data
.dvClipHeight
= 10.0f
;
12893 vp2_data
.dvMinZ
= 0.0f
;
12894 vp2_data
.dvMaxZ
= 2.0f
;
12895 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
12896 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12897 transformdata
.lpIn
= position_tests
;
12898 transformdata
.lpOut
= out
;
12899 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12900 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12901 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12902 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12904 static const struct vec4 cmp
[] =
12906 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
12907 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
12910 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12911 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12912 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12915 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
12916 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12918 hr
= IDirect3DDevice3_BeginScene(device
);
12919 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12920 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12922 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12923 hr
= IDirect3DDevice3_EndScene(device
);
12924 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12926 color
= get_surface_color(rt
, 58, 118);
12927 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12928 color
= get_surface_color(rt
, 62, 118);
12929 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12930 color
= get_surface_color(rt
, 58, 122);
12931 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12932 color
= get_surface_color(rt
, 62, 122);
12933 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12935 color
= get_surface_color(rt
, 157, 177);
12936 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12937 color
= get_surface_color(rt
, 161, 177);
12938 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12939 color
= get_surface_color(rt
, 157, 181);
12940 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12941 color
= get_surface_color(rt
, 161, 181);
12942 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12944 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
12945 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12946 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
12947 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12948 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
12949 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12951 vp2_data
.dwX
= 0.0;
12952 vp2_data
.dwY
= 0.0;
12953 vp2_data
.dwWidth
= 1;
12954 vp2_data
.dwHeight
= 1;
12955 vp2_data
.dvClipX
= -12.8f
;
12956 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
12957 vp2_data
.dvClipWidth
= 25.6f
;
12958 vp2_data
.dvClipHeight
= 25.6f
;
12959 vp2_data
.dvMinZ
= 0.0f
;
12960 vp2_data
.dvMaxZ
= 0.5f
;
12961 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
12962 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12963 transformdata
.lpIn
= cliptest
;
12964 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12965 offscreen
= 0xdeadbeef;
12966 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12967 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12968 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12969 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12970 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12972 static const D3DHVERTEX cmp_h
[] =
12974 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
12975 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
12976 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
12977 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
12979 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12980 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12981 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12982 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12983 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12984 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12987 destroy_viewport(device
, viewport
);
12988 IDirectDrawSurface4_Release(rt
);
12989 refcount
= IDirect3DDevice3_Release(device
);
12990 ok(!refcount
, "Device has %u references left.\n", refcount
);
12991 DestroyWindow(window
);
12994 static void test_display_mode_surface_pixel_format(void)
12996 unsigned int width
, height
, bpp
;
12997 IDirectDrawSurface4
*surface
;
12998 DDSURFACEDESC2 surface_desc
;
12999 IDirectDraw4
*ddraw
;
13004 if (!(ddraw
= create_ddraw()))
13006 skip("Failed to create ddraw.\n");
13010 surface_desc
.dwSize
= sizeof(surface_desc
);
13011 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13012 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13013 width
= surface_desc
.dwWidth
;
13014 height
= surface_desc
.dwHeight
;
13016 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13017 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
13018 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13019 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13022 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
13024 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
13026 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
13028 ok(bpp
, "Set display mode failed.\n");
13030 surface_desc
.dwSize
= sizeof(surface_desc
);
13031 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13032 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13033 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13034 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13035 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13036 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13038 memset(&surface_desc
, 0, sizeof(surface_desc
));
13039 surface_desc
.dwSize
= sizeof(surface_desc
);
13040 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13041 U5(surface_desc
).dwBackBufferCount
= 1;
13042 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
13043 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13044 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13045 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13046 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13047 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13048 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13049 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13050 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13051 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13052 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13053 IDirectDrawSurface4_Release(surface
);
13055 memset(&surface_desc
, 0, sizeof(surface_desc
));
13056 surface_desc
.dwSize
= sizeof(surface_desc
);
13057 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13058 surface_desc
.dwWidth
= width
;
13059 surface_desc
.dwHeight
= height
;
13060 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13061 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13062 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13063 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13064 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13065 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13066 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13067 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13068 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13069 IDirectDrawSurface4_Release(surface
);
13071 refcount
= IDirectDraw4_Release(ddraw
);
13072 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13073 DestroyWindow(window
);
13076 static void test_surface_desc_size(void)
13081 DDSURFACEDESC desc1
;
13082 DDSURFACEDESC2 desc2
;
13085 IDirectDrawSurface4
*surface4
;
13086 IDirectDrawSurface3
*surface3
;
13087 IDirectDrawSurface
*surface
;
13088 DDSURFACEDESC2 surface_desc
;
13089 HRESULT expected_hr
, hr
;
13090 IDirectDraw4
*ddraw
;
13094 static const struct
13101 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
13102 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
13103 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
13105 static const unsigned int desc_sizes
[] =
13107 sizeof(DDSURFACEDESC
),
13108 sizeof(DDSURFACEDESC2
),
13109 sizeof(DDSURFACEDESC
) + 1,
13110 sizeof(DDSURFACEDESC2
) + 1,
13111 2 * sizeof(DDSURFACEDESC
),
13112 2 * sizeof(DDSURFACEDESC2
),
13113 sizeof(DDSURFACEDESC
) - 1,
13114 sizeof(DDSURFACEDESC2
) - 1,
13115 sizeof(DDSURFACEDESC
) / 2,
13116 sizeof(DDSURFACEDESC2
) / 2,
13121 sizeof(desc
) - 100,
13124 if (!(ddraw
= create_ddraw()))
13126 skip("Failed to create ddraw.\n");
13129 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13130 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13132 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
13134 memset(&surface_desc
, 0, sizeof(surface_desc
));
13135 surface_desc
.dwSize
= sizeof(surface_desc
);
13136 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13137 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
13138 surface_desc
.dwHeight
= 128;
13139 surface_desc
.dwWidth
= 128;
13140 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
)))
13142 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
13145 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface
, (void **)&surface
);
13146 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13147 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
13148 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13150 /* GetSurfaceDesc() */
13151 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13153 memset(&desc
, 0, sizeof(desc
));
13154 desc
.dwSize
= desc_sizes
[j
];
13155 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13156 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
13157 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13158 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13160 memset(&desc
, 0, sizeof(desc
));
13161 desc
.dwSize
= desc_sizes
[j
];
13162 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13163 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
13164 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13165 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13167 memset(&desc
, 0, sizeof(desc
));
13168 desc
.dwSize
= desc_sizes
[j
];
13169 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13170 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface4
, &desc
.desc2
);
13171 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13172 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13176 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13178 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
13179 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
13180 DWORD expected_texture_stage
;
13182 memset(&desc
, 0, sizeof(desc
));
13183 desc
.dwSize
= desc_sizes
[j
];
13184 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13185 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13186 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
13187 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13188 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13189 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13190 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13191 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13192 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13193 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13196 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13197 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13198 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13199 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13200 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13201 todo_wine_if(!expected_texture_stage
)
13202 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13203 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13204 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13205 IDirectDrawSurface_Unlock(surface
, NULL
);
13208 memset(&desc
, 0, sizeof(desc
));
13209 desc
.dwSize
= desc_sizes
[j
];
13210 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13211 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13212 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
13213 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13214 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13215 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13216 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13217 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13218 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13219 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13222 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13223 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13224 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13225 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13226 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13227 todo_wine_if(!expected_texture_stage
)
13228 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13229 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13230 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13231 IDirectDrawSurface3_Unlock(surface3
, NULL
);
13234 memset(&desc
, 0, sizeof(desc
));
13235 desc
.dwSize
= desc_sizes
[j
];
13236 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13237 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13238 hr
= IDirectDrawSurface4_Lock(surface4
, NULL
, &desc
.desc2
, 0, 0);
13239 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13240 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13241 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13242 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13243 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13244 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13245 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13248 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13249 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13250 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13251 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13252 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13253 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13254 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13255 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13256 IDirectDrawSurface4_Unlock(surface4
, NULL
);
13260 IDirectDrawSurface4_Release(surface4
);
13261 IDirectDrawSurface3_Release(surface3
);
13262 IDirectDrawSurface_Release(surface
);
13265 /* GetDisplayMode() */
13266 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13268 memset(&desc
, 0xcc, sizeof(desc
));
13269 desc
.dwSize
= desc_sizes
[j
];
13270 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
13271 ? DD_OK
: DDERR_INVALIDPARAMS
;
13272 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &desc
.desc2
);
13273 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
13276 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
13277 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
13278 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
13282 refcount
= IDirectDraw4_Release(ddraw
);
13283 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13286 static void test_get_surface_from_dc(void)
13288 IDirectDrawSurface
*surface1
, *tmp
;
13289 IDirectDrawSurface4
*surface
;
13290 DDSURFACEDESC2 surface_desc
;
13291 IDirectDraw4
*ddraw
;
13298 window
= create_window();
13299 ddraw
= create_ddraw();
13300 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13301 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13302 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13304 memset(&surface_desc
, 0, sizeof(surface_desc
));
13305 surface_desc
.dwSize
= sizeof(surface_desc
);
13306 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
13307 surface_desc
.dwWidth
= 64;
13308 surface_desc
.dwHeight
= 64;
13309 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13311 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13312 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13313 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
13314 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13316 refcount
= get_refcount((IUnknown
*)surface1
);
13317 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13318 refcount
= get_refcount((IUnknown
*)surface
);
13319 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13321 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13322 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
13324 tmp
= (void *)0xdeadbeef;
13325 device_dc
= (void *)0xdeadbeef;
13326 hr
= GetSurfaceFromDC(NULL
, &tmp
, &device_dc
);
13327 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13328 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13329 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
13331 device_dc
= (void *)0xdeadbeef;
13332 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
13333 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13334 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
13336 tmp
= (void *)0xdeadbeef;
13337 hr
= GetSurfaceFromDC(dc
, &tmp
, NULL
);
13338 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13339 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13341 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
13342 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
13343 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
13344 IDirectDrawSurface_Release(tmp
);
13346 ret
= GetObjectType(device_dc
);
13347 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#x.\n", ret
);
13348 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
13349 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#x.\n", ret
);
13351 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, NULL
);
13352 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13354 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
13355 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
13356 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
13358 refcount
= get_refcount((IUnknown
*)surface1
);
13359 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13360 refcount
= get_refcount((IUnknown
*)surface
);
13361 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13363 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13364 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#x.\n", hr
);
13366 IDirectDrawSurface_Release(tmp
);
13368 dc
= CreateCompatibleDC(NULL
);
13369 ok(!!dc
, "CreateCompatibleDC failed.\n");
13371 tmp
= (void *)0xdeadbeef;
13372 device_dc
= (void *)0xdeadbeef;
13373 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
13374 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13375 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13376 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
13378 tmp
= (void *)0xdeadbeef;
13379 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
13380 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13381 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13383 ok(DeleteDC(dc
), "DeleteDC failed.\n");
13385 tmp
= (void *)0xdeadbeef;
13386 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, NULL
, (IDirectDrawSurface4
**)&tmp
);
13387 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13388 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13390 IDirectDrawSurface4_Release(surface
);
13391 IDirectDrawSurface_Release(surface1
);
13392 IDirectDraw4_Release(ddraw
);
13393 DestroyWindow(window
);
13396 static void test_ck_operation(void)
13398 IDirectDrawSurface4
*src
, *dst
;
13399 IDirectDrawSurface
*src1
, *dst1
;
13400 DDSURFACEDESC2 surface_desc
;
13401 IDirectDraw4
*ddraw
;
13410 window
= create_window();
13411 ddraw
= create_ddraw();
13412 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13413 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13414 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13416 memset(&surface_desc
, 0, sizeof(surface_desc
));
13417 surface_desc
.dwSize
= sizeof(surface_desc
);
13418 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13419 surface_desc
.dwWidth
= 4;
13420 surface_desc
.dwHeight
= 1;
13421 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13422 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13423 U1(U4(surface_desc
.ddpfPixelFormat
)).dwRGBBitCount
= 32;
13424 U2(U4(surface_desc
.ddpfPixelFormat
)).dwRBitMask
= 0x00ff0000;
13425 U3(U4(surface_desc
.ddpfPixelFormat
)).dwGBitMask
= 0x0000ff00;
13426 U4(U4(surface_desc
.ddpfPixelFormat
)).dwBBitMask
= 0x000000ff;
13427 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
13428 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13430 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
13431 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
13432 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
13433 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
13434 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13436 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13437 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13438 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13439 color
= surface_desc
.lpSurface
;
13440 color
[0] = 0x77010203;
13441 color
[1] = 0x00010203;
13442 color
[2] = 0x77ff00ff;
13443 color
[3] = 0x00ff00ff;
13444 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
13445 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13447 for (i
= 0; i
< 2; ++i
)
13449 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13450 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13451 color
= surface_desc
.lpSurface
;
13452 color
[0] = 0xcccccccc;
13453 color
[1] = 0xcccccccc;
13454 color
[2] = 0xcccccccc;
13455 color
[3] = 0xcccccccc;
13456 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13457 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13461 hr
= IDirectDrawSurface4_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
13462 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13466 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
13467 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13470 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
13471 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13472 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13473 color
= surface_desc
.lpSurface
;
13474 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
13475 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
13476 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
13477 * color keying nor copies it. */
13478 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
13479 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
13480 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13481 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
13482 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13483 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
13484 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
13485 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
13486 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
13487 color
[0], color
[1], color
[2], color
[3], i
);
13488 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13489 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13492 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13493 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13494 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
13495 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13497 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13498 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13499 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13501 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13502 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13503 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13504 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
13505 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13507 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
13508 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
13509 hr
= IDirectDrawSurface4_GetSurfaceDesc(src
, &surface_desc
);
13510 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13511 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
13512 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
13513 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13514 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13516 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
13517 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13518 ckey
.dwColorSpaceHighValue
= 0x00000000;
13519 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13520 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13522 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13523 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13524 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13525 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13526 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13528 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13529 ckey
.dwColorSpaceHighValue
= 0x00000001;
13530 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13531 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13533 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13534 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13535 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13536 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13537 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13539 ckey
.dwColorSpaceLowValue
= 0x000000fe;
13540 ckey
.dwColorSpaceHighValue
= 0x000000fd;
13541 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13542 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13544 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13545 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13546 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13547 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
13548 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13550 IDirectDrawSurface4_Release(src
);
13551 IDirectDrawSurface4_Release(dst
);
13553 /* Test source and destination keys and where they are read from. Use a surface with alpha
13554 * to avoid driver-dependent content in the X channel. */
13555 memset(&surface_desc
, 0, sizeof(surface_desc
));
13556 surface_desc
.dwSize
= sizeof(surface_desc
);
13557 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13558 surface_desc
.dwWidth
= 6;
13559 surface_desc
.dwHeight
= 1;
13560 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13561 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13562 U1(U4(surface_desc
.ddpfPixelFormat
)).dwRGBBitCount
= 32;
13563 U2(U4(surface_desc
.ddpfPixelFormat
)).dwRBitMask
= 0x00ff0000;
13564 U3(U4(surface_desc
.ddpfPixelFormat
)).dwGBitMask
= 0x0000ff00;
13565 U4(U4(surface_desc
.ddpfPixelFormat
)).dwBBitMask
= 0x000000ff;
13566 U5(U4(surface_desc
.ddpfPixelFormat
)).dwRGBAlphaBitMask
= 0xff000000;
13567 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
13568 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13569 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
13570 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13572 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
13573 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13574 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
13575 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13576 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
13577 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
13578 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
13579 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
13582 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
13583 skip("Failed to set destination color key, skipping related tests.\n");
13587 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13588 ckey
.dwColorSpaceHighValue
= 0x000000ff;
13589 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13590 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13591 ckey
.dwColorSpaceLowValue
= 0x000000aa;
13592 ckey
.dwColorSpaceHighValue
= 0x000000aa;
13593 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13594 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13596 memset(&fx
, 0, sizeof(fx
));
13597 fx
.dwSize
= sizeof(fx
);
13598 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
13599 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
13600 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
13601 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
13603 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13604 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13605 color
= surface_desc
.lpSurface
;
13606 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
13607 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
13608 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
13609 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
13610 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
13611 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
13612 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
13613 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13615 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13616 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13617 color
= surface_desc
.lpSurface
;
13618 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13619 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13620 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13622 /* Test a blit without keying. */
13623 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
13624 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13626 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13627 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13628 color
= surface_desc
.lpSurface
;
13629 /* Should have copied src data unmodified to dst. */
13630 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13631 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13632 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13633 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13635 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13636 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13637 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13640 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13641 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13643 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13644 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13645 color
= surface_desc
.lpSurface
;
13646 /* Src key applied to color[0]. It is unmodified, the others are copied. */
13647 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13648 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13649 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13650 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13652 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13653 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13654 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13656 /* Src override. */
13657 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
13658 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13660 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13661 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13662 color
= surface_desc
.lpSurface
;
13663 /* Override key applied to color[5]. It is unmodified, the others are copied. */
13664 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13665 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
13666 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13667 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13669 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13670 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13671 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13673 /* Src override AND src key. That is not supposed to work. */
13674 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
13675 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13677 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13678 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13679 color
= surface_desc
.lpSurface
;
13680 /* Ensure the destination was not changed. */
13681 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
13682 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
13683 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13684 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13686 /* Use different dst colors for the dst key test. */
13687 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13688 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13689 color
[2] = 0x00001100; /* Dest key in override. */
13690 color
[3] = 0x00001100; /* Dest key in override. */
13691 color
[4] = 0x000000aa; /* Dest key in src surface. */
13692 color
[5] = 0x000000aa; /* Dest key in src surface. */
13693 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13694 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13696 /* Dest key blit. The key is taken from the DESTINATION surface in v4! */
13697 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13698 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13700 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13701 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13702 color
= surface_desc
.lpSurface
;
13703 /* Dst key applied to color[0,1], they are the only changed pixels. */
13704 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13705 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13706 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13707 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13709 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13710 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13711 color
[2] = 0x00001100; /* Dest key in override. */
13712 color
[3] = 0x00001100; /* Dest key in override. */
13713 color
[4] = 0x000000aa; /* Dest key in src surface. */
13714 color
[5] = 0x000000aa; /* Dest key in src surface. */
13715 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13716 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13718 /* What happens with a QI'd older version of the interface? It takes the key
13719 * from the source surface. */
13720 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
13721 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13722 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
13723 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13725 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
13726 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13728 IDirectDrawSurface_Release(dst1
);
13729 IDirectDrawSurface_Release(src1
);
13731 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13732 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13733 color
= surface_desc
.lpSurface
;
13734 /* Dst key applied to color[4,5], they are the only changed pixels. */
13735 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13736 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13737 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13738 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13740 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13741 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13742 color
[2] = 0x00001100; /* Dest key in override. */
13743 color
[3] = 0x00001100; /* Dest key in override. */
13744 color
[4] = 0x000000aa; /* Dest key in src surface. */
13745 color
[5] = 0x000000aa; /* Dest key in src surface. */
13746 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
13747 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13749 /* Dest override key blit. */
13750 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
13751 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13753 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13754 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13755 color
= surface_desc
.lpSurface
;
13756 /* Dst key applied to color[2,3], they are the only changed pixels. */
13757 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
13758 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13759 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13760 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13762 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13763 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13764 color
[2] = 0x00001100; /* Dest key in override. */
13765 color
[3] = 0x00001100; /* Dest key in override. */
13766 color
[4] = 0x000000aa; /* Dest key in src surface. */
13767 color
[5] = 0x000000aa; /* Dest key in src surface. */
13768 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13769 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13771 /* Dest override together with surface key. Supposed to fail. */
13772 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
13773 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13775 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13776 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13777 color
= surface_desc
.lpSurface
;
13778 /* Destination is unchanged. */
13779 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13780 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13781 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13782 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13783 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13784 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13786 /* Source and destination key. This is driver dependent. New HW treats it like
13787 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
13790 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
13791 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13793 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13794 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13795 color
= surface_desc
.lpSurface
;
13796 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
13797 * the driver applies it. */
13798 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13799 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13800 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13801 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13803 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13804 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13805 color
[2] = 0x00001100; /* Dest key in override. */
13806 color
[3] = 0x00001100; /* Dest key in override. */
13807 color
[4] = 0x000000aa; /* Dest key in src surface. */
13808 color
[5] = 0x000000aa; /* Dest key in src surface. */
13809 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13810 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13813 /* Override keys without ddbltfx parameter fail */
13814 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
13815 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13816 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
13817 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13819 /* Try blitting without keys in the source surface. */
13820 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
13821 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13822 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
13823 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13825 /* That fails now. Do not bother to check that the data is unmodified. */
13826 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13827 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13829 /* Dest key blit still works, the destination surface key is used in v4. */
13830 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13831 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13833 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13834 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13835 color
= surface_desc
.lpSurface
;
13836 /* Dst key applied to color[0,1], they are the only changed pixels. */
13837 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13838 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13839 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13840 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13841 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13842 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13844 /* Try blitting without keys in the destination surface. */
13845 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
13846 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13847 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
13848 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13850 /* This fails, as sanity would dictate. */
13851 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13852 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13855 IDirectDrawSurface4_Release(src
);
13856 IDirectDrawSurface4_Release(dst
);
13857 refcount
= IDirectDraw4_Release(ddraw
);
13858 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13859 DestroyWindow(window
);
13862 static void test_vb_refcount(void)
13864 ULONG prev_d3d_refcount
, prev_device_refcount
;
13865 ULONG cur_d3d_refcount
, cur_device_refcount
;
13866 IDirect3DVertexBuffer
*vb
, *vb1
;
13867 IDirect3DVertexBuffer7
*vb7
;
13868 D3DVERTEXBUFFERDESC vb_desc
;
13869 IDirect3DDevice3
*device
;
13876 window
= create_window();
13877 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13879 skip("Failed to create a 3D device, skipping test.\n");
13880 DestroyWindow(window
);
13884 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
13885 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
13887 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
13888 prev_device_refcount
= get_refcount((IUnknown
*)device
);
13890 memset(&vb_desc
, 0, sizeof(vb_desc
));
13891 vb_desc
.dwSize
= sizeof(vb_desc
);
13892 vb_desc
.dwFVF
= D3DFVF_XYZ
;
13893 vb_desc
.dwNumVertices
= 4;
13894 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
13895 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
13897 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
13898 cur_device_refcount
= get_refcount((IUnknown
*)device
);
13899 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %u to %u.\n",
13900 prev_d3d_refcount
, cur_d3d_refcount
);
13901 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %u to %u.\n",
13902 prev_device_refcount
, cur_device_refcount
);
13904 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
13905 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer, hr %#x.\n", hr
);
13906 IDirect3DVertexBuffer_Release(vb1
);
13908 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
13909 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer7 returned unexpected hr %#x.\n", hr
);
13911 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
13912 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#x.\n", hr
);
13913 ok((IUnknown
*)vb
== unk
,
13914 "IDirect3DVertexBuffer and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
13915 IUnknown_Release(unk
);
13917 refcount
= IDirect3DVertexBuffer_Release(vb
);
13918 ok(!refcount
, "Vertex buffer has %u references left.\n", refcount
);
13919 IDirect3D3_Release(d3d
);
13920 refcount
= IDirect3DDevice3_Release(device
);
13921 ok(!refcount
, "Device has %u references left.\n", refcount
);
13922 DestroyWindow(window
);
13925 static void test_compute_sphere_visibility(void)
13927 static D3DMATRIX proj_1
=
13929 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
13930 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
13931 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
13932 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
13934 static D3DMATRIX proj_2
=
13936 10.0f
, 0.0f
, 0.0f
, 0.0f
,
13937 0.0f
, 10.0f
, 0.0f
, 0.0f
,
13938 0.0f
, 0.0f
, 10.0f
, 0.0f
,
13939 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13941 static D3DMATRIX view_1
=
13943 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
13944 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
13945 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
13946 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
13948 static D3DMATRIX identity
=
13950 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13951 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13952 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13953 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13957 D3DMATRIX
*view
, *proj
;
13958 unsigned int sphere_count
;
13959 D3DVECTOR center
[3];
13960 D3DVALUE radius
[3];
13961 const DWORD expected
[3];
13966 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, {0x1555}},
13967 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
13968 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
13969 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
13970 {4.354097f
, 12.500704f
, 17.251318f
}, {0x154a, 0x1555, 0x1555}},
13971 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, {0x1555}, TRUE
},
13972 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, {0x1401}},
13973 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, {0x401}},
13974 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, {0x1505}, TRUE
}, /* 5 */
13975 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x154a}},
13976 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x1562}},
13977 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, {0x1616}},
13978 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, {0x1496}},
13979 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, {0x956}}, /* 10 */
13980 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, {0x2156}},
13982 IDirect3DViewport3
*viewport
;
13983 IDirect3DDevice3
*device
;
13990 window
= create_window();
13991 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13993 skip("Failed to create a 3D device, skipping test.\n");
13994 DestroyWindow(window
);
13998 viewport
= create_viewport(device
, 0, 0, 640, 480);
13999 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14000 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14002 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
14004 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14006 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
14007 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
14009 hr
= IDirect3DDevice3_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
14010 tests
[i
].sphere_count
, 0, result
);
14011 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14013 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
14014 todo_wine_if(tests
[i
].todo
)
14015 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#x, got %#x.\n",
14016 i
, j
, tests
[i
].expected
[j
], result
[j
]);
14019 destroy_viewport(device
, viewport
);
14020 refcount
= IDirect3DDevice3_Release(device
);
14021 ok(!refcount
, "Device has %u references left.\n", refcount
);
14022 DestroyWindow(window
);
14025 static void test_texture_stages_limits(void)
14027 IDirectDrawSurface4
*surface
;
14028 DDSURFACEDESC2 surface_desc
;
14029 IDirect3DTexture2
*texture
;
14030 IDirect3DDevice3
*device
;
14031 IDirectDraw4
*ddraw
;
14038 window
= create_window();
14039 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14041 skip("Failed to create 3D device.\n");
14042 DestroyWindow(window
);
14045 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14046 ok(SUCCEEDED(hr
), "Failed to get Direct3D interface, hr %#x.\n", hr
);
14047 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14048 ok(SUCCEEDED(hr
), "Failed to get DirectDraw interface, hr %#x.\n", hr
);
14049 IDirect3D3_Release(d3d
);
14051 memset(&surface_desc
, 0, sizeof(surface_desc
));
14052 surface_desc
.dwSize
= sizeof(surface_desc
);
14053 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14054 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
14055 surface_desc
.dwWidth
= 16;
14056 surface_desc
.dwHeight
= 16;
14057 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14058 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
14059 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
14060 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
14061 IDirectDrawSurface4_Release(surface
);
14063 for (i
= 0; i
< 8; ++i
)
14065 hr
= IDirect3DDevice3_SetTexture(device
, i
, texture
);
14066 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
14067 hr
= IDirect3DDevice3_SetTexture(device
, i
, NULL
);
14068 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
14069 hr
= IDirect3DDevice3_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
14070 ok(hr
== D3D_OK
, "Failed to set texture stage state %u, hr %#x.\n", i
, hr
);
14073 IDirectDraw4_Release(ddraw
);
14074 IDirect3DTexture2_Release(texture
);
14075 refcount
= IDirect3DDevice3_Release(device
);
14076 ok(!refcount
, "Device has %u references left.\n", refcount
);
14077 DestroyWindow(window
);
14080 static void test_set_render_state(void)
14082 IDirect3DDevice3
*device
;
14088 window
= create_window();
14089 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14091 skip("Failed to create 3D device.\n");
14092 DestroyWindow(window
);
14096 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
14097 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14098 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
14099 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14101 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
14102 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14103 state
= 0xdeadbeef;
14104 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
14105 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14106 ok(!state
, "Got unexpected render state %#x.\n", state
);
14107 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
14108 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14109 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
14110 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14111 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#x.\n", state
);
14113 refcount
= IDirect3DDevice3_Release(device
);
14114 ok(!refcount
, "Device has %u references left.\n", refcount
);
14115 DestroyWindow(window
);
14118 static void test_map_synchronisation(void)
14120 LARGE_INTEGER frequency
, diff
, ts
[3];
14121 IDirect3DVertexBuffer
*buffer
;
14122 IDirect3DViewport3
*viewport
;
14123 unsigned int i
, j
, tri_count
;
14124 D3DVERTEXBUFFERDESC vb_desc
;
14125 IDirect3DDevice3
*device
;
14126 BOOL unsynchronised
, ret
;
14127 IDirectDrawSurface4
*rt
;
14134 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14136 /* DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE were introduced with
14137 * ddraw7 and are ignored in earlier versions. */
14138 static const struct
14140 unsigned int flags
;
14141 BOOL unsynchronised
;
14146 {DDLOCK_NOOVERWRITE
, FALSE
},
14147 {DDLOCK_DISCARDCONTENTS
, FALSE
},
14148 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, FALSE
},
14151 static const struct quad
14155 struct vec3 position
;
14162 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
14163 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14164 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
14165 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
14171 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14172 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14173 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14174 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14177 struct quad
*quads
;
14179 window
= create_window();
14180 ok(!!window
, "Failed to create a window.\n");
14182 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14184 skip("Failed to create a D3D device, skipping tests.\n");
14185 DestroyWindow(window
);
14189 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14190 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14192 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14193 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14194 viewport
= create_viewport(device
, 0, 0, 640, 480);
14195 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14196 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14198 tri_count
= 0x1000;
14200 ret
= QueryPerformanceFrequency(&frequency
);
14201 ok(ret
, "Failed to get performance counter frequency.\n");
14203 vb_desc
.dwSize
= sizeof(vb_desc
);
14204 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
14205 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
14206 vb_desc
.dwNumVertices
= tri_count
+ 2;
14207 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14208 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14209 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14210 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14211 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14215 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14216 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14218 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14219 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
14221 /* Initial draw to initialise states, compile shaders, etc. */
14222 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14223 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14224 hr
= IDirect3DDevice3_BeginScene(device
);
14225 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14226 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14227 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14228 hr
= IDirect3DDevice3_EndScene(device
);
14229 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14230 /* Read the result to ensure the GPU has finished drawing. */
14231 colour
= get_surface_color(rt
, 320, 240);
14233 /* Time drawing tri_count triangles. */
14234 ret
= QueryPerformanceCounter(&ts
[0]);
14235 ok(ret
, "Failed to read performance counter.\n");
14236 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14237 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14238 hr
= IDirect3DDevice3_BeginScene(device
);
14239 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14240 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14241 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14242 hr
= IDirect3DDevice3_EndScene(device
);
14243 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14244 colour
= get_surface_color(rt
, 320, 240);
14245 /* Time drawing a single triangle. */
14246 ret
= QueryPerformanceCounter(&ts
[1]);
14247 ok(ret
, "Failed to read performance counter.\n");
14248 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14249 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14250 hr
= IDirect3DDevice3_BeginScene(device
);
14251 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14252 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
14253 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14254 hr
= IDirect3DDevice3_EndScene(device
);
14255 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14256 colour
= get_surface_color(rt
, 320, 240);
14257 ret
= QueryPerformanceCounter(&ts
[2]);
14258 ok(ret
, "Failed to read performance counter.\n");
14260 IDirect3DVertexBuffer_Release(buffer
);
14262 /* Estimate the number of triangles we can draw in 100ms. */
14263 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
14264 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
14265 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
14266 vb_desc
.dwNumVertices
= tri_count
+ 2;
14268 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
14270 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14271 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14272 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14273 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14274 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14278 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14279 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14281 /* Start a draw operation. */
14282 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14283 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14284 hr
= IDirect3DDevice3_BeginScene(device
);
14285 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14286 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14287 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14288 hr
= IDirect3DDevice3_EndScene(device
);
14289 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14291 /* Map the last quad while the draw is in progress. */
14292 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
14293 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14294 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
14295 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14296 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14298 colour
= get_surface_color(rt
, 320, 240);
14299 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
14300 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
14301 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
14303 IDirect3DVertexBuffer_Release(buffer
);
14306 destroy_viewport(device
, viewport
);
14307 IDirectDrawSurface4_Release(rt
);
14308 IDirect3D3_Release(d3d
);
14309 refcount
= IDirect3DDevice3_Release(device
);
14310 ok(!refcount
, "Device has %u references left.\n", refcount
);
14311 DestroyWindow(window
);
14314 static void test_depth_readback(void)
14316 DWORD depth
, expected_depth
, max_diff
;
14317 IDirectDrawSurface4
*rt
, *ds
;
14318 IDirect3DViewport3
*viewport
;
14319 DDSURFACEDESC2 surface_desc
;
14320 IDirect3DDevice3
*device
;
14321 unsigned int i
, x
, y
;
14322 IDirectDraw4
*ddraw
;
14329 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14332 struct vec3 position
;
14337 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
14338 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14339 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
14340 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
14343 static const struct
14345 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
14350 {16, 0, 0x0000ffff, 0x00000000},
14351 {24, 0, 0x00ffffff, 0x00000000},
14352 {32, 0, 0x00ffffff, 0x00000000},
14353 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
14354 {32, 0, 0xffffffff, 0x00000000},
14357 window
= create_window();
14358 ok(!!window
, "Failed to create a window.\n");
14360 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14362 skip("Failed to create a D3D device, skipping tests.\n");
14363 DestroyWindow(window
);
14367 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14368 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14369 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14370 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
14372 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14373 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14374 viewport
= create_viewport(device
, 0, 0, 640, 480);
14375 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14376 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14378 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14379 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
14381 ds
= get_depth_stencil(device
);
14382 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
14383 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
14384 IDirectDrawSurface4_Release(ds
);
14386 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14388 memset(&surface_desc
, 0, sizeof(surface_desc
));
14389 surface_desc
.dwSize
= sizeof(surface_desc
);
14390 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
14391 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
14392 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
14393 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
14394 if (tests
[i
].s_depth
)
14395 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
14396 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
14397 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
14398 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
14399 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
14400 surface_desc
.dwWidth
= 640;
14401 surface_desc
.dwHeight
= 480;
14402 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
14405 skip("Format %u not supported, skipping test.\n", i
);
14409 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
14410 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
14411 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
14412 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
14414 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
14415 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
14416 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14417 hr
= IDirect3DDevice3_BeginScene(device
);
14418 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14419 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
14420 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14421 hr
= IDirect3DDevice3_EndScene(device
);
14422 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14424 for (y
= 60; y
< 480; y
+= 120)
14426 for (x
= 80; x
< 640; x
+= 160)
14428 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
14429 memset(&surface_desc
, 0, sizeof(surface_desc
));
14430 surface_desc
.dwSize
= sizeof(surface_desc
);
14431 hr
= IDirectDrawSurface4_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
14432 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14434 depth
= *((DWORD
*)surface_desc
.lpSurface
) & tests
[i
].z_mask
;
14435 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
14436 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
14437 todo_wine_if(tests
[i
].todo
)
14438 ok(abs(expected_depth
- depth
) <= max_diff
,
14439 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
14440 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
14442 hr
= IDirectDrawSurface4_Unlock(ds
, &r
);
14443 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14447 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
14448 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
14449 IDirectDrawSurface4_Release(ds
);
14452 destroy_viewport(device
, viewport
);
14453 IDirectDrawSurface4_Release(rt
);
14454 IDirectDraw4_Release(ddraw
);
14455 IDirect3D3_Release(d3d
);
14456 refcount
= IDirect3DDevice3_Release(device
);
14457 ok(!refcount
, "Device has %u references left.\n", refcount
);
14458 DestroyWindow(window
);
14461 static void test_clear(void)
14463 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
14464 IDirect3DViewport3
*viewport
, *viewport2
, *viewport3
;
14465 IDirect3DDevice3
*device
;
14466 IDirectDrawSurface4
*rt
;
14467 IDirectDraw4
*ddraw
;
14475 window
= create_window();
14476 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14478 skip("Failed to create 3D device.\n");
14479 DestroyWindow(window
);
14483 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14484 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14485 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14486 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
14488 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14489 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14491 viewport
= create_viewport(device
, 0, 0, 640, 480);
14492 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14493 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14495 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
14496 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14498 /* Positive x, negative y. */
14499 U1(rect
[0]).x1
= 0;
14500 U2(rect
[0]).y1
= 480;
14501 U3(rect
[0]).x2
= 320;
14502 U4(rect
[0]).y2
= 240;
14504 /* Positive x, positive y. */
14505 U1(rect
[1]).x1
= 0;
14506 U2(rect
[1]).y1
= 0;
14507 U3(rect
[1]).x2
= 320;
14508 U4(rect
[1]).y2
= 240;
14510 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
14511 * refuse negative rectangles, but it will not clear them either. */
14512 hr
= IDirect3DViewport3_Clear2(viewport
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
14513 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14515 color
= get_surface_color(rt
, 160, 360);
14516 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
14517 color
= get_surface_color(rt
, 160, 120);
14518 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
14519 color
= get_surface_color(rt
, 480, 360);
14520 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
14521 color
= get_surface_color(rt
, 480, 120);
14522 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
14524 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
14525 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14526 /* negative x, negative y.
14527 * Also ignored, except on WARP, which clears the entire screen. */
14528 rect_negneg
.x1
= 640;
14529 rect_negneg
.y1
= 240;
14530 rect_negneg
.x2
= 320;
14531 rect_negneg
.y2
= 0;
14532 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14533 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14535 color
= get_surface_color(rt
, 160, 360);
14536 ok(compare_color(color
, 0x00ffffff, 0)
14537 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14538 "Got unexpected color 0x%08x.\n", color
);
14539 color
= get_surface_color(rt
, 160, 120);
14540 ok(compare_color(color
, 0x00ffffff, 0)
14541 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14542 "Got unexpected color 0x%08x.\n", color
);
14543 color
= get_surface_color(rt
, 480, 360);
14544 ok(compare_color(color
, 0x00ffffff, 0)
14545 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14546 "Got unexpected color 0x%08x.\n", color
);
14547 color
= get_surface_color(rt
, 480, 120);
14548 ok(compare_color(color
, 0x00ffffff, 0)
14549 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14550 "Got unexpected color 0x%08x.\n", color
);
14552 /* Test how the viewport affects clears. */
14553 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
14554 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14556 viewport2
= create_viewport(device
, 160, 120, 160, 120);
14557 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport2
);
14558 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14560 hr
= IDirect3DViewport3_Clear2(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14561 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14563 viewport3
= create_viewport(device
, 320, 240, 320, 240);
14564 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
14565 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14567 U1(rect
[0]).x1
= 160;
14568 U2(rect
[0]).y1
= 120;
14569 U3(rect
[0]).x2
= 480;
14570 U4(rect
[0]).y2
= 360;
14571 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14572 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14574 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14575 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14577 color
= get_surface_color(rt
, 158, 118);
14578 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
14579 color
= get_surface_color(rt
, 162, 118);
14580 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
14581 color
= get_surface_color(rt
, 158, 122);
14582 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
14583 color
= get_surface_color(rt
, 162, 122);
14584 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
14586 color
= get_surface_color(rt
, 318, 238);
14587 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
14588 color
= get_surface_color(rt
, 322, 238);
14589 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
14590 color
= get_surface_color(rt
, 318, 242);
14591 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
14592 color
= get_surface_color(rt
, 322, 242);
14593 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
14595 color
= get_surface_color(rt
, 478, 358);
14596 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
14597 color
= get_surface_color(rt
, 482, 358);
14598 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
14599 color
= get_surface_color(rt
, 478, 362);
14600 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
14601 color
= get_surface_color(rt
, 482, 362);
14602 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
14604 /* The clear rectangle is rendertarget absolute, not relative to the
14606 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
14607 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14608 U1(rect
[0]).x1
= 330;
14609 U2(rect
[0]).y1
= 250;
14610 U3(rect
[0]).x2
= 340;
14611 U4(rect
[0]).y2
= 260;
14612 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14613 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14615 color
= get_surface_color(rt
, 328, 248);
14616 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
14617 color
= get_surface_color(rt
, 332, 248);
14618 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
14619 color
= get_surface_color(rt
, 328, 252);
14620 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
14621 color
= get_surface_color(rt
, 332, 252);
14622 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
14624 color
= get_surface_color(rt
, 338, 248);
14625 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
14626 color
= get_surface_color(rt
, 342, 248);
14627 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
14628 color
= get_surface_color(rt
, 338, 252);
14629 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
14630 color
= get_surface_color(rt
, 342, 252);
14631 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
14633 color
= get_surface_color(rt
, 328, 258);
14634 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
14635 color
= get_surface_color(rt
, 332, 258);
14636 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
14637 color
= get_surface_color(rt
, 328, 262);
14638 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
14639 color
= get_surface_color(rt
, 332, 262);
14640 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
14642 color
= get_surface_color(rt
, 338, 258);
14643 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
14644 color
= get_surface_color(rt
, 342, 258);
14645 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
14646 color
= get_surface_color(rt
, 338, 262);
14647 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
14648 color
= get_surface_color(rt
, 342, 262);
14649 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
14651 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
14654 IDirect3DViewport3_Release(viewport3
);
14655 IDirect3DViewport3_Release(viewport2
);
14656 IDirect3DViewport3_Release(viewport
);
14657 IDirectDrawSurface4_Release(rt
);
14658 IDirectDraw4_Release(ddraw
);
14659 IDirect3D3_Release(d3d
);
14660 refcount
= IDirect3DDevice3_Release(device
);
14661 ok(!refcount
, "Device has %u references left.\n", refcount
);
14662 DestroyWindow(window
);
14665 struct enum_surfaces_param
14667 IDirectDrawSurface4
*surfaces
[8];
14668 unsigned int count
;
14671 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
14673 struct enum_surfaces_param
*param
= context
;
14674 BOOL found
= FALSE
;
14677 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
14679 if (param
->surfaces
[i
] == surface
)
14686 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
14687 IDirectDrawSurface4_Release(surface
);
14690 return DDENUMRET_OK
;
14693 static void test_enum_surfaces(void)
14695 struct enum_surfaces_param param
= {{0}};
14696 DDSURFACEDESC2 desc
;
14697 IDirectDraw4
*ddraw
;
14700 ddraw
= create_ddraw();
14701 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14703 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
14704 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14706 memset(&desc
, 0, sizeof(desc
));
14707 desc
.dwSize
= sizeof(desc
);
14708 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
14709 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
14710 U2(desc
).dwMipMapCount
= 3;
14712 desc
.dwHeight
= 32;
14713 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
14714 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
14716 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
14717 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
14718 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
14719 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
14720 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
14721 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14722 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
14724 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14725 &desc
, ¶m
, enum_surfaces_cb
);
14726 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
14727 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14730 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
14731 NULL
, ¶m
, enum_surfaces_cb
);
14732 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
14733 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
14735 IDirectDrawSurface4_Release(param
.surfaces
[2]);
14736 IDirectDrawSurface4_Release(param
.surfaces
[1]);
14737 IDirectDrawSurface4_Release(param
.surfaces
[0]);
14738 IDirectDraw4_Release(ddraw
);
14743 DDDEVICEIDENTIFIER identifier
;
14744 DEVMODEW current_mode
;
14745 IDirectDraw4
*ddraw
;
14748 if (!(ddraw
= create_ddraw()))
14750 skip("Failed to create a ddraw object, skipping tests.\n");
14754 if (ddraw_get_identifier(ddraw
, &identifier
))
14756 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
14757 trace("Description string: \"%s\"\n", identifier
.szDescription
);
14758 trace("Driver version %d.%d.%d.%d\n",
14759 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
14760 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
14762 IDirectDraw4_Release(ddraw
);
14764 memset(¤t_mode
, 0, sizeof(current_mode
));
14765 current_mode
.dmSize
= sizeof(current_mode
);
14766 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
14767 registry_mode
.dmSize
= sizeof(registry_mode
);
14768 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
14769 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
14770 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
14772 skip("Current mode does not match registry mode, skipping test.\n");
14776 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
14777 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
14779 test_process_vertices();
14780 test_coop_level_create_device_window();
14781 test_clipper_blt();
14782 test_coop_level_d3d_state();
14783 test_surface_interface_mismatch();
14784 test_coop_level_threaded();
14786 test_texture_load_ckey();
14795 test_window_style();
14796 test_redundant_mode_set();
14797 test_coop_level_mode_set();
14798 test_coop_level_mode_set_multi();
14800 test_coop_level_surf_create();
14802 test_coop_level_multi_window();
14803 test_draw_strided();
14805 test_specular_lighting();
14806 test_clear_rect_count();
14807 test_coop_level_versions();
14808 test_lighting_interface_versions();
14809 test_coop_level_activateapp();
14810 test_texturemanage();
14811 test_block_formats_creation();
14812 test_unsupported_formats();
14814 test_primary_caps();
14815 test_surface_lock();
14816 test_surface_discard();
14818 test_set_surface_desc();
14819 test_user_memory_getdc();
14820 test_sysmem_overlay();
14821 test_primary_palette();
14822 test_surface_attachment();
14823 test_private_data();
14824 test_pixel_format();
14825 test_create_surface_pitch();
14827 test_palette_complex();
14830 test_palette_gdi();
14831 test_palette_alpha();
14832 test_vb_writeonly();
14833 test_lost_device();
14834 test_surface_desc_lock();
14835 test_texturemapblend();
14836 test_signed_formats();
14838 test_texcoordindex();
14839 test_colorkey_precision();
14840 test_range_colorkey();
14842 test_lockrect_invalid();
14843 test_yv12_overlay();
14844 test_offscreen_overlay();
14845 test_overlay_rect();
14847 test_blt_z_alpha();
14848 test_color_clamping();
14850 test_draw_primitive();
14851 test_edge_antialiasing_blending();
14852 test_transform_vertices();
14853 test_display_mode_surface_pixel_format();
14854 test_surface_desc_size();
14855 test_get_surface_from_dc();
14856 test_ck_operation();
14857 test_vb_refcount();
14858 test_compute_sphere_visibility();
14859 test_texture_stages_limits();
14860 test_set_render_state();
14861 test_map_synchronisation();
14862 test_depth_readback();
14864 test_enum_surfaces();