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"
23 #include "wine/heap.h"
29 HRESULT WINAPI
GetSurfaceFromDC(HDC dc
, struct IDirectDrawSurface
**surface
, HDC
*device_dc
);
31 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
32 static DEVMODEW registry_mode
;
34 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
51 struct create_window_thread_param
54 HANDLE window_created
;
55 HANDLE destroy_window
;
59 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
69 if (abs(x
- y
) > ulps
)
75 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
77 return compare_float(vec
->x
, x
, ulps
)
78 && compare_float(vec
->y
, y
, ulps
)
79 && compare_float(vec
->z
, z
, ulps
)
80 && compare_float(vec
->w
, w
, ulps
);
83 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
85 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
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
;
95 static BOOL
ddraw_get_identifier(IDirectDraw4
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
99 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw
, identifier
, 0);
100 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
102 return SUCCEEDED(hr
);
105 static BOOL
ddraw_is_warp(IDirectDraw4
*ddraw
)
107 DDDEVICEIDENTIFIER identifier
;
109 return strcmp(winetest_platform
, "wine")
110 && ddraw_get_identifier(ddraw
, &identifier
)
111 && strstr(identifier
.szDriver
, "warp");
114 static BOOL
ddraw_is_vendor(IDirectDraw4
*ddraw
, DWORD vendor
)
116 DDDEVICEIDENTIFIER identifier
;
118 return strcmp(winetest_platform
, "wine")
119 && ddraw_get_identifier(ddraw
, &identifier
)
120 && identifier
.dwVendorId
== vendor
;
123 static BOOL
ddraw_is_intel(IDirectDraw4
*ddraw
)
125 return ddraw_is_vendor(ddraw
, 0x8086);
128 static BOOL
ddraw_is_nvidia(IDirectDraw4
*ddraw
)
130 return ddraw_is_vendor(ddraw
, 0x10de);
133 static BOOL
ddraw_is_vmware(IDirectDraw4
*ddraw
)
135 return ddraw_is_vendor(ddraw
, 0x15ad);
138 static IDirectDrawSurface4
*create_overlay(IDirectDraw4
*ddraw
,
139 unsigned int width
, unsigned int height
, DWORD format
)
141 IDirectDrawSurface4
*surface
;
144 memset(&desc
, 0, sizeof(desc
));
145 desc
.dwSize
= sizeof(desc
);
146 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
147 desc
.dwWidth
= width
;
148 desc
.dwHeight
= height
;
149 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
150 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
151 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
152 U4(desc
).ddpfPixelFormat
.dwFourCC
= format
;
154 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
159 static HWND
create_window(void)
161 RECT r
= {0, 0, 640, 480};
163 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
165 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
166 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
169 static DWORD WINAPI
create_window_thread_proc(void *param
)
171 struct create_window_thread_param
*p
= param
;
175 p
->window
= create_window();
176 ret
= SetEvent(p
->window_created
);
177 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
183 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
184 DispatchMessageA(&msg
);
185 res
= WaitForSingleObject(p
->destroy_window
, 100);
186 if (res
== WAIT_OBJECT_0
)
188 if (res
!= WAIT_TIMEOUT
)
190 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
195 DestroyWindow(p
->window
);
200 static void create_window_thread(struct create_window_thread_param
*p
)
204 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
205 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
206 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
207 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
208 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
209 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
210 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
211 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
214 static void destroy_window_thread(struct create_window_thread_param
*p
)
216 SetEvent(p
->destroy_window
);
217 WaitForSingleObject(p
->thread
, INFINITE
);
218 CloseHandle(p
->destroy_window
);
219 CloseHandle(p
->window_created
);
220 CloseHandle(p
->thread
);
223 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
225 IDirectDrawSurface4
*rt
, *ret
;
226 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, {0}};
229 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
230 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
231 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
232 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
233 IDirectDrawSurface4_Release(rt
);
237 static HRESULT
set_display_mode(IDirectDraw4
*ddraw
, DWORD width
, DWORD height
)
239 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
241 return IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
244 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
246 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
247 DDSURFACEDESC2 surface_desc
;
251 memset(&surface_desc
, 0, sizeof(surface_desc
));
252 surface_desc
.dwSize
= sizeof(surface_desc
);
254 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
255 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
259 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
261 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
262 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
267 static void check_rect(IDirectDrawSurface4
*surface
, RECT r
, const char *message
)
269 LONG x_coords
[2][2] =
271 {r
.left
- 1, r
.left
+ 1},
272 {r
.right
+ 1, r
.right
- 1},
274 LONG y_coords
[2][2] =
276 {r
.top
- 1, r
.top
+ 1},
277 {r
.bottom
+ 1, r
.bottom
- 1}
279 unsigned int i
, j
, x_side
, y_side
;
283 for (i
= 0; i
< 2; ++i
)
285 for (j
= 0; j
< 2; ++j
)
287 for (x_side
= 0; x_side
< 2; ++x_side
)
289 for (y_side
= 0; y_side
< 2; ++y_side
)
291 DWORD expected
= (x_side
== 1 && y_side
== 1) ? 0x00ffffff : 0x00000000;
293 x
= x_coords
[i
][x_side
];
294 y
= y_coords
[j
][y_side
];
295 if (x
< 0 || x
>= 640 || y
< 0 || y
>= 480)
297 color
= get_surface_color(surface
, x
, y
);
298 ok(color
== expected
, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
299 message
, x
, y
, color
, expected
);
306 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
308 DDPIXELFORMAT
*z_fmt
= ctx
;
310 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
316 static IDirectDraw4
*create_ddraw(void)
318 IDirectDraw4
*ddraw4
;
322 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
325 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
326 IDirectDraw_Release(ddraw1
);
333 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
335 IDirectDrawSurface4
*surface
, *ds
;
336 IDirect3DDevice3
*device
= NULL
;
337 DDSURFACEDESC2 surface_desc
;
338 IDirectDraw4
*ddraw4
;
343 if (!(ddraw4
= create_ddraw()))
346 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
347 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
349 memset(&surface_desc
, 0, sizeof(surface_desc
));
350 surface_desc
.dwSize
= sizeof(surface_desc
);
351 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
352 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
353 surface_desc
.dwWidth
= 640;
354 surface_desc
.dwHeight
= 480;
356 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
357 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
359 if (coop_level
& DDSCL_NORMAL
)
361 IDirectDrawClipper
*clipper
;
363 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
364 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
365 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
366 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
367 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
368 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
369 IDirectDrawClipper_Release(clipper
);
372 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
373 IDirectDraw4_Release(ddraw4
);
376 IDirectDrawSurface4_Release(surface
);
380 memset(&z_fmt
, 0, sizeof(z_fmt
));
381 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
382 if (FAILED(hr
) || !z_fmt
.dwSize
)
384 IDirect3D3_Release(d3d3
);
385 IDirectDrawSurface4_Release(surface
);
389 memset(&surface_desc
, 0, sizeof(surface_desc
));
390 surface_desc
.dwSize
= sizeof(surface_desc
);
391 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
392 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
393 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
394 surface_desc
.dwWidth
= 640;
395 surface_desc
.dwHeight
= 480;
396 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
397 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
400 IDirect3D3_Release(d3d3
);
401 IDirectDrawSurface4_Release(surface
);
405 hr
= IDirectDrawSurface4_AddAttachedSurface(surface
, ds
);
406 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
407 IDirectDrawSurface4_Release(ds
);
410 IDirect3D3_Release(d3d3
);
411 IDirectDrawSurface4_Release(surface
);
415 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
416 IDirect3D3_Release(d3d3
);
417 IDirectDrawSurface4_Release(surface
);
424 static IDirect3DViewport3
*create_viewport(IDirect3DDevice3
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
426 IDirect3DViewport3
*viewport
;
431 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
432 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
433 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
434 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
435 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
436 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
437 memset(&vp
, 0, sizeof(vp
));
438 vp
.dwSize
= sizeof(vp
);
445 vp
.dvClipWidth
= 2.0f
;
446 vp
.dvClipHeight
= 2.0f
;
449 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
450 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
451 IDirect3D3_Release(d3d
);
456 static void destroy_viewport(IDirect3DDevice3
*device
, IDirect3DViewport3
*viewport
)
460 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
461 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
462 IDirect3DViewport3_Release(viewport
);
465 static IDirect3DMaterial3
*create_material(IDirect3DDevice3
*device
, D3DMATERIAL
*mat
)
467 IDirect3DMaterial3
*material
;
471 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
472 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
473 hr
= IDirect3D3_CreateMaterial(d3d
, &material
, NULL
);
474 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
475 hr
= IDirect3DMaterial3_SetMaterial(material
, mat
);
476 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
477 IDirect3D3_Release(d3d
);
482 static IDirect3DMaterial3
*create_diffuse_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
486 memset(&mat
, 0, sizeof(mat
));
487 mat
.dwSize
= sizeof(mat
);
488 U1(U(mat
).diffuse
).r
= r
;
489 U2(U(mat
).diffuse
).g
= g
;
490 U3(U(mat
).diffuse
).b
= b
;
491 U4(U(mat
).diffuse
).a
= a
;
493 return create_material(device
, &mat
);
496 static IDirect3DMaterial3
*create_diffuse_and_ambient_material(IDirect3DDevice3
*device
,
497 float r
, float g
, float b
, float a
)
501 memset(&mat
, 0, sizeof(mat
));
502 mat
.dwSize
= sizeof(mat
);
503 U1(U(mat
).diffuse
).r
= r
;
504 U2(U(mat
).diffuse
).g
= g
;
505 U3(U(mat
).diffuse
).b
= b
;
506 U4(U(mat
).diffuse
).a
= a
;
508 U1(U(mat
).ambient
).r
= r
;
509 U2(U(mat
).ambient
).g
= g
;
510 U3(U(mat
).ambient
).b
= b
;
511 U4(U(mat
).ambient
).a
= a
;
513 return create_material(device
, &mat
);
516 static IDirect3DMaterial3
*create_specular_material(IDirect3DDevice3
*device
,
517 float r
, float g
, float b
, float a
, float power
)
521 memset(&mat
, 0, sizeof(mat
));
522 mat
.dwSize
= sizeof(mat
);
523 U1(U2(mat
).specular
).r
= r
;
524 U2(U2(mat
).specular
).g
= g
;
525 U3(U2(mat
).specular
).b
= b
;
526 U4(U2(mat
).specular
).a
= a
;
527 U4(mat
).power
= power
;
529 return create_material(device
, &mat
);
532 static IDirect3DMaterial3
*create_emissive_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
536 memset(&mat
, 0, sizeof(mat
));
537 mat
.dwSize
= sizeof(mat
);
538 U1(U3(mat
).emissive
).r
= r
;
539 U2(U3(mat
).emissive
).g
= g
;
540 U3(U3(mat
).emissive
).b
= b
;
541 U4(U3(mat
).emissive
).a
= a
;
543 return create_material(device
, &mat
);
546 static void destroy_material(IDirect3DMaterial3
*material
)
548 IDirect3DMaterial3_Release(material
);
555 WPARAM expect_wparam
;
559 static const struct message
*expect_messages
;
560 static IDirectDraw4
*focus_test_ddraw
;
562 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
566 if (expect_messages
&& message
== expect_messages
->message
)
568 if (expect_messages
->check_wparam
)
569 ok (wparam
== expect_messages
->expect_wparam
,
570 "Got unexpected wparam %lx for message %x, expected %lx.\n",
571 wparam
, message
, expect_messages
->expect_wparam
);
573 if (focus_test_ddraw
)
575 hr
= IDirectDraw4_TestCooperativeLevel(focus_test_ddraw
);
576 ok(hr
== expect_messages
->ddraw_state
, "Got ddraw state %#x on message %#x, expected %#x.\n",
577 hr
, message
, expect_messages
->ddraw_state
);
583 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
586 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
587 * interface. This prevents subsequent SetCooperativeLevel() calls on a
588 * different window from failing with DDERR_HWNDALREADYSET. */
589 static void fix_wndproc(HWND window
, LONG_PTR proc
)
594 if (!(ddraw
= create_ddraw()))
597 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
598 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
599 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
600 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
601 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
603 IDirectDraw4_Release(ddraw
);
606 static void test_process_vertices(void)
608 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
609 IDirect3DViewport3
*viewport
;
610 D3DVERTEXBUFFERDESC vb_desc
;
611 IDirect3DDevice3
*device
;
612 struct vec3
*src_data
;
613 struct vec4
*dst_data
;
620 static D3DMATRIX identity
=
622 1.0f
, 0.0f
, 0.0f
, 0.0f
,
623 0.0f
, 1.0f
, 0.0f
, 0.0f
,
624 0.0f
, 0.0f
, 1.0f
, 0.0f
,
625 0.0f
, 0.0f
, 0.0f
, 1.0f
,
627 static D3DMATRIX projection
=
629 1.0f
, 0.0f
, 0.0f
, 0.0f
,
630 0.0f
, 1.0f
, 0.0f
, 0.0f
,
631 0.0f
, 0.0f
, 1.0f
, 0.0f
,
632 6.0f
, 7.0f
, 8.0f
, 1.0f
,
635 window
= create_window();
636 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
638 skip("Failed to create a 3D device, skipping test.\n");
639 DestroyWindow(window
);
643 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
644 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
646 memset(&vb_desc
, 0, sizeof(vb_desc
));
647 vb_desc
.dwSize
= sizeof(vb_desc
);
648 vb_desc
.dwFVF
= D3DFVF_XYZ
;
649 vb_desc
.dwNumVertices
= 3;
650 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
651 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
653 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
654 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
655 src_data
[0].x
= -1.0f
;
656 src_data
[0].y
= -1.0f
;
657 src_data
[0].z
= -1.0f
;
658 src_data
[1].x
= 0.0f
;
659 src_data
[1].y
= 0.0f
;
660 src_data
[1].z
= 0.0f
;
661 src_data
[2].x
= 1.0f
;
662 src_data
[2].y
= 1.0f
;
663 src_data
[2].z
= 1.0f
;
664 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
665 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
667 memset(&vb_desc
, 0, sizeof(vb_desc
));
668 vb_desc
.dwSize
= sizeof(vb_desc
);
669 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
670 vb_desc
.dwNumVertices
= 3;
671 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
672 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
674 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
675 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
676 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
677 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
678 vp2
.dwSize
= sizeof(vp2
);
685 vp2
.dvClipWidth
= 4.0f
;
686 vp2
.dvClipHeight
= 5.0f
;
689 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
690 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
691 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
692 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
694 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
695 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
696 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
697 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
698 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
699 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
701 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
702 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
704 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
705 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
706 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
707 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
708 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
709 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
710 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
711 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
712 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
713 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
714 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
715 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
716 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
718 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
719 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
721 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
722 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
724 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
725 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
726 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
727 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
728 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
729 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
730 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
731 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
732 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
733 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
734 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
735 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
736 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
738 vp2
.dwSize
= sizeof(vp2
);
745 vp2
.dvClipWidth
= 2.0f
;
746 vp2
.dvClipHeight
= 4.0f
;
749 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
750 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
752 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
753 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
755 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
756 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
757 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
758 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
759 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
760 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
761 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
762 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
763 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
764 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
765 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
766 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
767 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
769 vp1
.dwSize
= sizeof(vp1
);
780 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
781 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
783 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
784 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
786 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
787 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
788 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
789 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
790 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
791 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
792 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
793 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
794 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
795 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
796 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
797 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
798 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
800 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
801 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
803 IDirect3DVertexBuffer_Release(dst_vb
);
804 IDirect3DVertexBuffer_Release(src_vb
);
805 IDirect3DViewport3_Release(viewport
);
806 IDirect3D3_Release(d3d3
);
807 IDirect3DDevice3_Release(device
);
808 DestroyWindow(window
);
811 static void test_coop_level_create_device_window(void)
813 HWND focus_window
, device_window
;
817 focus_window
= create_window();
818 ddraw
= create_ddraw();
819 ok(!!ddraw
, "Failed to create a ddraw object.\n");
821 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
822 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
823 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
824 ok(!device_window
, "Unexpected device window found.\n");
825 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
826 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
827 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
828 ok(!device_window
, "Unexpected device window found.\n");
829 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
830 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
831 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
832 ok(!device_window
, "Unexpected device window found.\n");
833 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
834 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
835 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
836 ok(!device_window
, "Unexpected device window found.\n");
837 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
838 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
839 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
840 ok(!device_window
, "Unexpected device window found.\n");
842 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
843 if (broken(hr
== DDERR_INVALIDPARAMS
))
845 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
846 IDirectDraw4_Release(ddraw
);
847 DestroyWindow(focus_window
);
851 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
852 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
853 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
854 ok(!device_window
, "Unexpected device window found.\n");
855 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
856 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
857 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
858 ok(!device_window
, "Unexpected device window found.\n");
860 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
861 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
862 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
863 ok(!device_window
, "Unexpected device window found.\n");
864 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
865 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
866 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
867 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
868 ok(!!device_window
, "Device window not found.\n");
870 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
871 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
872 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
873 ok(!device_window
, "Unexpected device window found.\n");
874 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
875 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
876 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
877 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
878 ok(!!device_window
, "Device window not found.\n");
880 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
881 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
882 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
883 ok(!device_window
, "Unexpected device window found.\n");
884 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
885 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
886 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
887 ok(!device_window
, "Unexpected device window found.\n");
888 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
889 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
890 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
891 ok(!device_window
, "Unexpected device window found.\n");
892 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
893 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
894 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
895 ok(!!device_window
, "Device window not found.\n");
897 IDirectDraw4_Release(ddraw
);
898 DestroyWindow(focus_window
);
901 static void test_clipper_blt(void)
903 IDirectDrawSurface4
*src_surface
, *dst_surface
;
904 RECT client_rect
, src_rect
;
905 IDirectDrawClipper
*clipper
;
906 DDSURFACEDESC2 surface_desc
;
907 unsigned int i
, j
, x
, y
;
919 static const DWORD src_data
[] =
921 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
922 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
923 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
925 static const D3DCOLOR expected1
[] =
927 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
928 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
929 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
930 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
932 /* Nvidia on Windows seems to have an off-by-one error
933 * when processing source rectangles. Our left = 1 and
934 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
935 * read as well, but only for the edge pixels on the
936 * output image. The bug happens on the y axis as well,
937 * but we only read one row there, and all source rows
938 * contain the same data. This bug is not dependent on
939 * the presence of a clipper. */
940 static const D3DCOLOR expected1_broken
[] =
942 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
943 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
944 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
945 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
947 static const D3DCOLOR expected2
[] =
949 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
950 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
951 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
952 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
955 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
956 10, 10, 640, 480, 0, 0, 0, 0);
957 ShowWindow(window
, SW_SHOW
);
958 ddraw
= create_ddraw();
959 ok(!!ddraw
, "Failed to create a ddraw object.\n");
961 ret
= GetClientRect(window
, &client_rect
);
962 ok(ret
, "Failed to get client rect.\n");
963 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
964 ok(ret
, "Failed to map client rect.\n");
966 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
967 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
969 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
970 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
971 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
972 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
973 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
974 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
975 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
976 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
977 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
978 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
979 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
980 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
981 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
982 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
983 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
984 "Got unexpected bounding rect %s, expected %s.\n",
985 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
986 HeapFree(GetProcessHeap(), 0, rgn_data
);
988 r1
= CreateRectRgn(0, 0, 320, 240);
989 ok(!!r1
, "Failed to create region.\n");
990 r2
= CreateRectRgn(320, 240, 640, 480);
991 ok(!!r2
, "Failed to create region.\n");
992 CombineRgn(r1
, r1
, r2
, RGN_OR
);
993 ret
= GetRegionData(r1
, 0, NULL
);
994 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
995 ret
= GetRegionData(r1
, ret
, rgn_data
);
996 ok(!!ret
, "Failed to get region data.\n");
1001 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1002 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
1003 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1004 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1005 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
1006 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1008 HeapFree(GetProcessHeap(), 0, rgn_data
);
1010 memset(&surface_desc
, 0, sizeof(surface_desc
));
1011 surface_desc
.dwSize
= sizeof(surface_desc
);
1012 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1013 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
1014 surface_desc
.dwWidth
= 640;
1015 surface_desc
.dwHeight
= 480;
1016 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1017 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1018 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1019 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1020 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1021 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1023 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
1024 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
1025 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
1026 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1028 memset(&fx
, 0, sizeof(fx
));
1029 fx
.dwSize
= sizeof(fx
);
1030 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1031 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
1032 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1033 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
1035 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
1036 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
1037 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
1038 ptr
= surface_desc
.lpSurface
;
1039 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
1040 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
1041 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
1042 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
1043 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
1045 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
1046 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
1048 SetRect(&src_rect
, 1, 1, 5, 2);
1049 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
1050 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
1051 for (i
= 0; i
< 4; ++i
)
1053 for (j
= 0; j
< 4; ++j
)
1055 x
= 80 * ((2 * j
) + 1);
1056 y
= 60 * ((2 * i
) + 1);
1057 color
= get_surface_color(dst_surface
, x
, y
);
1058 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
1059 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
1060 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
1064 U5(fx
).dwFillColor
= 0xff0000ff;
1065 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1066 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
1067 for (i
= 0; i
< 4; ++i
)
1069 for (j
= 0; j
< 4; ++j
)
1071 x
= 80 * ((2 * j
) + 1);
1072 y
= 60 * ((2 * i
) + 1);
1073 color
= get_surface_color(dst_surface
, x
, y
);
1074 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1075 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1079 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1080 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
1082 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1083 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1084 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1085 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1086 DestroyWindow(window
);
1087 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1088 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
1089 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1090 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1091 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1092 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1093 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1094 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1095 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1096 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1097 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1098 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1100 IDirectDrawSurface4_Release(dst_surface
);
1101 IDirectDrawSurface4_Release(src_surface
);
1102 refcount
= IDirectDrawClipper_Release(clipper
);
1103 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
1104 IDirectDraw4_Release(ddraw
);
1107 static void test_coop_level_d3d_state(void)
1109 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1110 IDirectDrawSurface4
*rt
, *surface
;
1111 IDirect3DViewport3
*viewport
;
1112 IDirect3DDevice3
*device
;
1113 IDirectDraw4
*ddraw
;
1120 window
= create_window();
1121 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1123 skip("Failed to create a 3D device, skipping test.\n");
1124 DestroyWindow(window
);
1128 viewport
= create_viewport(device
, 0, 0, 640, 480);
1130 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1131 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1132 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1133 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1134 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1135 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1136 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1137 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1138 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1139 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
1140 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1141 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1142 color
= get_surface_color(rt
, 320, 240);
1143 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1145 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1146 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1147 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1148 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1149 IDirect3D3_Release(d3d
);
1150 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1151 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1152 hr
= IDirectDrawSurface4_IsLost(rt
);
1153 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1154 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
1155 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
1156 IDirectDraw4_Release(ddraw
);
1158 hr
= IDirect3DDevice3_GetRenderTarget(device
, &surface
);
1159 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1160 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1161 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1162 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1163 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1164 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1165 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1166 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1167 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
1168 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1169 color
= get_surface_color(rt
, 320, 240);
1170 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1172 destroy_viewport(device
, viewport
);
1173 IDirectDrawSurface4_Release(surface
);
1174 IDirectDrawSurface4_Release(rt
);
1175 IDirect3DDevice3_Release(device
);
1176 DestroyWindow(window
);
1179 static void test_surface_interface_mismatch(void)
1181 IDirectDraw4
*ddraw
= NULL
;
1182 IDirect3D3
*d3d
= NULL
;
1183 IDirectDrawSurface4
*surface
= NULL
, *ds
;
1184 IDirectDrawSurface3
*surface3
= NULL
;
1185 IDirect3DDevice3
*device
= NULL
;
1186 IDirect3DViewport3
*viewport
= NULL
;
1187 DDSURFACEDESC2 surface_desc
;
1188 DDPIXELFORMAT z_fmt
;
1193 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1195 window
= create_window();
1196 ddraw
= create_ddraw();
1197 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1198 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1199 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1201 memset(&surface_desc
, 0, sizeof(surface_desc
));
1202 surface_desc
.dwSize
= sizeof(surface_desc
);
1203 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1204 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1205 surface_desc
.dwWidth
= 640;
1206 surface_desc
.dwHeight
= 480;
1208 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1209 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1211 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1212 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
1214 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
1216 skip("D3D interface is not available, skipping test.\n");
1220 memset(&z_fmt
, 0, sizeof(z_fmt
));
1221 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
1222 if (FAILED(hr
) || !z_fmt
.dwSize
)
1224 skip("No depth buffer formats available, skipping test.\n");
1228 memset(&surface_desc
, 0, sizeof(surface_desc
));
1229 surface_desc
.dwSize
= sizeof(surface_desc
);
1230 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
1231 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1232 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
1233 surface_desc
.dwWidth
= 640;
1234 surface_desc
.dwHeight
= 480;
1235 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1236 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1240 /* Using a different surface interface version still works */
1241 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1242 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1243 refcount
= IDirectDrawSurface4_Release(ds
);
1244 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1249 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
1250 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1254 viewport
= create_viewport(device
, 0, 0, 640, 480);
1256 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1257 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1258 color
= get_surface_color(surface
, 320, 240);
1259 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1263 destroy_viewport(device
, viewport
);
1264 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1265 if (surface
) IDirectDrawSurface4_Release(surface
);
1266 if (device
) IDirect3DDevice3_Release(device
);
1267 if (d3d
) IDirect3D3_Release(d3d
);
1268 if (ddraw
) IDirectDraw4_Release(ddraw
);
1269 DestroyWindow(window
);
1272 static void test_coop_level_threaded(void)
1274 struct create_window_thread_param p
;
1275 IDirectDraw4
*ddraw
;
1278 ddraw
= create_ddraw();
1279 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1280 create_window_thread(&p
);
1282 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1283 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1285 IDirectDraw4_Release(ddraw
);
1286 destroy_window_thread(&p
);
1289 static void test_depth_blit(void)
1298 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1299 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1300 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1301 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1303 static const D3DCOLOR expected_colors
[4][4] =
1305 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1306 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1307 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1308 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1310 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1312 IDirect3DDevice3
*device
;
1313 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1314 IDirect3DViewport3
*viewport
;
1315 RECT src_rect
, dst_rect
;
1320 IDirectDraw4
*ddraw
;
1325 window
= create_window();
1326 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1328 skip("Failed to create a 3D device, skipping test.\n");
1329 DestroyWindow(window
);
1333 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1334 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1335 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1336 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1337 IDirect3D3_Release(d3d
);
1339 ds1
= get_depth_stencil(device
);
1341 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1342 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1343 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1344 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1345 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1346 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1347 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1348 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1349 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1350 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1351 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1352 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1353 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1354 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1355 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1356 IDirectDraw4_Release(ddraw
);
1358 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1359 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1360 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1362 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1363 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1364 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1365 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1367 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1368 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1369 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1370 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1373 SetRect(&src_rect
, 0, 0, 320, 240);
1374 SetRect(&dst_rect
, 0, 0, 320, 240);
1375 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1376 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1377 /* Different locations. */
1378 SetRect(&src_rect
, 0, 0, 320, 240);
1379 SetRect(&dst_rect
, 320, 240, 640, 480);
1380 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1381 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1383 SetRect(&src_rect
, 0, 0, 320, 240);
1384 SetRect(&dst_rect
, 0, 0, 640, 480);
1385 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1386 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1388 SetRect(&src_rect
, 0, 480, 640, 0);
1389 SetRect(&dst_rect
, 0, 0, 640, 480);
1390 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1391 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1392 SetRect(&src_rect
, 0, 0, 640, 480);
1393 SetRect(&dst_rect
, 0, 480, 640, 0);
1394 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1395 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1396 /* Full, explicit. */
1397 SetRect(&src_rect
, 0, 0, 640, 480);
1398 SetRect(&dst_rect
, 0, 0, 640, 480);
1399 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1400 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1401 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1403 /* Depth blit inside a BeginScene / EndScene pair */
1404 hr
= IDirect3DDevice3_BeginScene(device
);
1405 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1406 /* From the current depth stencil */
1407 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1408 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1409 /* To the current depth stencil */
1410 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1411 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1412 /* Between unbound surfaces */
1413 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1414 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1415 hr
= IDirect3DDevice3_EndScene(device
);
1416 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1418 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1419 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1420 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1421 * a reliable result(z = 0.0) */
1422 memset(&fx
, 0, sizeof(fx
));
1423 fx
.dwSize
= sizeof(fx
);
1424 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1425 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1427 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1428 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1429 SetRect(&dst_rect
, 0, 0, 320, 240);
1430 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1431 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1432 IDirectDrawSurface4_Release(ds3
);
1433 IDirectDrawSurface4_Release(ds2
);
1434 IDirectDrawSurface4_Release(ds1
);
1436 hr
= IDirect3DDevice3_BeginScene(device
);
1437 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1438 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1440 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1441 hr
= IDirect3DDevice3_EndScene(device
);
1442 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1444 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1445 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1446 for (i
= 0; i
< 4; ++i
)
1448 for (j
= 0; j
< 4; ++j
)
1450 unsigned int x
= 80 * ((2 * j
) + 1);
1451 unsigned int y
= 60 * ((2 * i
) + 1);
1452 color
= get_surface_color(rt
, x
, y
);
1453 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1454 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1457 IDirectDrawSurface4_Release(rt
);
1459 destroy_viewport(device
, viewport
);
1460 IDirect3DDevice3_Release(device
);
1461 DestroyWindow(window
);
1464 static void test_texture_load_ckey(void)
1466 IDirectDraw4
*ddraw
;
1467 IDirectDrawSurface4
*src
;
1468 IDirectDrawSurface4
*dst
;
1469 IDirect3DTexture2
*src_tex
;
1470 IDirect3DTexture2
*dst_tex
;
1471 DDSURFACEDESC2 ddsd
;
1475 ddraw
= create_ddraw();
1476 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1477 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1478 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1480 memset(&ddsd
, 0, sizeof(ddsd
));
1481 ddsd
.dwSize
= sizeof(ddsd
);
1482 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1483 ddsd
.dwHeight
= 128;
1485 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1486 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1487 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1488 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1489 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1490 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1492 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1493 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1496 /* 64 bit ddraw does not support d3d */
1497 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1498 IDirectDrawSurface4_Release(dst
);
1499 IDirectDrawSurface4_Release(src
);
1500 IDirectDraw4_Release(ddraw
);
1503 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1504 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1506 /* No surface has a color key */
1507 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1508 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1509 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1510 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1511 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1512 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1513 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1515 /* Source surface has a color key */
1516 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1517 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1518 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1519 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1520 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1521 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1522 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1523 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1524 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1526 /* Both surfaces have a color key: Dest ckey is overwritten */
1527 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1528 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1529 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1530 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1531 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1532 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1533 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1534 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1535 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1537 /* Only the destination has a color key: It is not deleted */
1538 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1539 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1540 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1541 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1542 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1543 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1544 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1545 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1546 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1547 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1549 IDirect3DTexture2_Release(dst_tex
);
1550 IDirect3DTexture2_Release(src_tex
);
1551 IDirectDrawSurface4_Release(dst
);
1552 IDirectDrawSurface4_Release(src
);
1553 IDirectDraw4_Release(ddraw
);
1556 static ULONG
get_refcount(IUnknown
*test_iface
)
1558 IUnknown_AddRef(test_iface
);
1559 return IUnknown_Release(test_iface
);
1562 static void test_viewport_object(void)
1564 IDirectDraw4
*ddraw
;
1566 HRESULT hr
, old_d3d_ref
;
1570 IDirect3DViewport
*viewport
;
1571 IDirect3DViewport2
*viewport2
;
1572 IDirect3DViewport3
*viewport3
, *another_vp
, *test_vp
;
1573 IDirectDrawGammaControl
*gamma
;
1576 IDirect3DDevice3
*device
;
1584 window
= create_window();
1585 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1587 skip("Failed to create a 3D device, skipping test.\n");
1588 DestroyWindow(window
);
1591 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1592 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1593 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1594 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1595 old_d3d_ref
= get_refcount((IUnknown
*) d3d
);
1597 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1598 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1599 ref
= get_refcount((IUnknown
*)viewport3
);
1600 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1601 ref
= get_refcount((IUnknown
*)d3d
);
1602 ok(ref
== old_d3d_ref
, "Got unexpected refcount %u.\n", ref
);
1604 memset(&desc
, 0, sizeof(desc
));
1605 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1606 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1607 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) + 1;
1608 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1609 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1610 desc
.vp1
.dwSize
= sizeof(desc
.vp1
) - 1;
1611 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1612 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1613 desc
.vp1
.dwSize
= sizeof(desc
.vp1
);
1614 hr
= IDirect3DViewport3_GetViewport(viewport3
, &desc
.vp1
);
1615 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1616 ok(desc
.vp1
.dwSize
== sizeof(desc
.vp1
), "Got unexpected dwSize %u.\n", desc
.vp1
.dwSize
);
1617 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &desc
.vp2
);
1618 ok(hr
== D3DERR_VIEWPORTDATANOTSET
, "Got unexpected hr %#x.\n", hr
);
1619 ok(desc
.vp2
.dwSize
== sizeof(desc
.vp2
), "Got unexpected dwSize %u.\n", desc
.vp2
.dwSize
);
1620 desc
.vp2
.dwSize
= sizeof(desc
.vp2
) + 1;
1621 hr
= IDirect3DViewport3_GetViewport2(viewport3
, &desc
.vp2
);
1622 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1624 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1625 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1626 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1627 ok(!gamma
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1628 /* NULL iid: Segfaults */
1630 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1631 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1632 ref
= get_refcount((IUnknown
*)viewport
);
1633 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1634 ref
= get_refcount((IUnknown
*)viewport3
);
1635 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1636 IDirect3DViewport_Release(viewport
);
1639 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1640 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1641 ref
= get_refcount((IUnknown
*)viewport2
);
1642 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1643 ref
= get_refcount((IUnknown
*)viewport3
);
1644 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1645 IDirect3DViewport3_Release(viewport2
);
1647 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IUnknown
, (void **)&unknown
);
1648 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1649 ref
= get_refcount((IUnknown
*)viewport3
);
1650 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1651 ref
= get_refcount(unknown
);
1652 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1653 IUnknown_Release(unknown
);
1655 hr
= IDirect3DDevice3_DeleteViewport(device
, NULL
);
1656 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1657 hr
= IDirect3DDevice3_GetCurrentViewport(device
, NULL
);
1658 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1660 hr
= IDirect3D3_CreateViewport(d3d
, &another_vp
, NULL
);
1661 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1663 /* Setting a viewport not in the viewport list fails */
1664 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1665 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1667 /* AddViewport(NULL): Segfault */
1668 hr
= IDirect3DDevice3_AddViewport(device
, viewport3
);
1669 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1670 ref
= get_refcount((IUnknown
*) viewport3
);
1671 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1672 hr
= IDirect3DDevice3_AddViewport(device
, another_vp
);
1673 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1674 ref
= get_refcount((IUnknown
*) another_vp
);
1675 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1677 test_vp
= (IDirect3DViewport3
*) 0xbaadc0de;
1678 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1679 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1680 ok(test_vp
== (IDirect3DViewport3
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1682 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1683 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1684 ref
= get_refcount((IUnknown
*) viewport3
);
1685 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1686 ref
= get_refcount((IUnknown
*) device
);
1687 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1690 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1691 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1692 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1693 ref
= get_refcount((IUnknown
*) viewport3
);
1694 ok(ref
== 4, "Got unexpected refcount %u.\n", ref
);
1696 IDirect3DViewport3_Release(test_vp
);
1698 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1700 /* Cannot set the viewport to NULL */
1701 hr
= IDirect3DDevice3_SetCurrentViewport(device
, NULL
);
1702 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1704 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1705 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1706 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1708 IDirect3DViewport3_Release(test_vp
);
1710 /* SetCurrentViewport properly releases the old viewport's reference */
1711 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1712 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1713 ref
= get_refcount((IUnknown
*) viewport3
);
1714 ok(ref
== 2, "Got unexpected refcount %u.\n", ref
);
1715 ref
= get_refcount((IUnknown
*) another_vp
);
1716 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1718 /* Unlike device2::DeleteViewport, device3::DeleteViewport releases the
1719 * reference held by SetCurrentViewport */
1720 hr
= IDirect3DDevice3_DeleteViewport(device
, another_vp
);
1721 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1722 ref
= get_refcount((IUnknown
*) another_vp
);
1723 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1725 /* GetCurrentViewport still fails */
1727 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1728 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1729 ok(!test_vp
, "Got unexpected viewport %p\n", test_vp
);
1731 /* Setting a different viewport doesn't have any surprises now */
1732 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1733 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1734 ref
= get_refcount((IUnknown
*) viewport3
);
1735 ok(ref
== 3, "Got unexpected refcount %u.\n", ref
);
1736 ref
= get_refcount((IUnknown
*) another_vp
);
1737 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1739 memset(&vp
, 0, sizeof(vp
));
1740 memset(&vp
, 0, sizeof(vp2
));
1741 vp
.dwSize
= vp2
.dwSize
= 0;
1742 vp
.dwX
= vp2
.dwX
= 0;
1743 vp
.dwY
= vp2
.dwY
= 0;
1744 vp
.dwWidth
= vp2
.dwWidth
= 640;
1745 vp
.dwHeight
= vp2
.dwHeight
= 480;
1746 vp
.dvMinZ
= vp2
.dvMinZ
= 0.0f
;
1747 vp
.dvMaxZ
= vp2
.dvMaxZ
= 1.0f
;
1748 vp
.dvScaleX
= vp
.dwWidth
/ 2.0f
;
1749 vp
.dvScaleY
= vp
.dwHeight
/ 2.0f
;
1752 vp2
.dvClipX
= -1.0f
;
1754 vp2
.dvClipWidth
= 2.0f
;
1755 vp2
.dvClipHeight
= 2.0f
;
1756 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1757 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1758 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1759 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1761 vp
.dwSize
= sizeof(vp
);
1762 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1763 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1764 vp2
.dwSize
= sizeof(vp2
);
1765 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1766 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
1768 /* Destroying the device removes the viewport and releases the reference */
1769 IDirect3DDevice3_Release(device
);
1770 ref
= get_refcount((IUnknown
*) viewport3
);
1771 ok(ref
== 1, "Got unexpected refcount %u.\n", ref
);
1773 vp
.dwSize
= sizeof(vp
);
1774 hr
= IDirect3DViewport3_SetViewport(viewport3
, &vp
);
1775 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1776 vp2
.dwSize
= sizeof(vp2
);
1777 hr
= IDirect3DViewport3_SetViewport2(viewport3
, &vp2
);
1778 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
, "Got unexpected hr %#x.\n", hr
);
1780 ref
= IDirect3DViewport3_Release(another_vp
);
1781 ok(!ref
, "Got unexpected refcount %u.\n", ref
);
1782 ref
= IDirect3DViewport3_Release(viewport3
);
1783 ok(!ref
, "Got unexpected refcount %u.\n", ref
);
1784 IDirect3D3_Release(d3d
);
1785 DestroyWindow(window
);
1786 IDirectDraw4_Release(ddraw
);
1789 static void test_zenable(void)
1791 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1794 struct vec4 position
;
1799 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1800 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1801 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1802 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1804 IDirect3DViewport3
*viewport
;
1805 IDirect3DDevice3
*device
;
1806 IDirectDrawSurface4
*rt
;
1813 window
= create_window();
1814 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1816 skip("Failed to create a 3D device, skipping test.\n");
1817 DestroyWindow(window
);
1821 viewport
= create_viewport(device
, 0, 0, 640, 480);
1822 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1823 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1825 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1826 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1828 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1829 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1830 hr
= IDirect3DDevice3_BeginScene(device
);
1831 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1832 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1833 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1834 hr
= IDirect3DDevice3_EndScene(device
);
1835 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1837 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1838 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1839 for (i
= 0; i
< 4; ++i
)
1841 for (j
= 0; j
< 4; ++j
)
1843 x
= 80 * ((2 * j
) + 1);
1844 y
= 60 * ((2 * i
) + 1);
1845 color
= get_surface_color(rt
, x
, y
);
1846 ok(compare_color(color
, 0x0000ff00, 1),
1847 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1850 IDirectDrawSurface4_Release(rt
);
1852 destroy_viewport(device
, viewport
);
1853 IDirect3DDevice3_Release(device
);
1854 DestroyWindow(window
);
1857 static void test_ck_rgba(void)
1859 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1862 struct vec4 position
;
1863 struct vec2 texcoord
;
1867 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1868 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1869 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1870 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1871 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1872 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1873 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1874 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1878 D3DCOLOR fill_color
;
1881 D3DCOLOR result1
, result1_broken
;
1882 D3DCOLOR result2
, result2_broken
;
1886 /* r200 on Windows doesn't check the alpha component when applying the color
1887 * key, so the key matches on every texel. */
1888 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1889 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1890 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1891 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1892 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1893 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1894 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1895 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1898 IDirectDrawSurface4
*surface
;
1899 IDirect3DViewport3
*viewport
;
1900 DDSURFACEDESC2 surface_desc
;
1901 IDirect3DTexture2
*texture
;
1902 IDirect3DDevice3
*device
;
1903 IDirectDrawSurface4
*rt
;
1904 IDirectDraw4
*ddraw
;
1912 window
= create_window();
1913 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1915 skip("Failed to create a 3D device, skipping test.\n");
1916 DestroyWindow(window
);
1920 viewport
= create_viewport(device
, 0, 0, 640, 480);
1921 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1922 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1924 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1925 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1926 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1927 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1928 IDirect3D3_Release(d3d
);
1930 memset(&surface_desc
, 0, sizeof(surface_desc
));
1931 surface_desc
.dwSize
= sizeof(surface_desc
);
1932 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1933 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1934 surface_desc
.dwWidth
= 256;
1935 surface_desc
.dwHeight
= 256;
1936 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1937 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1938 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1939 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1940 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1941 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1942 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1943 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1944 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1945 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1946 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1947 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1948 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1950 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1951 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1952 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1953 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1954 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1955 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1957 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1958 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1960 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1962 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1963 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1964 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1965 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1967 memset(&fx
, 0, sizeof(fx
));
1968 fx
.dwSize
= sizeof(fx
);
1969 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1970 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1971 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1973 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
1974 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1975 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1976 hr
= IDirect3DDevice3_BeginScene(device
);
1977 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1978 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1979 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1980 hr
= IDirect3DDevice3_EndScene(device
);
1981 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1983 color
= get_surface_color(rt
, 320, 240);
1984 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
1985 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1986 tests
[i
].result1
, i
, color
);
1988 U5(fx
).dwFillColor
= 0xff0000ff;
1989 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1990 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1992 hr
= IDirect3DDevice3_BeginScene(device
);
1993 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1994 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1995 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1996 hr
= IDirect3DDevice3_EndScene(device
);
1997 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1999 /* This tests that fragments that are masked out by the color key are
2000 * discarded, instead of just fully transparent. */
2001 color
= get_surface_color(rt
, 320, 240);
2002 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
2003 "Expected color 0x%08x for test %u, got 0x%08x.\n",
2004 tests
[i
].result2
, i
, color
);
2007 IDirectDrawSurface4_Release(rt
);
2008 IDirect3DTexture2_Release(texture
);
2009 IDirectDrawSurface4_Release(surface
);
2010 destroy_viewport(device
, viewport
);
2011 IDirectDraw4_Release(ddraw
);
2012 IDirect3DDevice3_Release(device
);
2013 DestroyWindow(window
);
2016 static void test_ck_default(void)
2018 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
2021 struct vec4 position
;
2022 struct vec2 texcoord
;
2026 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
2027 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
2028 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
2029 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
2031 IDirectDrawSurface4
*surface
, *rt
;
2032 IDirect3DViewport3
*viewport
;
2033 DDSURFACEDESC2 surface_desc
;
2034 IDirect3DTexture2
*texture
;
2035 IDirect3DDevice3
*device
;
2036 IDirectDraw4
*ddraw
;
2044 window
= create_window();
2045 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2047 skip("Failed to create a 3D device, skipping test.\n");
2048 DestroyWindow(window
);
2052 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2053 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2054 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2055 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
2056 IDirect3D3_Release(d3d
);
2058 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
2059 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
2061 viewport
= create_viewport(device
, 0, 0, 640, 480);
2062 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
2063 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
2065 memset(&surface_desc
, 0, sizeof(surface_desc
));
2066 surface_desc
.dwSize
= sizeof(surface_desc
);
2067 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
2068 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2069 surface_desc
.dwWidth
= 256;
2070 surface_desc
.dwHeight
= 256;
2071 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
2072 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2073 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
2074 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
2075 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
2076 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
2077 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
2078 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
2079 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2080 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2081 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
2082 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
2083 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
2084 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
2086 memset(&fx
, 0, sizeof(fx
));
2087 fx
.dwSize
= sizeof(fx
);
2088 U5(fx
).dwFillColor
= 0x000000ff;
2089 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
2090 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
2092 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2093 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2094 hr
= IDirect3DDevice3_BeginScene(device
);
2095 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2096 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2097 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2098 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
2099 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2100 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2101 hr
= IDirect3DDevice3_EndScene(device
);
2102 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2103 color
= get_surface_color(rt
, 320, 240);
2104 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
2106 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
2107 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
2108 hr
= IDirect3DDevice3_BeginScene(device
);
2109 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
2110 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
2111 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
2112 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
2113 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
2114 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
2115 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
2116 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
2117 hr
= IDirect3DDevice3_EndScene(device
);
2118 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
2119 color
= get_surface_color(rt
, 320, 240);
2120 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
2122 IDirect3DTexture_Release(texture
);
2123 IDirectDrawSurface4_Release(surface
);
2124 destroy_viewport(device
, viewport
);
2125 IDirectDrawSurface4_Release(rt
);
2126 IDirect3DDevice3_Release(device
);
2127 IDirectDraw4_Release(ddraw
);
2128 DestroyWindow(window
);
2131 static void test_ck_complex(void)
2133 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
2134 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
2135 DDSURFACEDESC2 surface_desc
;
2136 IDirect3DDevice3
*device
;
2137 DDCOLORKEY color_key
;
2138 IDirectDraw4
*ddraw
;
2145 window
= create_window();
2146 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2148 skip("Failed to create a 3D device, skipping test.\n");
2149 DestroyWindow(window
);
2152 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2153 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2154 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2155 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
2156 IDirect3D3_Release(d3d
);
2158 memset(&surface_desc
, 0, sizeof(surface_desc
));
2159 surface_desc
.dwSize
= sizeof(surface_desc
);
2160 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2161 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2162 surface_desc
.dwWidth
= 128;
2163 surface_desc
.dwHeight
= 128;
2164 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2165 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2167 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2168 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2169 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2170 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2171 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2172 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2173 memset(&color_key
, 0, sizeof(color_key
));
2174 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2175 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2176 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2177 color_key
.dwColorSpaceLowValue
);
2178 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2179 color_key
.dwColorSpaceHighValue
);
2182 IDirectDrawSurface_AddRef(mipmap
);
2183 for (i
= 0; i
< 7; ++i
)
2185 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2186 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2188 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2189 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2190 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2191 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2192 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2193 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
2194 memset(&color_key
, 0, sizeof(color_key
));
2195 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2196 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
2197 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2198 color_key
.dwColorSpaceLowValue
, i
);
2199 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2200 color_key
.dwColorSpaceHighValue
, i
);
2202 IDirectDrawSurface_Release(mipmap
);
2206 memset(&color_key
, 0, sizeof(color_key
));
2207 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2208 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2209 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2210 color_key
.dwColorSpaceLowValue
);
2211 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2212 color_key
.dwColorSpaceHighValue
);
2214 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2215 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2216 IDirectDrawSurface_Release(mipmap
);
2217 refcount
= IDirectDrawSurface4_Release(surface
);
2218 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2220 memset(&surface_desc
, 0, sizeof(surface_desc
));
2221 surface_desc
.dwSize
= sizeof(surface_desc
);
2222 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2223 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2224 U5(surface_desc
).dwBackBufferCount
= 1;
2225 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2226 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2228 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2229 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2230 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2231 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2232 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2233 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2234 memset(&color_key
, 0, sizeof(color_key
));
2235 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2236 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2237 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2238 color_key
.dwColorSpaceLowValue
);
2239 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2240 color_key
.dwColorSpaceHighValue
);
2242 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
2243 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2245 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2246 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2247 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2248 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2249 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2250 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2251 memset(&color_key
, 0, sizeof(color_key
));
2252 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2253 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2254 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2255 color_key
.dwColorSpaceLowValue
);
2256 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2257 color_key
.dwColorSpaceHighValue
);
2259 IDirectDrawSurface_Release(tmp
);
2261 refcount
= IDirectDrawSurface4_Release(surface
);
2262 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2263 IDirectDraw4_Release(ddraw
);
2264 refcount
= IDirect3DDevice3_Release(device
);
2265 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2266 DestroyWindow(window
);
2272 REFIID refcount_iid
;
2276 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2277 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2279 ULONG refcount
, expected_refcount
;
2280 IUnknown
*iface1
, *iface2
;
2284 for (i
= 0; i
< entry_count
; ++i
)
2286 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2287 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2290 for (j
= 0; j
< entry_count
; ++j
)
2292 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2293 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2296 expected_refcount
= 0;
2297 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2298 ++expected_refcount
;
2299 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2300 ++expected_refcount
;
2301 refcount
= IUnknown_Release(iface2
);
2302 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2303 refcount
, test_name
, i
, j
, expected_refcount
);
2307 expected_refcount
= 0;
2308 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2309 ++expected_refcount
;
2310 refcount
= IUnknown_Release(iface1
);
2311 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2312 refcount
, test_name
, i
, expected_refcount
);
2317 static void test_surface_qi(void)
2319 static const struct qi_test tests
[] =
2321 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface4
, S_OK
},
2322 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface4
, S_OK
},
2323 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2324 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2325 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2326 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2327 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2328 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2329 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2330 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2331 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2332 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2333 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2334 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2335 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2336 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2337 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2338 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2339 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2340 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2341 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2342 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2343 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2344 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2345 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2346 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2347 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2348 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2349 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2350 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2351 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2352 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2353 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2354 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2355 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2356 {NULL
, NULL
, E_INVALIDARG
},
2359 IDirectDrawSurface4
*surface
;
2360 DDSURFACEDESC2 surface_desc
;
2361 IDirect3DDevice3
*device
;
2362 IDirectDraw4
*ddraw
;
2366 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2368 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2372 window
= create_window();
2373 /* Try to create a D3D device to see if the ddraw implementation supports
2374 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2375 * doesn't support e.g. the IDirect3DTexture interfaces. */
2376 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2378 skip("Failed to create a 3D device, skipping test.\n");
2379 DestroyWindow(window
);
2382 IDirect3DDevice_Release(device
);
2383 ddraw
= create_ddraw();
2384 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2385 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2386 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2388 memset(&surface_desc
, 0, sizeof(surface_desc
));
2389 surface_desc
.dwSize
= sizeof(surface_desc
);
2390 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2391 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2392 surface_desc
.dwWidth
= 512;
2393 surface_desc
.dwHeight
= 512;
2394 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface4
**)0xdeadbeef, NULL
);
2395 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2396 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2397 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2399 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface4
, tests
, ARRAY_SIZE(tests
));
2401 IDirectDrawSurface4_Release(surface
);
2402 IDirectDraw4_Release(ddraw
);
2403 DestroyWindow(window
);
2406 static void test_device_qi(void)
2408 static const struct qi_test tests
[] =
2410 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2411 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2412 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2413 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2414 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2415 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2416 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2417 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2418 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2419 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2420 {&IID_IDirect3DDevice3
, &IID_IDirect3DDevice3
, S_OK
},
2421 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice3
, S_OK
},
2422 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice3
, S_OK
},
2423 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2424 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2425 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2426 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2427 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2428 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2429 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2430 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2431 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2432 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2433 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2434 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2435 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2436 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2437 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2438 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2439 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2440 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2441 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2442 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2443 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2444 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2445 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2446 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2447 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2448 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2449 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2450 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2451 {&IID_IUnknown
, &IID_IDirect3DDevice3
, S_OK
},
2454 IDirect3DDevice3
*device
;
2457 window
= create_window();
2458 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2460 skip("Failed to create a 3D device, skipping test.\n");
2461 DestroyWindow(window
);
2465 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice3
, tests
, ARRAY_SIZE(tests
));
2467 IDirect3DDevice3_Release(device
);
2468 DestroyWindow(window
);
2471 static void test_wndproc(void)
2473 LONG_PTR proc
, ddraw_proc
;
2474 IDirectDraw4
*ddraw
;
2480 static struct message messages
[] =
2482 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2483 {WM_MOVE
, FALSE
, 0},
2484 {WM_SIZE
, FALSE
, 0},
2485 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2486 {WM_ACTIVATE
, FALSE
, 0},
2487 {WM_SETFOCUS
, FALSE
, 0},
2491 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2492 ddraw
= create_ddraw();
2493 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2495 wc
.lpfnWndProc
= test_proc
;
2496 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2497 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2499 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2500 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2502 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2503 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2504 (LONG_PTR
)test_proc
, proc
);
2505 expect_messages
= messages
;
2506 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2507 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2508 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2509 expect_messages
= NULL
;
2510 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2511 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2512 (LONG_PTR
)test_proc
, proc
);
2513 ref
= IDirectDraw4_Release(ddraw
);
2514 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2515 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2516 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2517 (LONG_PTR
)test_proc
, proc
);
2519 /* DDSCL_NORMAL doesn't. */
2520 ddraw
= create_ddraw();
2521 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2522 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2523 (LONG_PTR
)test_proc
, proc
);
2524 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2525 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2526 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2527 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2528 (LONG_PTR
)test_proc
, proc
);
2529 ref
= IDirectDraw4_Release(ddraw
);
2530 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2531 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2532 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2533 (LONG_PTR
)test_proc
, proc
);
2535 /* The original window proc is only restored by ddraw if the current
2536 * window proc matches the one ddraw set. This also affects switching
2537 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2538 ddraw
= create_ddraw();
2539 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2540 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2541 (LONG_PTR
)test_proc
, proc
);
2542 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2543 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2544 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2545 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2546 (LONG_PTR
)test_proc
, proc
);
2548 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2549 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2550 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2551 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2552 (LONG_PTR
)test_proc
, proc
);
2553 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2554 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2555 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2556 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2557 (LONG_PTR
)test_proc
, proc
);
2558 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2559 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2560 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2561 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2562 (LONG_PTR
)DefWindowProcA
, proc
);
2563 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2564 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2565 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, ddraw_proc
);
2566 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2567 (LONG_PTR
)DefWindowProcA
, proc
);
2568 ref
= IDirectDraw4_Release(ddraw
);
2569 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2570 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2571 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2572 (LONG_PTR
)test_proc
, proc
);
2574 ddraw
= create_ddraw();
2575 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2576 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2577 (LONG_PTR
)test_proc
, proc
);
2578 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2579 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2580 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2581 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2582 (LONG_PTR
)test_proc
, proc
);
2583 ref
= IDirectDraw4_Release(ddraw
);
2584 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2585 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2586 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2587 (LONG_PTR
)DefWindowProcA
, proc
);
2589 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2590 expect_messages
= NULL
;
2591 DestroyWindow(window
);
2592 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2595 static void test_window_style(void)
2597 LONG style
, exstyle
, tmp
, expected_style
;
2598 RECT fullscreen_rect
, r
;
2599 IDirectDraw4
*ddraw
;
2605 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2606 0, 0, 100, 100, 0, 0, 0, 0);
2607 ddraw
= create_ddraw();
2608 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2610 style
= GetWindowLongA(window
, GWL_STYLE
);
2611 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2612 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2614 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2615 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2617 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2618 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2619 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2620 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2622 GetWindowRect(window
, &r
);
2623 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2624 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2625 GetClientRect(window
, &r
);
2626 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2628 ret
= SetForegroundWindow(GetDesktopWindow());
2629 ok(ret
, "Failed to set foreground window.\n");
2631 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2632 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2633 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2634 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2636 ret
= SetForegroundWindow(window
);
2637 ok(ret
, "Failed to set foreground window.\n");
2638 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2639 * the next tests expect this. */
2640 ShowWindow(window
, SW_HIDE
);
2642 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2643 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2645 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2646 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2647 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2648 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2650 ShowWindow(window
, SW_SHOW
);
2651 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2652 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2654 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2655 expected_style
= style
| WS_VISIBLE
;
2656 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2657 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2658 expected_style
= exstyle
| WS_EX_TOPMOST
;
2659 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2661 ret
= SetForegroundWindow(GetDesktopWindow());
2662 ok(ret
, "Failed to set foreground window.\n");
2663 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2664 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2665 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2666 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2667 expected_style
= exstyle
| WS_EX_TOPMOST
;
2668 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2670 ref
= IDirectDraw4_Release(ddraw
);
2671 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2673 DestroyWindow(window
);
2676 static void test_redundant_mode_set(void)
2678 DDSURFACEDESC2 surface_desc
= {0};
2679 IDirectDraw4
*ddraw
;
2685 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2686 0, 0, 100, 100, 0, 0, 0, 0);
2687 ddraw
= create_ddraw();
2688 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2690 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2691 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2693 surface_desc
.dwSize
= sizeof(surface_desc
);
2694 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
2695 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2697 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2698 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2699 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2701 GetWindowRect(window
, &q
);
2705 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2706 GetWindowRect(window
, &s
);
2707 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2709 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2710 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2711 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2713 GetWindowRect(window
, &s
);
2714 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2715 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2717 ref
= IDirectDraw4_Release(ddraw
);
2718 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2720 DestroyWindow(window
);
2723 static SIZE screen_size
, screen_size2
;
2725 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2727 if (message
== WM_SIZE
)
2729 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2730 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2733 return test_proc(hwnd
, message
, wparam
, lparam
);
2736 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2738 if (message
== WM_SIZE
)
2740 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2741 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2744 return test_proc(hwnd
, message
, wparam
, lparam
);
2747 struct test_coop_level_mode_set_enum_param
2749 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2752 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
2754 struct test_coop_level_mode_set_enum_param
*param
= context
;
2756 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2757 return DDENUMRET_OK
;
2758 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2759 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2760 return DDENUMRET_OK
;
2762 if (!param
->ddraw_width
)
2764 param
->ddraw_width
= surface_desc
->dwWidth
;
2765 param
->ddraw_height
= surface_desc
->dwHeight
;
2766 return DDENUMRET_OK
;
2768 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2769 return DDENUMRET_OK
;
2771 param
->user32_width
= surface_desc
->dwWidth
;
2772 param
->user32_height
= surface_desc
->dwHeight
;
2773 return DDENUMRET_CANCEL
;
2776 static void test_coop_level_mode_set(void)
2778 IDirectDrawSurface4
*primary
;
2779 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2780 IDirectDraw4
*ddraw
;
2781 DDSURFACEDESC2 ddsd
;
2783 HWND window
, window2
;
2787 struct test_coop_level_mode_set_enum_param param
;
2792 static const struct message exclusive_messages
[] =
2794 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2795 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2796 {WM_SIZE
, FALSE
, 0},
2797 {WM_DISPLAYCHANGE
, FALSE
, 0},
2800 static const struct message exclusive_focus_loss_messages
[] =
2802 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
, DD_OK
},
2803 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DD_OK
}, /* Window resize due to mode change. */
2804 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DD_OK
},
2805 {WM_SIZE
, TRUE
, SIZE_RESTORED
, DD_OK
}, /* Generated by DefWindowProc. */
2806 {WM_DISPLAYCHANGE
, FALSE
, 0, DD_OK
},
2807 {WM_KILLFOCUS
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2808 {WM_WINDOWPOSCHANGING
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
}, /* Window minimized. */
2809 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2810 * SW_MINIMIZED, causing a recursive window activation that does not
2811 * produce the same result in Wine yet. Ignore the difference for now.
2812 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2813 {WM_WINDOWPOSCHANGED
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2814 {WM_MOVE
, FALSE
, 0, DDERR_NOEXCLUSIVEMODE
},
2815 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
, DDERR_NOEXCLUSIVEMODE
},
2816 {WM_ACTIVATEAPP
, TRUE
, FALSE
, DDERR_NOEXCLUSIVEMODE
},
2819 static const struct message exclusive_focus_restore_messages
[] =
2821 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2822 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2823 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2824 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2825 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2826 /* Native redundantly sets the window size here. */
2827 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2828 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2829 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2830 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2833 static const struct message sc_restore_messages
[] =
2835 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2836 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2837 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2838 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2841 static const struct message sc_minimize_messages
[] =
2843 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2844 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2845 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2846 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2849 static const struct message sc_maximize_messages
[] =
2851 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2852 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2853 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2854 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2858 static const struct message normal_messages
[] =
2860 {WM_DISPLAYCHANGE
, FALSE
, 0},
2864 ddraw
= create_ddraw();
2865 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2867 memset(¶m
, 0, sizeof(param
));
2868 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2869 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2870 ref
= IDirectDraw4_Release(ddraw
);
2871 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2873 if (!param
.user32_height
)
2875 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2879 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2880 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2881 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2883 memset(&devmode
, 0, sizeof(devmode
));
2884 devmode
.dmSize
= sizeof(devmode
);
2885 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2886 devmode
.dmPelsWidth
= param
.user32_width
;
2887 devmode
.dmPelsHeight
= param
.user32_height
;
2888 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2889 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2891 ddraw
= create_ddraw();
2892 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2894 wc
.lpfnWndProc
= mode_set_proc
;
2895 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2896 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2897 wc
.lpfnWndProc
= mode_set_proc2
;
2898 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2899 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2901 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2902 0, 0, 100, 100, 0, 0, 0, 0);
2903 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2904 0, 0, 100, 100, 0, 0, 0, 0);
2906 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2907 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2909 GetWindowRect(window
, &r
);
2910 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2911 wine_dbgstr_rect(&r
));
2913 memset(&ddsd
, 0, sizeof(ddsd
));
2914 ddsd
.dwSize
= sizeof(ddsd
);
2915 ddsd
.dwFlags
= DDSD_CAPS
;
2916 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2918 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2919 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2920 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2921 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2922 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2923 param
.user32_width
, ddsd
.dwWidth
);
2924 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2925 param
.user32_height
, ddsd
.dwHeight
);
2927 GetWindowRect(window
, &r
);
2928 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2929 wine_dbgstr_rect(&r
));
2931 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2932 expect_messages
= exclusive_messages
;
2936 hr
= IDirectDrawSurface4_IsLost(primary
);
2937 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2938 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2939 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2940 hr
= IDirectDrawSurface4_IsLost(primary
);
2941 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2943 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2944 expect_messages
= NULL
;
2945 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2946 "Expected screen size %ux%u, got %ux%u.\n",
2947 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2949 GetWindowRect(window
, &r
);
2950 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2951 wine_dbgstr_rect(&r
));
2953 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2954 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2955 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2956 param
.user32_width
, ddsd
.dwWidth
);
2957 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2958 param
.user32_height
, ddsd
.dwHeight
);
2959 IDirectDrawSurface4_Release(primary
);
2961 memset(&ddsd
, 0, sizeof(ddsd
));
2962 ddsd
.dwSize
= sizeof(ddsd
);
2963 ddsd
.dwFlags
= DDSD_CAPS
;
2964 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2966 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2967 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2968 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2969 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2970 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2971 param
.ddraw_width
, ddsd
.dwWidth
);
2972 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2973 param
.ddraw_height
, ddsd
.dwHeight
);
2975 GetWindowRect(window
, &r
);
2976 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2977 wine_dbgstr_rect(&r
));
2979 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2980 expect_messages
= exclusive_messages
;
2984 hr
= IDirectDrawSurface4_IsLost(primary
);
2985 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2986 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2987 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2988 hr
= IDirectDrawSurface4_IsLost(primary
);
2989 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2991 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2992 expect_messages
= NULL
;
2993 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2994 "Expected screen size %ux%u, got %ux%u.\n",
2995 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2997 GetWindowRect(window
, &r
);
2998 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2999 wine_dbgstr_rect(&r
));
3001 expect_messages
= exclusive_focus_loss_messages
;
3002 focus_test_ddraw
= ddraw
;
3003 ret
= SetForegroundWindow(GetDesktopWindow());
3004 ok(ret
, "Failed to set foreground window.\n");
3005 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3006 focus_test_ddraw
= NULL
;
3008 memset(&devmode
, 0, sizeof(devmode
));
3009 devmode
.dmSize
= sizeof(devmode
);
3010 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3011 ok(ret
, "Failed to get display mode.\n");
3012 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3013 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
3014 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3016 expect_messages
= exclusive_focus_restore_messages
;
3017 ShowWindow(window
, SW_RESTORE
);
3018 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3020 GetWindowRect(window
, &r
);
3021 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3022 wine_dbgstr_rect(&r
));
3023 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3024 ok(ret
, "Failed to get display mode.\n");
3025 ok(devmode
.dmPelsWidth
== param
.ddraw_width
3026 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
3027 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3029 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3030 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3031 /* Normally the primary should be restored here. Unfortunately this causes the
3032 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
3033 * testbot. Another Restore call would presumably avoid the crash, but it also moots
3034 * the point of the GetSurfaceDesc call. */
3036 expect_messages
= sc_minimize_messages
;
3037 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3038 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3039 expect_messages
= NULL
;
3041 expect_messages
= sc_restore_messages
;
3042 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3043 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3044 expect_messages
= NULL
;
3046 expect_messages
= sc_maximize_messages
;
3047 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3048 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3049 expect_messages
= NULL
;
3051 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3052 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3054 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3055 expect_messages
= exclusive_messages
;
3059 hr
= IDirectDrawSurface4_IsLost(primary
);
3060 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3061 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3062 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3063 hr
= IDirectDrawSurface4_IsLost(primary
);
3064 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3066 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3067 expect_messages
= NULL
;
3068 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3069 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3070 "Expected screen size %ux%u, got %ux%u.\n",
3071 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
3073 GetWindowRect(window
, &r
);
3074 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3075 wine_dbgstr_rect(&r
));
3077 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3078 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3079 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3080 param
.ddraw_width
, ddsd
.dwWidth
);
3081 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3082 param
.ddraw_height
, ddsd
.dwHeight
);
3083 IDirectDrawSurface4_Release(primary
);
3086 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3087 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3089 memset(&ddsd
, 0, sizeof(ddsd
));
3090 ddsd
.dwSize
= sizeof(ddsd
);
3091 ddsd
.dwFlags
= DDSD_CAPS
;
3092 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3094 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3095 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3096 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3097 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3098 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3099 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3100 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3101 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3103 GetWindowRect(window
, &r
);
3104 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3105 wine_dbgstr_rect(&r
));
3107 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3108 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3110 GetWindowRect(window
, &r
);
3111 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3112 wine_dbgstr_rect(&r
));
3114 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3115 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3116 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3117 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3118 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3119 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3120 IDirectDrawSurface4_Release(primary
);
3122 memset(&ddsd
, 0, sizeof(ddsd
));
3123 ddsd
.dwSize
= sizeof(ddsd
);
3124 ddsd
.dwFlags
= DDSD_CAPS
;
3125 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3127 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3128 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3129 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3130 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3131 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3132 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3133 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3134 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3136 GetWindowRect(window
, &r
);
3137 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3138 wine_dbgstr_rect(&r
));
3140 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3141 expect_messages
= normal_messages
;
3145 hr
= IDirectDrawSurface4_IsLost(primary
);
3146 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3147 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3148 devmode
.dmPelsWidth
= param
.user32_width
;
3149 devmode
.dmPelsHeight
= param
.user32_height
;
3150 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3151 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3152 hr
= IDirectDrawSurface4_IsLost(primary
);
3153 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3155 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3156 expect_messages
= NULL
;
3157 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3159 GetWindowRect(window
, &r
);
3160 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3161 wine_dbgstr_rect(&r
));
3163 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3164 expect_messages
= normal_messages
;
3168 hr
= IDirectDrawSurface4_Restore(primary
);
3169 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3170 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3171 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3172 hr
= IDirectDrawSurface4_Restore(primary
);
3173 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3174 hr
= IDirectDrawSurface4_IsLost(primary
);
3175 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3177 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3178 expect_messages
= NULL
;
3179 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3181 GetWindowRect(window
, &r
);
3182 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3183 wine_dbgstr_rect(&r
));
3185 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3186 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3187 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3188 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3189 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3190 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3191 IDirectDrawSurface4_Release(primary
);
3193 memset(&ddsd
, 0, sizeof(ddsd
));
3194 ddsd
.dwSize
= sizeof(ddsd
);
3195 ddsd
.dwFlags
= DDSD_CAPS
;
3196 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3198 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3199 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3200 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3201 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3202 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3203 param
.ddraw_width
, ddsd
.dwWidth
);
3204 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3205 param
.ddraw_height
, ddsd
.dwHeight
);
3207 GetWindowRect(window
, &r
);
3208 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3209 wine_dbgstr_rect(&r
));
3211 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3212 expect_messages
= normal_messages
;
3216 hr
= IDirectDrawSurface4_IsLost(primary
);
3217 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3218 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3219 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3220 hr
= IDirectDrawSurface4_IsLost(primary
);
3221 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3223 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3224 expect_messages
= NULL
;
3225 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3227 GetWindowRect(window
, &r
);
3228 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3229 wine_dbgstr_rect(&r
));
3231 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3232 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3233 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3234 param
.ddraw_width
, ddsd
.dwWidth
);
3235 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3236 param
.ddraw_height
, ddsd
.dwHeight
);
3237 IDirectDrawSurface4_Release(primary
);
3239 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3240 ok(ret
, "Failed to get display mode.\n");
3241 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3242 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3243 "Expected resolution %ux%u, got %ux%u.\n",
3244 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3245 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3246 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3247 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3249 memset(&ddsd
, 0, sizeof(ddsd
));
3250 ddsd
.dwSize
= sizeof(ddsd
);
3251 ddsd
.dwFlags
= DDSD_CAPS
;
3252 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3254 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3255 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3256 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3257 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3258 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3259 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3260 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3261 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3263 GetWindowRect(window
, &r
);
3264 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3265 wine_dbgstr_rect(&r
));
3267 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3268 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3269 * not DDSCL_FULLSCREEN. */
3270 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3271 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3273 GetWindowRect(window
, &r
);
3274 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3275 wine_dbgstr_rect(&r
));
3277 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3278 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3279 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3280 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3281 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3282 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3283 IDirectDrawSurface4_Release(primary
);
3285 memset(&ddsd
, 0, sizeof(ddsd
));
3286 ddsd
.dwSize
= sizeof(ddsd
);
3287 ddsd
.dwFlags
= DDSD_CAPS
;
3288 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3290 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3291 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3292 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3293 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3294 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3295 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3296 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3297 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3299 GetWindowRect(window
, &r
);
3300 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3301 wine_dbgstr_rect(&r
));
3303 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3304 expect_messages
= normal_messages
;
3308 hr
= IDirectDrawSurface4_IsLost(primary
);
3309 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3310 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3311 devmode
.dmPelsWidth
= param
.user32_width
;
3312 devmode
.dmPelsHeight
= param
.user32_height
;
3313 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3314 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3315 hr
= IDirectDrawSurface4_IsLost(primary
);
3316 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3318 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3319 expect_messages
= NULL
;
3320 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3322 GetWindowRect(window
, &r
);
3323 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3324 wine_dbgstr_rect(&r
));
3326 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3327 expect_messages
= normal_messages
;
3331 hr
= IDirectDrawSurface4_Restore(primary
);
3332 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3333 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3334 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3335 hr
= IDirectDrawSurface4_Restore(primary
);
3336 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3337 hr
= IDirectDrawSurface4_IsLost(primary
);
3338 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3340 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3341 expect_messages
= NULL
;
3342 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3344 GetWindowRect(window
, &r
);
3345 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3346 wine_dbgstr_rect(&r
));
3348 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3349 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3350 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3351 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3352 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3353 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3354 IDirectDrawSurface4_Release(primary
);
3356 memset(&ddsd
, 0, sizeof(ddsd
));
3357 ddsd
.dwSize
= sizeof(ddsd
);
3358 ddsd
.dwFlags
= DDSD_CAPS
;
3359 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3361 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3362 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3363 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3364 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3365 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3366 param
.ddraw_width
, ddsd
.dwWidth
);
3367 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3368 param
.ddraw_height
, ddsd
.dwHeight
);
3370 GetWindowRect(window
, &r
);
3371 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3372 wine_dbgstr_rect(&r
));
3374 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3375 expect_messages
= normal_messages
;
3379 hr
= IDirectDrawSurface4_IsLost(primary
);
3380 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3381 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3382 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3383 hr
= IDirectDrawSurface4_IsLost(primary
);
3384 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3386 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3387 expect_messages
= NULL
;
3388 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3390 GetWindowRect(window
, &r
);
3391 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3392 wine_dbgstr_rect(&r
));
3394 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3395 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3396 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3397 param
.ddraw_width
, ddsd
.dwWidth
);
3398 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3399 param
.ddraw_height
, ddsd
.dwHeight
);
3400 IDirectDrawSurface4_Release(primary
);
3402 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3403 ok(ret
, "Failed to get display mode.\n");
3404 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3405 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3406 "Expected resolution %ux%u, got %ux%u.\n",
3407 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3408 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3409 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3410 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3412 memset(&ddsd
, 0, sizeof(ddsd
));
3413 ddsd
.dwSize
= sizeof(ddsd
);
3414 ddsd
.dwFlags
= DDSD_CAPS
;
3415 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3417 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3418 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3419 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3420 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3421 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3422 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3423 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3424 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3425 IDirectDrawSurface4_Release(primary
);
3427 GetWindowRect(window
, &r
);
3428 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3429 wine_dbgstr_rect(&r
));
3431 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3432 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3433 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3434 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3435 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3437 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3438 expect_messages
= exclusive_messages
;
3442 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3443 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3445 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3446 expect_messages
= NULL
;
3447 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3448 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3449 "Expected screen size %ux%u, got %ux%u.\n",
3450 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3451 screen_size
.cx
, screen_size
.cy
);
3453 GetWindowRect(window
, &r
);
3454 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3455 wine_dbgstr_rect(&r
));
3457 memset(&ddsd
, 0, sizeof(ddsd
));
3458 ddsd
.dwSize
= sizeof(ddsd
);
3459 ddsd
.dwFlags
= DDSD_CAPS
;
3460 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3462 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3463 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3464 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3465 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3466 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3467 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3468 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3469 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3470 IDirectDrawSurface4_Release(primary
);
3472 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3473 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3474 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3475 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3476 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3478 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3479 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3481 memset(&ddsd
, 0, sizeof(ddsd
));
3482 ddsd
.dwSize
= sizeof(ddsd
);
3483 ddsd
.dwFlags
= DDSD_CAPS
;
3484 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3486 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3487 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3488 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3489 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3490 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3491 param
.ddraw_width
, ddsd
.dwWidth
);
3492 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3493 param
.ddraw_height
, ddsd
.dwHeight
);
3494 IDirectDrawSurface4_Release(primary
);
3496 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3497 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3499 /* If the window is changed at the same time, messages are sent to the new window. */
3500 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3501 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3502 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3503 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3505 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3506 expect_messages
= exclusive_messages
;
3509 screen_size2
.cx
= 0;
3510 screen_size2
.cy
= 0;
3512 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3513 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3515 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3516 expect_messages
= NULL
;
3517 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3518 screen_size
.cx
, screen_size
.cy
);
3519 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3520 "Expected screen size 2 %ux%u, got %ux%u.\n",
3521 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3523 GetWindowRect(window
, &r
);
3524 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3525 wine_dbgstr_rect(&r
));
3526 GetWindowRect(window2
, &r
);
3527 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3528 wine_dbgstr_rect(&r
));
3530 memset(&ddsd
, 0, sizeof(ddsd
));
3531 ddsd
.dwSize
= sizeof(ddsd
);
3532 ddsd
.dwFlags
= DDSD_CAPS
;
3533 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3535 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3536 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3537 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3538 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3539 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3540 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3541 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3542 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3543 IDirectDrawSurface4_Release(primary
);
3545 ref
= IDirectDraw4_Release(ddraw
);
3546 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3548 GetWindowRect(window
, &r
);
3549 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3550 wine_dbgstr_rect(&r
));
3552 expect_messages
= NULL
;
3553 DestroyWindow(window
);
3554 DestroyWindow(window2
);
3555 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3556 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3559 static void test_coop_level_mode_set_multi(void)
3561 IDirectDraw4
*ddraw1
, *ddraw2
;
3567 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3568 0, 0, 100, 100, 0, 0, 0, 0);
3569 ddraw1
= create_ddraw();
3570 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3572 /* With just a single ddraw object, the display mode is restored on
3574 hr
= set_display_mode(ddraw1
, 800, 600);
3575 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3576 w
= GetSystemMetrics(SM_CXSCREEN
);
3577 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3578 h
= GetSystemMetrics(SM_CYSCREEN
);
3579 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3581 ref
= IDirectDraw4_Release(ddraw1
);
3582 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3583 w
= GetSystemMetrics(SM_CXSCREEN
);
3584 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3585 h
= GetSystemMetrics(SM_CYSCREEN
);
3586 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3588 /* When there are multiple ddraw objects, the display mode is restored to
3589 * the initial mode, before the first SetDisplayMode() call. */
3590 ddraw1
= create_ddraw();
3591 hr
= set_display_mode(ddraw1
, 800, 600);
3592 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3593 w
= GetSystemMetrics(SM_CXSCREEN
);
3594 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3595 h
= GetSystemMetrics(SM_CYSCREEN
);
3596 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3598 ddraw2
= create_ddraw();
3599 hr
= set_display_mode(ddraw2
, 640, 480);
3600 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3601 w
= GetSystemMetrics(SM_CXSCREEN
);
3602 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3603 h
= GetSystemMetrics(SM_CYSCREEN
);
3604 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3606 ref
= IDirectDraw4_Release(ddraw2
);
3607 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3608 w
= GetSystemMetrics(SM_CXSCREEN
);
3609 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3610 h
= GetSystemMetrics(SM_CYSCREEN
);
3611 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3613 ref
= IDirectDraw4_Release(ddraw1
);
3614 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3615 w
= GetSystemMetrics(SM_CXSCREEN
);
3616 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3617 h
= GetSystemMetrics(SM_CYSCREEN
);
3618 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3620 /* Regardless of release ordering. */
3621 ddraw1
= create_ddraw();
3622 hr
= set_display_mode(ddraw1
, 800, 600);
3623 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3624 w
= GetSystemMetrics(SM_CXSCREEN
);
3625 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3626 h
= GetSystemMetrics(SM_CYSCREEN
);
3627 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3629 ddraw2
= create_ddraw();
3630 hr
= set_display_mode(ddraw2
, 640, 480);
3631 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3632 w
= GetSystemMetrics(SM_CXSCREEN
);
3633 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3634 h
= GetSystemMetrics(SM_CYSCREEN
);
3635 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3637 ref
= IDirectDraw4_Release(ddraw1
);
3638 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3639 w
= GetSystemMetrics(SM_CXSCREEN
);
3640 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3641 h
= GetSystemMetrics(SM_CYSCREEN
);
3642 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3644 ref
= IDirectDraw4_Release(ddraw2
);
3645 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3646 w
= GetSystemMetrics(SM_CXSCREEN
);
3647 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3648 h
= GetSystemMetrics(SM_CYSCREEN
);
3649 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3651 /* But only for ddraw objects that called SetDisplayMode(). */
3652 ddraw1
= create_ddraw();
3653 ddraw2
= create_ddraw();
3654 hr
= set_display_mode(ddraw2
, 640, 480);
3655 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3656 w
= GetSystemMetrics(SM_CXSCREEN
);
3657 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3658 h
= GetSystemMetrics(SM_CYSCREEN
);
3659 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3661 ref
= IDirectDraw4_Release(ddraw1
);
3662 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3663 w
= GetSystemMetrics(SM_CXSCREEN
);
3664 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3665 h
= GetSystemMetrics(SM_CYSCREEN
);
3666 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3668 ref
= IDirectDraw4_Release(ddraw2
);
3669 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3670 w
= GetSystemMetrics(SM_CXSCREEN
);
3671 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3672 h
= GetSystemMetrics(SM_CYSCREEN
);
3673 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3675 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3676 * restoring the display mode. */
3677 ddraw1
= create_ddraw();
3678 hr
= set_display_mode(ddraw1
, 800, 600);
3679 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3680 w
= GetSystemMetrics(SM_CXSCREEN
);
3681 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3682 h
= GetSystemMetrics(SM_CYSCREEN
);
3683 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3685 ddraw2
= create_ddraw();
3686 hr
= set_display_mode(ddraw2
, 640, 480);
3687 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3688 w
= GetSystemMetrics(SM_CXSCREEN
);
3689 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3690 h
= GetSystemMetrics(SM_CYSCREEN
);
3691 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3693 hr
= IDirectDraw4_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3694 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3696 ref
= IDirectDraw4_Release(ddraw1
);
3697 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3698 w
= GetSystemMetrics(SM_CXSCREEN
);
3699 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3700 h
= GetSystemMetrics(SM_CYSCREEN
);
3701 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3703 ref
= IDirectDraw4_Release(ddraw2
);
3704 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3705 w
= GetSystemMetrics(SM_CXSCREEN
);
3706 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3707 h
= GetSystemMetrics(SM_CYSCREEN
);
3708 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3710 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3711 ddraw1
= create_ddraw();
3712 hr
= set_display_mode(ddraw1
, 800, 600);
3713 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3714 w
= GetSystemMetrics(SM_CXSCREEN
);
3715 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3716 h
= GetSystemMetrics(SM_CYSCREEN
);
3717 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3719 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3720 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3722 ddraw2
= create_ddraw();
3723 hr
= set_display_mode(ddraw2
, 640, 480);
3724 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3726 ref
= IDirectDraw4_Release(ddraw1
);
3727 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3728 w
= GetSystemMetrics(SM_CXSCREEN
);
3729 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3730 h
= GetSystemMetrics(SM_CYSCREEN
);
3731 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3733 ref
= IDirectDraw4_Release(ddraw2
);
3734 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3735 w
= GetSystemMetrics(SM_CXSCREEN
);
3736 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3737 h
= GetSystemMetrics(SM_CYSCREEN
);
3738 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3740 DestroyWindow(window
);
3743 static void test_initialize(void)
3745 IDirectDraw4
*ddraw
;
3748 ddraw
= create_ddraw();
3749 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3751 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3752 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3753 IDirectDraw4_Release(ddraw
);
3756 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw4
, (void **)&ddraw
);
3757 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr
);
3758 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3759 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3760 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3761 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3762 IDirectDraw4_Release(ddraw
);
3766 static void test_coop_level_surf_create(void)
3768 IDirectDrawSurface4
*surface
;
3769 IDirectDraw4
*ddraw
;
3770 DDSURFACEDESC2 ddsd
;
3773 ddraw
= create_ddraw();
3774 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3776 memset(&ddsd
, 0, sizeof(ddsd
));
3777 ddsd
.dwSize
= sizeof(ddsd
);
3778 ddsd
.dwFlags
= DDSD_CAPS
;
3779 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3780 surface
= (void *)0xdeadbeef;
3781 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3782 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3783 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3785 surface
= (void *)0xdeadbeef;
3786 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3787 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3788 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3790 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
3791 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3793 surface
= (void *)0xdeadbeef;
3794 hr
= IDirectDraw4_CreateSurface(ddraw
, NULL
, &surface
, NULL
);
3795 ok(hr
== DDERR_INVALIDPARAMS
, "Unexpected hr %#x.\n", hr
);
3796 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3798 IDirectDraw4_Release(ddraw
);
3801 static void test_vb_discard(void)
3803 static const struct vec4 quad
[] =
3805 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
3806 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
3807 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
3808 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
3811 IDirect3DDevice3
*device
;
3813 IDirect3DVertexBuffer
*buffer
;
3816 D3DVERTEXBUFFERDESC desc
;
3818 static const unsigned int vbsize
= 16;
3821 window
= create_window();
3822 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3824 skip("Failed to create a 3D device, skipping test.\n");
3825 DestroyWindow(window
);
3829 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
3830 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
3832 memset(&desc
, 0, sizeof(desc
));
3833 desc
.dwSize
= sizeof(desc
);
3834 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
3835 desc
.dwFVF
= D3DFVF_XYZRHW
;
3836 desc
.dwNumVertices
= vbsize
;
3837 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
3838 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
3840 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3841 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3842 memcpy(data
, quad
, sizeof(quad
));
3843 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3844 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3846 hr
= IDirect3DDevice3_BeginScene(device
);
3847 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3848 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
3849 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3850 hr
= IDirect3DDevice3_EndScene(device
);
3851 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3853 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3854 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3855 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
3856 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3857 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3859 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3860 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3861 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
3863 if (data
[i
] != 0xaa)
3865 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
3869 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3870 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3872 IDirect3DVertexBuffer_Release(buffer
);
3873 IDirect3D3_Release(d3d
);
3874 IDirect3DDevice3_Release(device
);
3875 DestroyWindow(window
);
3878 static void test_coop_level_multi_window(void)
3880 HWND window1
, window2
;
3881 IDirectDraw4
*ddraw
;
3884 window1
= create_window();
3885 window2
= create_window();
3886 ddraw
= create_ddraw();
3887 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3889 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3890 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3891 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3892 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3893 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3894 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3896 IDirectDraw4_Release(ddraw
);
3897 DestroyWindow(window2
);
3898 DestroyWindow(window1
);
3901 static void test_draw_strided(void)
3903 static struct vec3 position
[] =
3910 static DWORD diffuse
[] =
3912 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3914 static WORD indices
[] =
3919 IDirectDrawSurface4
*rt
;
3920 IDirect3DDevice3
*device
;
3924 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
3925 IDirect3DViewport3
*viewport
;
3926 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3928 window
= create_window();
3929 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3931 skip("Failed to create a 3D device, skipping test.\n");
3932 DestroyWindow(window
);
3936 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
3937 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3938 viewport
= create_viewport(device
, 0, 0, 640, 480);
3939 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
3940 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
3941 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
3942 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
3944 hr
= IDirect3DDevice3_BeginScene(device
);
3945 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3947 memset(&strided
, 0x55, sizeof(strided
));
3948 strided
.position
.lpvData
= position
;
3949 strided
.position
.dwStride
= sizeof(*position
);
3950 strided
.diffuse
.lpvData
= diffuse
;
3951 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
3952 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
3953 &strided
, 4, indices
, 6, 0);
3954 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3956 hr
= IDirect3DDevice3_EndScene(device
);
3957 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3959 color
= get_surface_color(rt
, 320, 240);
3960 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
3962 IDirect3DViewport3_Release(viewport
);
3963 IDirectDrawSurface4_Release(rt
);
3964 IDirect3DDevice3_Release(device
);
3965 DestroyWindow(window
);
3968 static void test_lighting(void)
3970 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3971 static D3DMATRIX mat
=
3973 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3974 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3975 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3976 0.0f
, 0.0f
, 0.0f
, 1.0f
,
3980 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3981 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3982 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3983 0.0f
, 0.0f
, 0.5f
, 1.0f
,
3987 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3988 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3989 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
3990 10.f
, 10.0f
, 10.0f
, 1.0f
,
3994 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3995 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3996 0.0f
, 0.0f
, 1.0f
, -1.0f
,
3997 10.f
, 10.0f
, 10.0f
, 0.0f
,
3999 static struct vertex
4001 struct vec3 position
;
4006 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4007 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4008 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
4009 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
4013 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4014 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4015 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
4016 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
4018 static struct vertex_normal
4020 struct vec3 position
;
4026 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4027 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4028 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4029 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
4033 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4034 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4035 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4036 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
4040 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4041 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4042 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4043 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4047 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4048 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4049 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4050 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
4054 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4055 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4056 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4057 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
4059 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
4062 D3DMATRIX
*world_matrix
;
4065 const char *message
;
4069 {&mat
, nquad
, 0x000080ff, "Lit quad with light"},
4070 {&mat_singular
, nquad
, 0x000080b4, "Lit quad with singular world matrix"},
4071 {&mat_transf
, rotatedquad
, 0x000080ff, "Lit quad with transformation matrix"},
4072 {&mat_nonaffine
, translatedquad
, 0x000080ff, "Lit quad with non-affine matrix"},
4074 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
4075 IDirect3DVertexBuffer
*src_vb1
, *src_vb2
, *dst_vb
;
4076 IDirect3DViewport3
*viewport
, *viewport2
;
4077 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
4078 struct vertex_normal
*src_data2
;
4079 IDirect3DMaterial3
*material
;
4080 D3DMATERIALHANDLE mat_handle
;
4081 D3DVERTEXBUFFERDESC vb_desc
;
4082 IDirect3DDevice3
*device
;
4083 struct vertex
*src_data1
;
4084 IDirectDrawSurface4
*rt
;
4085 IDirect3DLight
*light
;
4086 D3DLIGHT2 light_desc
;
4095 struct vec4 position
;
4101 window
= create_window();
4102 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4104 skip("Failed to create a 3D device, skipping test.\n");
4105 DestroyWindow(window
);
4109 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4110 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4112 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4113 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4115 viewport
= create_viewport(device
, 0, 0, 640, 480);
4116 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4117 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4119 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4120 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4122 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4123 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4124 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4125 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4126 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4127 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4128 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4129 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4130 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4131 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4132 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
4133 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4134 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
4135 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4137 hr
= IDirect3DDevice3_BeginScene(device
);
4138 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4140 memset(&vb_desc
, 0, sizeof(vb_desc
));
4141 vb_desc
.dwSize
= sizeof(vb_desc
);
4142 vb_desc
.dwFVF
= fvf
;
4143 vb_desc
.dwNumVertices
= 2;
4144 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb1
, 0, NULL
);
4145 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4146 vb_desc
.dwSize
= sizeof(vb_desc
);
4147 vb_desc
.dwFVF
= nfvf
;
4148 vb_desc
.dwNumVertices
= 2;
4149 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb2
, 0, NULL
);
4150 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4152 memset(&vb_desc
, 0, sizeof(vb_desc
));
4153 vb_desc
.dwSize
= sizeof(vb_desc
);
4154 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4155 vb_desc
.dwNumVertices
= 4;
4156 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0, NULL
);
4157 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4159 hr
= IDirect3DVertexBuffer_Lock(src_vb1
, 0, (void **)&src_data1
, NULL
);
4160 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4161 memcpy(src_data1
, unlitquad
, sizeof(*src_data1
));
4162 memcpy(&src_data1
[1], litquad
, sizeof(*src_data1
));
4163 hr
= IDirect3DVertexBuffer_Unlock(src_vb1
);
4164 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4166 hr
= IDirect3DVertexBuffer_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4167 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4168 memcpy(src_data2
, unlitnquad
, sizeof(*src_data2
));
4169 memcpy(&src_data2
[1], litnquad
, sizeof(*src_data2
));
4170 hr
= IDirect3DVertexBuffer_Unlock(src_vb2
);
4171 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4173 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
4174 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4175 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4176 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0,
4177 1, src_vb1
, 0, device
, 0);
4178 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4179 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
4181 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4183 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4184 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4185 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 1,
4186 1, src_vb1
, 1, device
, 0);
4187 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4188 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4190 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4192 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4193 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4194 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 2,
4195 1, src_vb2
, 0, device
, 0);
4196 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4197 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4199 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4201 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4202 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4203 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 3,
4204 1, src_vb2
, 1, device
, 0);
4205 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4206 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4208 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4210 hr
= IDirect3DDevice3_EndScene(device
);
4211 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4213 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4214 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4216 color
= get_surface_color(rt
, 160, 360);
4217 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
4218 ok(dst_data
[0].diffuse
== 0xffff0000,
4219 "Unlit quad without normals has color 0x%08x, expected 0xffff0000.\n", dst_data
[0].diffuse
);
4220 ok(!dst_data
[0].specular
,
4221 "Unexpected specular color 0x%08x.\n", dst_data
[0].specular
);
4223 color
= get_surface_color(rt
, 160, 120);
4224 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
4225 ok(dst_data
[1].diffuse
== 0xff00ff00,
4226 "Lit quad without normals has color 0x%08x, expected 0xff000000.\n", dst_data
[1].diffuse
);
4227 ok(!dst_data
[1].specular
,
4228 "Unexpected specular color 0x%08x.\n", dst_data
[1].specular
);
4230 color
= get_surface_color(rt
, 480, 360);
4231 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x.\n", color
);
4232 ok(dst_data
[2].diffuse
== 0xff0000ff,
4233 "Unlit quad with normals has color 0x%08x, expected 0xff0000ff.\n", dst_data
[2].diffuse
);
4234 ok(!dst_data
[2].specular
,
4235 "Unexpected specular color 0x%08x.\n", dst_data
[2].specular
);
4237 color
= get_surface_color(rt
, 480, 120);
4238 ok(color
== 0x00ffff00, "Lit quad with normals has color 0x%08x.\n", color
);
4239 ok(dst_data
[3].diffuse
== 0xffffff00,
4240 "Lit quad with normals has color 0x%08x, expected 0xff000000.\n", dst_data
[3].diffuse
);
4241 ok(!dst_data
[3].specular
,
4242 "Unexpected specular color 0x%08x.\n", dst_data
[3].specular
);
4244 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
4245 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4247 material
= create_diffuse_and_ambient_material(device
, 0.0f
, 1.0f
, 1.0f
, 0.5f
);
4248 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4249 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4250 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4251 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4252 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_AMBIENT
, 0xff008000);
4253 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4255 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4256 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4257 memset(&light_desc
, 0, sizeof(light_desc
));
4258 light_desc
.dwSize
= sizeof(light_desc
);
4259 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
4260 U1(light_desc
.dcvColor
).r
= 1.0f
;
4261 U2(light_desc
.dcvColor
).g
= 1.0f
;
4262 U3(light_desc
.dcvColor
).b
= 1.0f
;
4263 U4(light_desc
.dcvColor
).a
= 0.5f
;
4264 U3(light_desc
.dvDirection
).z
= 1.0f
;
4265 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4266 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4267 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4268 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4269 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4270 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
4272 viewport2
= create_viewport(device
, 0, 0, 640, 480);
4273 hr
= IDirect3DViewport3_AddLight(viewport2
, light
);
4274 ok(hr
== D3DERR_LIGHTHASVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
4275 IDirect3DViewport3_Release(viewport2
);
4277 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4278 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4280 hr
= IDirect3DDevice3_BeginScene(device
);
4281 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4283 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, nquad
,
4285 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4287 hr
= IDirect3DDevice3_EndScene(device
);
4288 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4290 color
= get_surface_color(rt
, 320, 240);
4291 ok(color
== 0x00008000, "Lit quad with no light has color 0x%08x.\n", color
);
4293 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
4294 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4295 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4296 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4297 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4298 light_desc
.dwFlags
= 0;
4299 hr
= IDirect3DLight_GetLight(light
, (D3DLIGHT
*)&light_desc
);
4300 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4301 ok(light_desc
.dwFlags
== D3DLIGHT_ACTIVE
, "Got unexpected flags %#x.\n", light_desc
.dwFlags
);
4303 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4304 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4306 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4308 hr
= IDirect3DVertexBuffer_Lock(src_vb2
, 0, (void **)&src_data2
, NULL
);
4309 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4310 memcpy(src_data2
, tests
[i
].quad
, sizeof(*src_data2
));
4311 hr
= IDirect3DVertexBuffer_Unlock(src_vb2
);
4312 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4314 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
4315 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4317 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4318 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4320 hr
= IDirect3DDevice3_BeginScene(device
);
4321 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4323 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
4324 1, src_vb2
, 0, device
, 0);
4325 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4326 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
4328 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4330 hr
= IDirect3DDevice3_EndScene(device
);
4331 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4333 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4334 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4336 color
= get_surface_color(rt
, 320, 240);
4337 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
4338 ok(dst_data
[0].diffuse
== (tests
[i
].expected
| 0xff000000),
4339 "%s has color 0x%08x.\n", tests
[i
].message
, dst_data
[0].diffuse
);
4340 ok(!dst_data
[0].specular
,
4341 "%s has specular color 0x%08x.\n", tests
[i
].message
, dst_data
[0].specular
);
4343 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
4344 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4347 IDirect3DVertexBuffer_Release(src_vb1
);
4348 IDirect3DVertexBuffer_Release(src_vb2
);
4349 IDirect3DVertexBuffer_Release(dst_vb
);
4351 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4352 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4353 IDirect3DLight_Release(light
);
4354 destroy_material(material
);
4355 IDirect3DViewport3_Release(viewport
);
4356 IDirectDrawSurface4_Release(rt
);
4357 refcount
= IDirect3DDevice3_Release(device
);
4358 ok(!refcount
, "Device has %u references left.\n", refcount
);
4359 IDirect3D3_Release(d3d
);
4360 DestroyWindow(window
);
4363 static void test_specular_lighting(void)
4365 static const unsigned int vertices_side
= 5;
4366 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
4367 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4368 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
4369 static D3DMATRIX mat
=
4371 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4372 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4373 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4374 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4376 static const struct vertex
4378 struct vec3 position
;
4383 {{-0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4384 {{ 0.0f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4385 {{ 0.5f
, -0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4386 {{-0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4387 {{ 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4388 {{ 0.5f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4389 {{-0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4390 {{ 0.0f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4391 {{ 0.5f
, 0.5f
, 1.0f
}, {0.0f
, 0.0f
, -1.0f
}},
4394 static D3DLIGHT2 directional
=
4397 D3DLIGHT_DIRECTIONAL
,
4398 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4399 {{0.0f
}, {0.0f
}, {0.0f
}},
4400 {{0.0f
}, {0.0f
}, {1.0f
}},
4406 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4407 {{0.0f
}, {0.0f
}, {0.0f
}},
4408 {{0.0f
}, {0.0f
}, {0.0f
}},
4417 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4418 {{0.0f
}, {0.0f
}, {0.0f
}},
4419 {{0.0f
}, {0.0f
}, {1.0f
}},
4423 M_PI
/ 12.0f
, M_PI
/ 3.0f
4428 D3DLIGHT_PARALLELPOINT
,
4429 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4430 {{0.5f
}, {0.0f
}, {-1.0f
}},
4431 {{0.0f
}, {0.0f
}, {0.0f
}},
4437 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4438 {{-1.1f
}, {0.0f
}, {1.1f
}},
4439 {{0.0f
}, {0.0f
}, {0.0f
}},
4448 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4449 {{0.0f
}, {0.0f
}, {0.1f
}},
4450 {{0.0f
}, {0.0f
}, {0.0f
}},
4455 static const struct expected_color
4460 expected_directional
[] =
4462 {160, 120, 0x003c3c3c},
4463 {320, 120, 0x00717171},
4464 {480, 120, 0x003c3c3c},
4465 {160, 240, 0x00717171},
4466 {320, 240, 0x00ffffff},
4467 {480, 240, 0x00717171},
4468 {160, 360, 0x003c3c3c},
4469 {320, 360, 0x00717171},
4470 {480, 360, 0x003c3c3c},
4474 {160, 120, 0x00000000},
4475 {320, 120, 0x00090909},
4476 {480, 120, 0x00000000},
4477 {160, 240, 0x00090909},
4478 {320, 240, 0x00fafafa},
4479 {480, 240, 0x00090909},
4480 {160, 360, 0x00000000},
4481 {320, 360, 0x00090909},
4482 {480, 360, 0x00000000},
4486 {160, 120, 0x00000000},
4487 {320, 120, 0x00020202},
4488 {480, 120, 0x00000000},
4489 {160, 240, 0x00020202},
4490 {320, 240, 0x00fafafa},
4491 {480, 240, 0x00020202},
4492 {160, 360, 0x00000000},
4493 {320, 360, 0x00020202},
4494 {480, 360, 0x00000000},
4496 expected_parallelpoint
[] =
4498 {160, 120, 0x00050505},
4499 {320, 120, 0x002c2c2c},
4500 {480, 120, 0x006e6e6e},
4501 {160, 240, 0x00090909},
4502 {320, 240, 0x00717171},
4503 {480, 240, 0x00ffffff},
4504 {160, 360, 0x00050505},
4505 {320, 360, 0x002c2c2c},
4506 {480, 360, 0x006e6e6e},
4508 expected_point_far
[] =
4510 {160, 120, 0x00000000},
4511 {320, 120, 0x00000000},
4512 {480, 120, 0x00000000},
4513 {160, 240, 0x00000000},
4514 {320, 240, 0x00ffffff},
4515 {480, 240, 0x00000000},
4516 {160, 360, 0x00000000},
4517 {320, 360, 0x00000000},
4518 {480, 360, 0x00000000},
4522 {160, 120, 0x00000000},
4523 {320, 120, 0x00000000},
4524 {480, 120, 0x00000000},
4525 {160, 240, 0x00000000},
4526 {320, 240, 0x00000000},
4527 {480, 240, 0x00000000},
4528 {160, 360, 0x00000000},
4529 {320, 360, 0x00000000},
4530 {480, 360, 0x00000000},
4536 float specular_power
;
4537 const struct expected_color
*expected
;
4538 unsigned int expected_count
;
4542 /* D3DRENDERSTATE_LOCALVIEWER does not exist in D3D < 7 (the behavior is
4543 * the one you get on newer D3D versions with it set as TRUE). */
4544 {&directional
, FALSE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4545 {&directional
, TRUE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4546 {&point
, TRUE
, 30.0f
, expected_point
, ARRAY_SIZE(expected_point
)},
4547 {&spot
, TRUE
, 30.0f
, expected_spot
, ARRAY_SIZE(expected_spot
)},
4548 {¶llelpoint
, TRUE
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
4549 {&point_side
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4550 {&point_far
, TRUE
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
4551 {&directional
, FALSE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4552 {&directional
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4553 {&point
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4554 {&spot
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4555 {¶llelpoint
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4556 {&point_far
, TRUE
, 0.0f
, expected_zero
, ARRAY_SIZE(expected_zero
)},
4559 IDirect3DLight
*light
, *dummy_lights
[64];
4560 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
4561 struct vertex
*quad
, *src_data
;
4562 D3DVERTEXBUFFERDESC vb_desc
;
4563 D3DMATERIALHANDLE mat_handle
;
4564 IDirect3DViewport3
*viewport
;
4565 IDirect3DMaterial3
*material
;
4566 IDirect3DDevice3
*device
;
4567 IDirectDrawSurface4
*rt
;
4568 D3DLIGHT2 light_desc
;
4574 unsigned int i
, j
, x
, y
;
4577 struct vec4 position
;
4583 window
= create_window();
4584 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4586 skip("Failed to create a 3D device, skipping test.\n");
4587 DestroyWindow(window
);
4591 quad
= heap_alloc(vertices_side
* vertices_side
* sizeof(*quad
));
4592 indices
= heap_alloc(indices_count
* sizeof(*indices
));
4593 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
4595 for (x
= 0; x
< vertices_side
; ++x
)
4597 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4598 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4599 quad
[i
].position
.z
= 1.0f
;
4600 quad
[i
].normal
.x
= 0.0f
;
4601 quad
[i
].normal
.y
= 0.0f
;
4602 quad
[i
++].normal
.z
= -1.0f
;
4605 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
4607 for (x
= 0; x
< (vertices_side
- 1); ++x
)
4609 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4610 indices
[i
++] = y
* vertices_side
+ x
;
4611 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4612 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4613 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4614 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
4618 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4619 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4621 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4622 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4624 viewport
= create_viewport(device
, 0, 0, 640, 480);
4625 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4626 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4628 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4629 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4630 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4631 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4632 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4633 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4634 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4635 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4636 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4637 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4639 memset(&light_desc
, 0, sizeof(light_desc
));
4640 light_desc
.dwSize
= sizeof(light_desc
);
4641 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
4642 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
4643 U3(light_desc
.dvDirection
).z
= 1.0f
;
4645 for (i
= 0; i
< ARRAY_SIZE(dummy_lights
); ++i
)
4647 hr
= IDirect3D3_CreateLight(d3d
, &dummy_lights
[i
], NULL
);
4648 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4649 hr
= IDirect3DViewport3_AddLight(viewport
, dummy_lights
[i
]);
4650 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4651 hr
= IDirect3DLight_SetLight(dummy_lights
[i
], (D3DLIGHT
*)&light_desc
);
4652 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4655 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4656 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4657 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4658 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4660 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
4661 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4663 memset(&vb_desc
, 0, sizeof(vb_desc
));
4664 vb_desc
.dwSize
= sizeof(vb_desc
);
4665 vb_desc
.dwFVF
= fvf
;
4666 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
4667 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &src_vb
, 0, NULL
);
4668 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4669 hr
= IDirect3DVertexBuffer_Lock(src_vb
, 0, (void **)&src_data
, NULL
);
4670 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4671 memcpy(src_data
, vertices
, sizeof(vertices
));
4672 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
4673 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4675 memset(&vb_desc
, 0, sizeof(vb_desc
));
4676 vb_desc
.dwSize
= sizeof(vb_desc
);
4677 vb_desc
.dwFVF
= D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_SPECULAR
;
4678 vb_desc
.dwNumVertices
= ARRAY_SIZE(vertices
);
4679 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &dst_vb
, 0, NULL
);
4680 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4682 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4684 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
4685 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
4686 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4688 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
4689 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4691 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 0.5f
, tests
[i
].specular_power
);
4692 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4693 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4694 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4695 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4697 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4698 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4700 hr
= IDirect3DDevice3_BeginScene(device
);
4701 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4703 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4704 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4705 memset(dst_data
, 0, sizeof(*dst_data
) * ARRAY_SIZE(vertices
));
4706 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
4707 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4709 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
| D3DVOP_LIGHT
, 0,
4710 ARRAY_SIZE(vertices
), src_vb
, 0, device
, 0);
4711 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4712 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
4713 vertices_side
* vertices_side
, indices
, indices_count
, 0);
4714 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4716 hr
= IDirect3DDevice3_EndScene(device
);
4717 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4719 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, 0, (void **)&dst_data
, NULL
);
4720 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4722 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
4724 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
4725 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
4726 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
4727 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
4728 tests
[i
].expected
[j
].y
, color
, i
);
4729 ok(!dst_data
[j
].diffuse
, "Expected color 0x00000000 for vertex %u, got 0x%08x, case %u.\n",
4730 j
, dst_data
[j
].diffuse
, i
);
4731 ok(compare_color(dst_data
[j
].specular
, tests
[i
].expected
[j
].color
, 1),
4732 "Expected color 0x%08x for vertex %u, got 0x%08x, case %u.\n",
4733 tests
[i
].expected
[j
].color
, j
, dst_data
[j
].specular
, i
);
4735 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
4736 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4738 destroy_material(material
);
4741 for (i
= 0; i
< ARRAY_SIZE(dummy_lights
); ++i
)
4742 IDirect3DLight_Release(dummy_lights
[i
]);
4744 IDirect3DVertexBuffer_Release(dst_vb
);
4745 IDirect3DVertexBuffer_Release(src_vb
);
4747 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4748 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
4749 IDirect3DLight_Release(light
);
4750 IDirect3DViewport3_Release(viewport
);
4751 IDirectDrawSurface4_Release(rt
);
4752 refcount
= IDirect3DDevice3_Release(device
);
4753 ok(!refcount
, "Device has %u references left.\n", refcount
);
4754 IDirect3D3_Release(d3d
);
4755 DestroyWindow(window
);
4760 static void test_clear_rect_count(void)
4762 IDirectDrawSurface4
*rt
;
4763 IDirect3DDevice3
*device
;
4767 IDirect3DViewport3
*viewport
;
4768 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4770 window
= create_window();
4771 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4773 skip("Failed to create a 3D device, skipping test.\n");
4774 DestroyWindow(window
);
4778 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4779 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4781 viewport
= create_viewport(device
, 0, 0, 640, 480);
4782 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4783 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
4784 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00ffffff, 0.0f
, 0);
4785 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4786 hr
= IDirect3DViewport3_Clear2(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
, 0x00ff0000, 0.0f
, 0);
4787 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4788 hr
= IDirect3DViewport3_Clear2(viewport
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
4789 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4790 hr
= IDirect3DViewport3_Clear2(viewport
, 1, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
4791 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4793 color
= get_surface_color(rt
, 320, 240);
4794 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4795 "Got unexpected color 0x%08x.\n", color
);
4797 IDirect3DViewport3_Release(viewport
);
4798 IDirectDrawSurface4_Release(rt
);
4799 IDirect3DDevice3_Release(device
);
4800 DestroyWindow(window
);
4803 static BOOL
test_mode_restored(IDirectDraw4
*ddraw
, HWND window
)
4805 DDSURFACEDESC2 ddsd1
, ddsd2
;
4808 memset(&ddsd1
, 0, sizeof(ddsd1
));
4809 ddsd1
.dwSize
= sizeof(ddsd1
);
4810 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd1
);
4811 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4813 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4814 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4815 hr
= set_display_mode(ddraw
, 640, 480);
4816 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4817 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4818 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4820 memset(&ddsd2
, 0, sizeof(ddsd2
));
4821 ddsd2
.dwSize
= sizeof(ddsd2
);
4822 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd2
);
4823 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4824 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
4825 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
4827 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4830 static void test_coop_level_versions(void)
4836 IDirectDrawSurface
*surface
;
4837 IDirectDraw4
*ddraw4
;
4840 window
= create_window();
4841 ddraw4
= create_ddraw();
4842 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4843 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4844 restored
= test_mode_restored(ddraw4
, window
);
4845 ok(restored
, "Display mode not restored in new ddraw object\n");
4847 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4848 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4849 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4851 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4852 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4853 restored
= test_mode_restored(ddraw4
, window
);
4854 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4856 /* A successful one does */
4857 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4858 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4859 restored
= test_mode_restored(ddraw4
, window
);
4860 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4862 IDirectDraw_Release(ddraw
);
4863 IDirectDraw4_Release(ddraw4
);
4865 ddraw4
= create_ddraw();
4866 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4867 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4868 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4870 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4871 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4872 restored
= test_mode_restored(ddraw4
, window
);
4873 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4875 IDirectDraw_Release(ddraw
);
4876 IDirectDraw4_Release(ddraw4
);
4878 /* A failing call does not restore the ddraw2+ behavior */
4879 ddraw4
= create_ddraw();
4880 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4881 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4882 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4884 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4885 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4886 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4887 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4888 restored
= test_mode_restored(ddraw4
, window
);
4889 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4891 IDirectDraw_Release(ddraw
);
4892 IDirectDraw4_Release(ddraw4
);
4894 /* Neither does a sequence of successful calls with the new interface */
4895 ddraw4
= create_ddraw();
4896 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4897 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4898 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4900 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4901 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4902 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4903 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4904 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4905 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4907 restored
= test_mode_restored(ddraw4
, window
);
4908 ok(!restored
, "Display mode restored after ddraw1-ddraw4 SetCooperativeLevel() call sequence\n");
4909 IDirectDraw_Release(ddraw
);
4910 IDirectDraw4_Release(ddraw4
);
4912 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4913 ddraw4
= create_ddraw();
4914 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4915 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4916 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4918 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4919 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4921 memset(&ddsd
, 0, sizeof(ddsd
));
4922 ddsd
.dwSize
= sizeof(ddsd
);
4923 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4924 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4925 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4926 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4927 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
4928 IDirectDrawSurface_Release(surface
);
4929 restored
= test_mode_restored(ddraw4
, window
);
4930 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4932 IDirectDraw_Release(ddraw
);
4933 IDirectDraw4_Release(ddraw4
);
4934 DestroyWindow(window
);
4937 static void test_lighting_interface_versions(void)
4939 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4940 IDirect3DMaterial3
*emissive
;
4941 IDirect3DViewport3
*viewport
;
4942 IDirect3DDevice3
*device
;
4943 IDirectDrawSurface4
*rt
;
4947 D3DMATERIALHANDLE mat_handle
;
4951 static D3DVERTEX quad
[] =
4953 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4954 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4955 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4956 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4959 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
4962 struct vec3 position
;
4964 DWORD diffuse
, specular
;
4968 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4969 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4970 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4971 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4974 static D3DLVERTEX lquad
[] =
4976 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4977 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4978 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4979 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4982 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
4985 struct vec3 position
;
4986 DWORD diffuse
, specular
;
4987 struct vec2 texcoord
;
4991 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4992 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4993 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4994 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4997 static D3DTLVERTEX tlquad
[] =
4999 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5000 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5001 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5002 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
5009 DWORD d3drs_lighting
, d3drs_specular
;
5015 /* Lighting is enabled when all of these conditions are met:
5016 * 1) No pretransformed position(D3DFVF_XYZRHW)
5017 * 2) Normals are available (D3DFVF_NORMAL)
5018 * 3) D3DDP_DONOTLIGHT is not set.
5020 * D3DRENDERSTATE_LIGHTING is ignored, it is not defined
5021 * in this d3d version */
5024 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
5025 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
5026 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5027 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5028 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
5029 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
5030 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5031 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
5034 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x0000ff00},
5035 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
5036 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5037 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5038 /* The specular color in the vertex is ignored because
5039 * D3DRENDERSTATE_COLORVERTEX is not enabled */
5040 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x0000ff00},
5041 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
5042 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5043 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5046 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
5047 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
5048 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5049 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5050 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
5051 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
5052 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5053 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5056 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
5057 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x00ff0000},
5058 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5059 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
5060 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
5061 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x00ff8080},
5062 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5063 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
5066 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
5067 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
5068 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5069 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
5070 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
5071 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
5072 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5073 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
5076 window
= create_window();
5077 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5079 skip("Failed to create a 3D device, skipping test.\n");
5080 DestroyWindow(window
);
5084 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
5085 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
5087 viewport
= create_viewport(device
, 0, 0, 640, 480);
5088 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
5089 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
5091 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
5092 hr
= IDirect3DMaterial3_GetHandle(emissive
, device
, &mat_handle
);
5093 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
5094 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
5095 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
5096 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
5097 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
5099 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
5100 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
5101 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected FALSE.\n", rs
);
5103 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5105 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
5106 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
5108 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
5109 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
5110 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
5111 tests
[i
].d3drs_specular
);
5112 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
5114 hr
= IDirect3DDevice3_BeginScene(device
);
5115 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
5116 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
5117 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
5118 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
5119 hr
= IDirect3DDevice3_EndScene(device
);
5120 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
5122 color
= get_surface_color(rt
, 320, 240);
5123 ok(compare_color(color
, tests
[i
].color
, 1),
5124 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
5125 color
, tests
[i
].color
, i
);
5128 destroy_material(emissive
);
5129 destroy_viewport(device
, viewport
);
5130 IDirectDrawSurface4_Release(rt
);
5131 ref
= IDirect3DDevice3_Release(device
);
5132 ok(ref
== 0, "Device not properly released, refcount %u.\n", ref
);
5133 DestroyWindow(window
);
5139 IDirectDraw4
*ddraw
;
5142 } activateapp_testdata
;
5144 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
5146 if (message
== WM_ACTIVATEAPP
)
5148 if (activateapp_testdata
.ddraw
)
5151 activateapp_testdata
.received
= FALSE
;
5152 hr
= IDirectDraw4_SetCooperativeLevel(activateapp_testdata
.ddraw
,
5153 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
5154 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
5155 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
5157 activateapp_testdata
.received
= TRUE
;
5160 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
5163 static void test_coop_level_activateapp(void)
5165 IDirectDraw4
*ddraw
;
5169 DDSURFACEDESC2 ddsd
;
5170 IDirectDrawSurface4
*surface
;
5172 ddraw
= create_ddraw();
5173 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5175 wc
.lpfnWndProc
= activateapp_test_proc
;
5176 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
5177 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
5179 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
5180 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
5182 /* Exclusive with window already active. */
5183 SetForegroundWindow(window
);
5184 activateapp_testdata
.received
= FALSE
;
5185 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5186 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5187 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
5188 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5189 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5191 /* Exclusive with window not active. */
5192 SetForegroundWindow(GetDesktopWindow());
5193 activateapp_testdata
.received
= FALSE
;
5194 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5195 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5196 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5197 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5198 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5200 /* Normal with window not active, then exclusive with the same window. */
5201 SetForegroundWindow(GetDesktopWindow());
5202 activateapp_testdata
.received
= FALSE
;
5203 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5204 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5205 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
5206 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5207 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5208 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5209 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5210 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5212 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
5213 SetForegroundWindow(GetDesktopWindow());
5214 activateapp_testdata
.received
= FALSE
;
5215 activateapp_testdata
.ddraw
= ddraw
;
5216 activateapp_testdata
.window
= window
;
5217 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
5218 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5219 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5220 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5221 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5222 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5224 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
5225 * succeeding. Another switch to exclusive and back to normal is needed to release the
5226 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
5227 * WM_ACTIVATEAPP messages. */
5228 activateapp_testdata
.ddraw
= NULL
;
5229 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5230 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5231 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5232 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5234 /* Setting DDSCL_NORMAL with recursive invocation. */
5235 SetForegroundWindow(GetDesktopWindow());
5236 activateapp_testdata
.received
= FALSE
;
5237 activateapp_testdata
.ddraw
= ddraw
;
5238 activateapp_testdata
.window
= window
;
5239 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
5240 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5241 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5242 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
5244 /* DDraw is in exclusive mode now. */
5245 memset(&ddsd
, 0, sizeof(ddsd
));
5246 ddsd
.dwSize
= sizeof(ddsd
);
5247 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
5248 U5(ddsd
).dwBackBufferCount
= 1;
5249 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
5250 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5251 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
5252 IDirectDrawSurface4_Release(surface
);
5254 /* Recover again, just to be sure. */
5255 activateapp_testdata
.ddraw
= NULL
;
5256 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
5257 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5258 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5259 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5261 DestroyWindow(window
);
5262 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
5263 IDirectDraw4_Release(ddraw
);
5266 static void test_texturemanage(void)
5268 IDirectDraw4
*ddraw
;
5270 DDSURFACEDESC2 ddsd
;
5271 IDirectDrawSurface4
*surface
;
5273 DDCAPS hal_caps
, hel_caps
;
5274 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
5277 DWORD caps_in
, caps2_in
;
5279 DWORD caps_out
, caps2_out
;
5283 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5285 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5287 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5289 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5291 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
5292 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
5293 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
5294 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
5295 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5296 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
5297 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
5298 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
5300 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5302 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5304 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5306 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5308 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5310 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
5312 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
5313 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
5314 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
5315 DDSCAPS_SYSTEMMEMORY
, 0},
5318 ddraw
= create_ddraw();
5319 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5320 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
5321 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5323 memset(&hal_caps
, 0, sizeof(hal_caps
));
5324 hal_caps
.dwSize
= sizeof(hal_caps
);
5325 memset(&hel_caps
, 0, sizeof(hel_caps
));
5326 hel_caps
.dwSize
= sizeof(hel_caps
);
5327 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
5328 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5329 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
5331 skip("Managed textures not supported, skipping managed texture test.\n");
5332 IDirectDraw4_Release(ddraw
);
5336 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
5338 memset(&ddsd
, 0, sizeof(ddsd
));
5339 ddsd
.dwSize
= sizeof(ddsd
);
5340 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5341 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
5342 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
5346 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5347 ok(hr
== tests
[i
].hr
, "Got unexpected, hr %#x, case %u.\n", hr
, i
);
5351 memset(&ddsd
, 0, sizeof(ddsd
));
5352 ddsd
.dwSize
= sizeof(ddsd
);
5353 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5354 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5356 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
5357 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5358 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
5359 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
5360 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5361 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
5363 IDirectDrawSurface4_Release(surface
);
5366 IDirectDraw4_Release(ddraw
);
5369 #define SUPPORT_DXT1 0x01
5370 #define SUPPORT_DXT2 0x02
5371 #define SUPPORT_DXT3 0x04
5372 #define SUPPORT_DXT4 0x08
5373 #define SUPPORT_DXT5 0x10
5374 #define SUPPORT_YUY2 0x20
5375 #define SUPPORT_UYVY 0x40
5377 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5379 DWORD
*supported_fmts
= ctx
;
5381 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
5382 return DDENUMRET_OK
;
5384 switch (fmt
->dwFourCC
)
5386 case MAKEFOURCC('D','X','T','1'):
5387 *supported_fmts
|= SUPPORT_DXT1
;
5389 case MAKEFOURCC('D','X','T','2'):
5390 *supported_fmts
|= SUPPORT_DXT2
;
5392 case MAKEFOURCC('D','X','T','3'):
5393 *supported_fmts
|= SUPPORT_DXT3
;
5395 case MAKEFOURCC('D','X','T','4'):
5396 *supported_fmts
|= SUPPORT_DXT4
;
5398 case MAKEFOURCC('D','X','T','5'):
5399 *supported_fmts
|= SUPPORT_DXT5
;
5401 case MAKEFOURCC('Y','U','Y','2'):
5402 *supported_fmts
|= SUPPORT_YUY2
;
5404 case MAKEFOURCC('U','Y','V','Y'):
5405 *supported_fmts
|= SUPPORT_UYVY
;
5411 return DDENUMRET_OK
;
5414 static void test_block_formats_creation(void)
5416 HRESULT hr
, expect_hr
;
5417 unsigned int i
, j
, w
, h
;
5419 IDirectDraw4
*ddraw
;
5421 IDirect3DDevice3
*device
;
5422 IDirectDrawSurface4
*surface
;
5423 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
5424 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
5425 DDSURFACEDESC2 ddsd
;
5434 unsigned int block_width
;
5435 unsigned int block_height
;
5436 unsigned int block_size
;
5437 BOOL create_size_checked
, overlay
;
5441 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
5442 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
5443 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
5444 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
5445 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
5446 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
5447 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
5457 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
5458 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
5460 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
5461 * Other hw / drivers successfully create those surfaces. Ignore them, this
5462 * suggests that no game uses this, otherwise Nvidia would support it. */
5464 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
5465 "videomemory texture", FALSE
5468 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
5469 "videomemory overlay", TRUE
5472 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
5473 "systemmemory texture", FALSE
5476 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
5477 "managed texture", FALSE
5489 enum size_type size_type
;
5495 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5496 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5497 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5498 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5499 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5500 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5501 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
5502 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5503 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
5504 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
5505 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5506 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5507 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5508 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5511 window
= create_window();
5512 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5514 skip("Failed to create a 3D device, skipping test.\n");
5515 DestroyWindow(window
);
5519 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5520 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5521 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5522 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5523 IDirect3D3_Release(d3d
);
5525 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
,
5527 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5529 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
5530 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5531 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
5532 num_fourcc_codes
* sizeof(*fourcc_codes
));
5535 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
5536 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5537 for (i
= 0; i
< num_fourcc_codes
; i
++)
5539 for (j
= 0; j
< ARRAY_SIZE(formats
); j
++)
5541 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
5542 supported_overlay_fmts
|= formats
[j
].support_flag
;
5545 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
5547 memset(&hal_caps
, 0, sizeof(hal_caps
));
5548 hal_caps
.dwSize
= sizeof(hal_caps
);
5549 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
5550 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5552 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
5554 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5556 for (j
= 0; j
< ARRAY_SIZE(types
); j
++)
5560 if (formats
[i
].overlay
!= types
[j
].overlay
5561 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
5564 if (formats
[i
].overlay
)
5565 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
5567 support
= supported_fmts
& formats
[i
].support_flag
;
5569 for (w
= 1; w
<= 8; w
++)
5571 for (h
= 1; h
<= 8; h
++)
5573 BOOL block_aligned
= TRUE
;
5576 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
5577 block_aligned
= FALSE
;
5579 memset(&ddsd
, 0, sizeof(ddsd
));
5580 ddsd
.dwSize
= sizeof(ddsd
);
5581 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5582 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
5583 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
5584 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5585 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5586 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5590 /* TODO: Handle power of two limitations. I cannot test the pow2
5591 * behavior on windows because I have no hardware that doesn't at
5592 * least support np2_conditional. There's probably no HW that
5593 * supports DXTN textures but no conditional np2 textures. */
5594 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
5595 expect_hr
= DDERR_INVALIDPARAMS
;
5596 else if (formats
[i
].create_size_checked
&& !block_aligned
)
5598 expect_hr
= DDERR_INVALIDPARAMS
;
5599 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
5605 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5608 "Got unexpected hr %#x for format %s, resource type %s, size %ux%u, expected %#x.\n",
5609 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
5612 IDirectDrawSurface4_Release(surface
);
5617 if (formats
[i
].overlay
)
5620 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
5622 memset(&ddsd
, 0, sizeof(ddsd
));
5623 ddsd
.dwSize
= sizeof(ddsd
);
5624 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
5625 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
5627 switch (user_mem_tests
[j
].size_type
)
5629 case SIZE_TYPE_ZERO
:
5630 U1(ddsd
).dwLinearSize
= 0;
5633 case SIZE_TYPE_PITCH
:
5634 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
5637 case SIZE_TYPE_SIZE
:
5638 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
5641 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
5643 ddsd
.lpSurface
= mem
;
5644 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5645 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5646 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5650 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5651 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#x, format %s.\n", j
, hr
, formats
[i
].name
);
5656 memset(&ddsd
, 0, sizeof(ddsd
));
5657 ddsd
.dwSize
= sizeof(ddsd
);
5658 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5659 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", j
, hr
);
5660 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
5661 "Test %u: Got unexpected flags %#x.\n", j
, ddsd
.dwFlags
);
5662 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
5663 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#x.\n",
5664 j
, U1(ddsd
).dwLinearSize
);
5666 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
5667 "Test %u: Got unexpected linear size %#x, expected %#x.\n",
5668 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
5669 IDirectDrawSurface4_Release(surface
);
5673 HeapFree(GetProcessHeap(), 0, mem
);
5675 IDirectDraw4_Release(ddraw
);
5676 IDirect3DDevice3_Release(device
);
5677 DestroyWindow(window
);
5680 struct format_support_check
5682 const DDPIXELFORMAT
*format
;
5686 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5688 struct format_support_check
*format
= ctx
;
5690 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
5692 format
->supported
= TRUE
;
5693 return DDENUMRET_CANCEL
;
5696 return DDENUMRET_OK
;
5699 static void test_unsupported_formats(void)
5702 BOOL expect_success
;
5704 IDirectDraw4
*ddraw
;
5706 IDirect3DDevice3
*device
;
5707 IDirectDrawSurface4
*surface
;
5708 DDSURFACEDESC2 ddsd
;
5710 DWORD expected_caps
;
5721 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
5722 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
5728 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5729 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
5733 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
5735 window
= create_window();
5736 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5738 skip("Failed to create a 3D device, skipping test.\n");
5739 DestroyWindow(window
);
5743 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5744 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5745 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5746 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5747 IDirect3D3_Release(d3d
);
5749 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5751 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
5752 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
5753 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5755 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
5757 memset(&ddsd
, 0, sizeof(ddsd
));
5758 ddsd
.dwSize
= sizeof(ddsd
);
5759 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5760 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
5763 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
5765 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
5766 expect_success
= FALSE
;
5768 expect_success
= TRUE
;
5770 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5771 ok(SUCCEEDED(hr
) == expect_success
,
5772 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
5773 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
5777 memset(&ddsd
, 0, sizeof(ddsd
));
5778 ddsd
.dwSize
= sizeof(ddsd
);
5779 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5780 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5782 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
5783 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5784 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
5785 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5786 else if (check
.supported
)
5787 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5789 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5791 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
5792 "Expected capability %#x, format %s, input cap %#x.\n",
5793 expected_caps
, formats
[i
].name
, caps
[j
]);
5795 IDirectDrawSurface4_Release(surface
);
5799 IDirectDraw4_Release(ddraw
);
5800 IDirect3DDevice3_Release(device
);
5801 DestroyWindow(window
);
5804 static void test_rt_caps(void)
5806 PALETTEENTRY palette_entries
[256];
5807 IDirectDrawPalette
*palette
;
5808 IDirectDraw4
*ddraw
;
5809 DDPIXELFORMAT z_fmt
;
5816 static const DDPIXELFORMAT p8_fmt
=
5818 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5819 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
5824 const DDPIXELFORMAT
*pf
;
5827 HRESULT create_device_hr
;
5828 HRESULT set_rt_hr
, alternative_set_rt_hr
;
5834 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5835 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5842 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5843 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5850 DDSCAPS_OFFSCREENPLAIN
,
5851 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5858 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5859 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5860 D3DERR_SURFACENOTINVIDMEM
,
5866 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5867 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5874 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5875 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5883 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5891 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5898 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5899 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5900 D3DERR_SURFACENOTINVIDMEM
,
5906 DDSCAPS_SYSTEMMEMORY
,
5907 DDSCAPS_SYSTEMMEMORY
,
5915 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5922 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5924 DDERR_NOPALETTEATTACHED
,
5930 DDSCAPS_OFFSCREENPLAIN
,
5931 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5938 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5939 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5940 DDERR_NOPALETTEATTACHED
,
5946 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5947 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5954 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
5955 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5957 DDERR_INVALIDPIXELFORMAT
,
5962 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5963 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5965 DDERR_INVALIDPIXELFORMAT
,
5971 DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5978 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5979 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5981 DDERR_INVALIDPIXELFORMAT
,
5986 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5987 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5994 window
= create_window();
5995 ddraw
= create_ddraw();
5996 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5997 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5998 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6000 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
6002 skip("D3D interface is not available, skipping test.\n");
6006 memset(&z_fmt
, 0, sizeof(z_fmt
));
6007 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
6008 if (FAILED(hr
) || !z_fmt
.dwSize
)
6010 skip("No depth buffer formats available, skipping test.\n");
6011 IDirect3D3_Release(d3d
);
6015 memset(palette_entries
, 0, sizeof(palette_entries
));
6016 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
6017 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6019 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6021 IDirectDrawSurface4
*surface
, *rt
, *expected_rt
, *tmp
;
6022 DDSURFACEDESC2 surface_desc
;
6023 IDirect3DDevice3
*device
;
6025 memset(&surface_desc
, 0, sizeof(surface_desc
));
6026 surface_desc
.dwSize
= sizeof(surface_desc
);
6027 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6028 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6029 if (test_data
[i
].pf
)
6031 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6032 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6034 surface_desc
.dwWidth
= 640;
6035 surface_desc
.dwHeight
= 480;
6036 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6037 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
6038 i
, test_data
[i
].caps_in
, hr
);
6040 memset(&surface_desc
, 0, sizeof(surface_desc
));
6041 surface_desc
.dwSize
= sizeof(surface_desc
);
6042 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
6043 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6044 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
6045 "Test %u: Got unexpected caps %#x, expected %#x.\n",
6046 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
6048 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
6049 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
6050 i
, hr
, test_data
[i
].create_device_hr
);
6053 if (hr
== DDERR_NOPALETTEATTACHED
)
6055 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
6056 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
6057 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
6058 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6059 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
6061 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
6063 IDirectDrawSurface4_Release(surface
);
6065 memset(&surface_desc
, 0, sizeof(surface_desc
));
6066 surface_desc
.dwSize
= sizeof(surface_desc
);
6067 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6068 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
6069 surface_desc
.dwWidth
= 640;
6070 surface_desc
.dwHeight
= 480;
6071 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6072 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
6074 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
6075 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
6078 memset(&surface_desc
, 0, sizeof(surface_desc
));
6079 surface_desc
.dwSize
= sizeof(surface_desc
);
6080 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6081 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6082 if (test_data
[i
].pf
)
6084 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
6085 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
6087 surface_desc
.dwWidth
= 640;
6088 surface_desc
.dwHeight
= 480;
6089 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
6090 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
6091 i
, test_data
[i
].caps_in
, hr
);
6093 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
6094 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
6095 "Test %u: Got unexpected hr %#x, expected %#x.\n",
6096 i
, hr
, test_data
[i
].set_rt_hr
);
6097 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
6100 expected_rt
= surface
;
6102 hr
= IDirect3DDevice3_GetRenderTarget(device
, &tmp
);
6103 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
6104 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
6106 IDirectDrawSurface4_Release(tmp
);
6107 IDirectDrawSurface4_Release(rt
);
6108 refcount
= IDirect3DDevice3_Release(device
);
6109 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
6110 refcount
= IDirectDrawSurface4_Release(surface
);
6111 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
6114 IDirectDrawPalette_Release(palette
);
6115 IDirect3D3_Release(d3d
);
6118 refcount
= IDirectDraw4_Release(ddraw
);
6119 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6120 DestroyWindow(window
);
6123 static void test_primary_caps(void)
6125 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6126 IDirectDrawSurface4
*surface
;
6127 DDSURFACEDESC2 surface_desc
;
6128 IDirectDraw4
*ddraw
;
6138 DWORD back_buffer_count
;
6146 DDSCAPS_PRIMARYSURFACE
,
6149 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
6153 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
6160 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
6167 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
6174 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
6181 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
6188 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6195 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6202 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6204 DDERR_NOEXCLUSIVEMODE
,
6208 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6209 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6215 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6216 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
6219 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
6222 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6223 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
6229 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
6230 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
6237 window
= create_window();
6238 ddraw
= create_ddraw();
6239 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6241 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6243 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
6244 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6246 memset(&surface_desc
, 0, sizeof(surface_desc
));
6247 surface_desc
.dwSize
= sizeof(surface_desc
);
6248 surface_desc
.dwFlags
= DDSD_CAPS
;
6249 if (test_data
[i
].back_buffer_count
!= ~0u)
6250 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6251 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
6252 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
6253 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6254 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
6258 memset(&surface_desc
, 0, sizeof(surface_desc
));
6259 surface_desc
.dwSize
= sizeof(surface_desc
);
6260 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
6261 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
6262 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
6263 "Test %u: Got unexpected caps %#x, expected %#x.\n",
6264 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
6266 IDirectDrawSurface4_Release(surface
);
6269 refcount
= IDirectDraw4_Release(ddraw
);
6270 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6271 DestroyWindow(window
);
6274 static void test_surface_lock(void)
6276 IDirectDraw4
*ddraw
;
6277 IDirect3D3
*d3d
= NULL
;
6278 IDirectDrawSurface4
*surface
;
6282 DDSURFACEDESC2 ddsd
;
6284 DDPIXELFORMAT z_fmt
;
6294 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
6296 "videomemory offscreenplain"
6299 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
6301 "systemmemory offscreenplain"
6304 DDSCAPS_PRIMARYSURFACE
,
6309 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6311 "videomemory texture"
6314 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
6316 "opaque videomemory texture"
6319 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
6321 "systemmemory texture"
6325 DDSCAPS2_TEXTUREMANAGE
,
6330 DDSCAPS2_D3DTEXTUREMANAGE
,
6335 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6336 "opaque managed texture"
6340 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
6341 "opaque managed texture"
6344 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6355 window
= create_window();
6356 ddraw
= create_ddraw();
6357 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6358 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6359 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6361 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
6363 skip("D3D interface is not available, skipping test.\n");
6367 memset(&z_fmt
, 0, sizeof(z_fmt
));
6368 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
6369 if (FAILED(hr
) || !z_fmt
.dwSize
)
6371 skip("No depth buffer formats available, skipping test.\n");
6375 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6377 memset(&ddsd
, 0, sizeof(ddsd
));
6378 ddsd
.dwSize
= sizeof(ddsd
);
6379 ddsd
.dwFlags
= DDSD_CAPS
;
6380 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6382 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6386 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
6388 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
6389 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
6391 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6392 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6394 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6395 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6397 memset(&ddsd
, 0, sizeof(ddsd
));
6398 ddsd
.dwSize
= sizeof(ddsd
);
6399 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6400 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6403 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6404 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6407 memset(&ddsd
, 0, sizeof(ddsd
));
6408 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6409 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
6411 IDirectDrawSurface4_Release(surface
);
6416 IDirect3D3_Release(d3d
);
6417 refcount
= IDirectDraw4_Release(ddraw
);
6418 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6419 DestroyWindow(window
);
6422 static void test_surface_discard(void)
6424 IDirect3DDevice3
*device
;
6426 IDirectDraw4
*ddraw
;
6429 DDSURFACEDESC2 ddsd
;
6430 IDirectDrawSurface4
*surface
, *target
;
6439 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6440 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6441 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6442 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6443 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
6444 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6445 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
6446 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6450 window
= create_window();
6451 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6453 skip("Failed to create a 3D device, skipping test.\n");
6454 DestroyWindow(window
);
6457 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
6458 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6459 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
6460 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6461 hr
= IDirect3DDevice3_GetRenderTarget(device
, &target
);
6462 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6464 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6468 memset(&ddsd
, 0, sizeof(ddsd
));
6469 ddsd
.dwSize
= sizeof(ddsd
);
6470 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6471 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6472 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6475 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6476 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#x, case %u.\n", hr
, i
);
6478 memset(&ddsd
, 0, sizeof(ddsd
));
6479 ddsd
.dwSize
= sizeof(ddsd
);
6480 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6481 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6482 addr
= ddsd
.lpSurface
;
6483 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6484 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6486 memset(&ddsd
, 0, sizeof(ddsd
));
6487 ddsd
.dwSize
= sizeof(ddsd
);
6488 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6489 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6490 discarded
= ddsd
.lpSurface
!= addr
;
6491 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6492 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6494 hr
= IDirectDrawSurface4_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
6495 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
6497 memset(&ddsd
, 0, sizeof(ddsd
));
6498 ddsd
.dwSize
= sizeof(ddsd
);
6499 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6500 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6501 discarded
|= ddsd
.lpSurface
!= addr
;
6502 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6503 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6505 IDirectDrawSurface4_Release(surface
);
6507 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
6508 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
6509 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
6512 IDirectDrawSurface4_Release(target
);
6513 IDirectDraw4_Release(ddraw
);
6514 IDirect3D3_Release(d3d
);
6515 IDirect3DDevice3_Release(device
);
6516 DestroyWindow(window
);
6519 static void fill_surface(IDirectDrawSurface4
*surface
, D3DCOLOR color
)
6521 DDSURFACEDESC2 surface_desc
= {sizeof(surface_desc
)};
6526 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6527 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6529 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
6531 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
);
6532 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
6538 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6539 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6542 static void test_flip(void)
6544 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6545 IDirectDrawSurface4
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
6546 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
6547 DDSURFACEDESC2 surface_desc
;
6548 BOOL sysmem_primary
;
6549 IDirectDraw4
*ddraw
;
6550 DWORD expected_caps
;
6564 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
6565 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
6566 {"TEXTURE", DDSCAPS_TEXTURE
},
6569 window
= create_window();
6570 ddraw
= create_ddraw();
6571 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6573 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6574 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6576 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6578 /* Creating a flippable texture induces a BSoD on some versions of the
6579 * Intel graphics driver. At least Intel GMA 950 with driver version
6580 * 6.14.10.4926 on Windows XP SP3 is affected. */
6581 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
6583 win_skip("Skipping flippable texture test.\n");
6587 memset(&surface_desc
, 0, sizeof(surface_desc
));
6588 surface_desc
.dwSize
= sizeof(surface_desc
);
6589 surface_desc
.dwFlags
= DDSD_CAPS
;
6590 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6591 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6592 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6593 surface_desc
.dwWidth
= 512;
6594 surface_desc
.dwHeight
= 512;
6595 U5(surface_desc
).dwBackBufferCount
= 3;
6596 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6597 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6599 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
6600 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6601 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6602 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6604 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
6605 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
6606 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6607 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6609 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
6610 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6611 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
6612 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6616 memset(&surface_desc
, 0, sizeof(surface_desc
));
6617 surface_desc
.dwSize
= sizeof(surface_desc
);
6618 hr
= IDirectDrawSurface4_GetSurfaceDesc(frontbuffer
, &surface_desc
);
6619 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6620 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6621 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6622 expected_caps
|= DDSCAPS_VISIBLE
;
6623 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6624 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6625 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
6627 hr
= IDirectDrawSurface4_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
6628 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6629 memset(&surface_desc
, 0, sizeof(surface_desc
));
6630 surface_desc
.dwSize
= sizeof(surface_desc
);
6631 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer1
, &surface_desc
);
6632 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6633 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6634 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6635 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
6636 expected_caps
|= DDSCAPS_BACKBUFFER
;
6637 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6638 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6640 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
6641 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6642 memset(&surface_desc
, 0, sizeof(surface_desc
));
6643 surface_desc
.dwSize
= sizeof(surface_desc
);
6644 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer2
, &surface_desc
);
6645 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6646 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6647 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6648 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
6649 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6650 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6652 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
6653 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6654 memset(&surface_desc
, 0, sizeof(surface_desc
));
6655 surface_desc
.dwSize
= sizeof(surface_desc
);
6656 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer3
, &surface_desc
);
6657 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6658 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6659 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6660 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6661 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6663 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
6664 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6665 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
6666 test_data
[i
].name
, surface
, frontbuffer
);
6667 IDirectDrawSurface4_Release(surface
);
6669 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
6670 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6671 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6672 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6673 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6674 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6675 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6677 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6678 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6679 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6680 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6681 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6682 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
6683 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
6685 memset(&surface_desc
, 0, sizeof(surface_desc
));
6686 surface_desc
.dwSize
= sizeof(surface_desc
);
6687 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6688 surface_desc
.ddsCaps
.dwCaps
= 0;
6689 surface_desc
.dwWidth
= 640;
6690 surface_desc
.dwHeight
= 480;
6691 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6692 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6693 hr
= IDirectDrawSurface4_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
6694 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6695 IDirectDrawSurface4_Release(surface
);
6697 hr
= IDirectDrawSurface4_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
6698 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6699 hr
= IDirectDrawSurface4_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
6700 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6701 hr
= IDirectDrawSurface4_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
6702 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6703 hr
= IDirectDrawSurface4_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
6704 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6706 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
6707 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
6708 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
6709 fill_surface(backbuffer1
, 0xffff0000);
6710 fill_surface(backbuffer2
, 0xff00ff00);
6711 fill_surface(backbuffer3
, 0xff0000ff);
6713 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6714 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6715 color
= get_surface_color(backbuffer1
, 320, 240);
6716 /* The testbot seems to just copy the contents of one surface to all the
6717 * others, instead of properly flipping. */
6718 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6719 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6720 color
= get_surface_color(backbuffer2
, 320, 240);
6721 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6722 fill_surface(backbuffer3
, 0xffff0000);
6724 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6725 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6726 color
= get_surface_color(backbuffer1
, 320, 240);
6727 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6728 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6729 color
= get_surface_color(backbuffer2
, 320, 240);
6730 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6731 fill_surface(backbuffer3
, 0xff00ff00);
6733 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6734 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6735 color
= get_surface_color(backbuffer1
, 320, 240);
6736 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6737 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6738 color
= get_surface_color(backbuffer2
, 320, 240);
6739 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6740 fill_surface(backbuffer3
, 0xff0000ff);
6742 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
6743 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6744 color
= get_surface_color(backbuffer2
, 320, 240);
6745 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6746 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6747 color
= get_surface_color(backbuffer3
, 320, 240);
6748 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6749 fill_surface(backbuffer1
, 0xffff0000);
6751 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
6752 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6753 color
= get_surface_color(backbuffer1
, 320, 240);
6754 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6755 color
= get_surface_color(backbuffer3
, 320, 240);
6756 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6757 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6758 fill_surface(backbuffer2
, 0xff00ff00);
6760 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
6761 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6762 color
= get_surface_color(backbuffer1
, 320, 240);
6763 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6764 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6765 color
= get_surface_color(backbuffer2
, 320, 240);
6766 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6768 IDirectDrawSurface4_Release(backbuffer3
);
6769 IDirectDrawSurface4_Release(backbuffer2
);
6770 IDirectDrawSurface4_Release(backbuffer1
);
6771 IDirectDrawSurface4_Release(frontbuffer
);
6774 refcount
= IDirectDraw4_Release(ddraw
);
6775 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6776 DestroyWindow(window
);
6779 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
6781 memset(ddsd
, 0, sizeof(*ddsd
));
6782 ddsd
->dwSize
= sizeof(*ddsd
);
6785 static void test_set_surface_desc(void)
6787 IDirectDraw4
*ddraw
;
6790 DDSURFACEDESC2 ddsd
;
6791 IDirectDrawSurface4
*surface
;
6801 invalid_caps_tests
[] =
6803 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
6804 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
6805 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
6806 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
6807 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
6810 window
= create_window();
6811 ddraw
= create_ddraw();
6812 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6813 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6814 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6817 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6820 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6821 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6822 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6823 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6824 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6825 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6826 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6828 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6829 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6832 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6833 ddsd
.lpSurface
= data
;
6834 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6835 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6837 /* Redundantly setting the same lpSurface is not an error. */
6838 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6839 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6840 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6841 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6842 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6843 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
6845 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6846 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6847 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6848 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
6849 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6850 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6853 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6854 ddsd
.lpSurface
= data
;
6855 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 1);
6856 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
6858 ddsd
.lpSurface
= NULL
;
6859 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6860 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
6862 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, NULL
, 0);
6863 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
6865 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6866 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6867 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6868 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6869 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6871 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
6872 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6873 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
6875 ddsd
.dwFlags
= DDSD_CAPS
;
6876 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6877 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6879 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
6880 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
6881 ddsd
.lpSurface
= data
;
6882 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6883 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6884 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6885 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6886 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6887 ddsd
.ddsCaps
.dwCaps
= 0;
6888 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
6889 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6890 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6892 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6893 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6894 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6895 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6896 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6898 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
6900 ddsd
.dwFlags
= DDSD_HEIGHT
;
6902 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6903 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
6905 ddsd
.lpSurface
= data
;
6906 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
6907 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6908 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6911 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6912 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
6915 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6916 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
6917 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6918 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6920 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0 */
6922 ddsd
.dwFlags
= DDSD_PITCH
;
6923 U1(ddsd
).lPitch
= 8 * 4;
6924 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6925 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
6927 ddsd
.dwFlags
= DDSD_WIDTH
;
6929 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6930 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
6932 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
6933 ddsd
.lpSurface
= data
;
6934 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6935 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
6937 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
6938 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6939 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
6941 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6942 U1(ddsd
).lPitch
= 16 * 4;
6944 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6945 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6948 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6949 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6950 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6951 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6952 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
6954 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
6956 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
6957 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6958 U1(ddsd
).lPitch
= 4 * 4;
6959 ddsd
.lpSurface
= data
;
6960 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6961 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6963 U1(ddsd
).lPitch
= 4;
6964 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6965 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6967 U1(ddsd
).lPitch
= 16 * 4 + 1;
6968 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6969 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6971 U1(ddsd
).lPitch
= 16 * 4 + 3;
6972 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6973 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6975 U1(ddsd
).lPitch
= -4;
6976 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6977 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
6979 U1(ddsd
).lPitch
= 16 * 4;
6980 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6981 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6984 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6985 U1(ddsd
).lPitch
= 0;
6987 ddsd
.lpSurface
= data
;
6988 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6989 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
6991 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6992 U1(ddsd
).lPitch
= 16 * 4;
6994 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6995 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
6997 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
6998 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
6999 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7000 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7001 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7002 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7003 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7004 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7005 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7006 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
7008 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
7009 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7010 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7012 /* Can't set color keys. */
7014 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
7015 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
7016 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
7017 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7018 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7020 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
7021 ddsd
.lpSurface
= data
;
7022 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7023 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
7025 IDirectDrawSurface4_Release(surface
);
7027 /* SetSurfaceDesc needs systemmemory surfaces.
7029 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
7030 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
7033 ddsd
.dwFlags
= DDSD_CAPS
;
7034 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
7035 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
7036 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
7038 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7041 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7042 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7043 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7044 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7045 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7046 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7049 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7050 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
7053 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
7054 invalid_caps_tests
[i
].name
);
7059 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7060 ddsd
.lpSurface
= data
;
7061 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7062 if (invalid_caps_tests
[i
].supported
)
7064 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7068 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7069 invalid_caps_tests
[i
].name
, hr
);
7071 /* Check priority of error conditions. */
7072 ddsd
.dwFlags
= DDSD_WIDTH
;
7073 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7074 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
7075 invalid_caps_tests
[i
].name
, hr
);
7078 IDirectDrawSurface4_Release(surface
);
7082 ref
= IDirectDraw4_Release(ddraw
);
7083 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7084 DestroyWindow(window
);
7087 static void test_user_memory_getdc(void)
7089 IDirectDraw4
*ddraw
;
7092 DDSURFACEDESC2 ddsd
;
7093 IDirectDrawSurface4
*surface
;
7102 window
= create_window();
7103 ddraw
= create_ddraw();
7104 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7106 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7107 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7110 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
7113 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7114 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7115 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7116 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7117 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7118 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7119 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7120 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7121 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7123 memset(data
, 0xaa, sizeof(data
));
7125 ddsd
.dwFlags
= DDSD_LPSURFACE
;
7126 ddsd
.lpSurface
= data
;
7127 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7128 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7130 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
7131 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7132 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
7133 ok(!!bitmap
, "Failed to get bitmap.\n");
7134 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
7135 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
7136 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
7137 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
7138 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
7139 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
7140 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7142 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
7143 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
7145 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
7146 ddsd
.lpSurface
= data
;
7149 U1(ddsd
).lPitch
= sizeof(*data
);
7150 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
7151 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
7153 memset(data
, 0xaa, sizeof(data
));
7154 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
7155 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
7156 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
7157 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
7158 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
7159 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
7161 for (y
= 0; y
< 4; y
++)
7163 for (x
= 0; x
< 4; x
++)
7165 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
7166 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
7169 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
7173 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
7175 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
7177 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
7179 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
7182 IDirectDrawSurface4_Release(surface
);
7183 ref
= IDirectDraw4_Release(ddraw
);
7184 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7185 DestroyWindow(window
);
7188 static void test_sysmem_overlay(void)
7190 IDirectDraw4
*ddraw
;
7193 DDSURFACEDESC2 ddsd
;
7194 IDirectDrawSurface4
*surface
;
7197 window
= create_window();
7198 ddraw
= create_ddraw();
7199 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7201 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7202 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7205 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
7208 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
7209 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
7210 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7211 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7212 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7213 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7214 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7215 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
7216 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
7218 ref
= IDirectDraw4_Release(ddraw
);
7219 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
7220 DestroyWindow(window
);
7223 static void test_primary_palette(void)
7225 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
7226 IDirectDrawSurface4
*primary
, *backbuffer
;
7227 PALETTEENTRY palette_entries
[256];
7228 IDirectDrawPalette
*palette
, *tmp
;
7229 DDSURFACEDESC2 surface_desc
;
7230 IDirectDraw4
*ddraw
;
7236 window
= create_window();
7237 ddraw
= create_ddraw();
7238 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7239 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
7241 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
7242 IDirectDraw4_Release(ddraw
);
7243 DestroyWindow(window
);
7246 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7247 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7249 memset(&surface_desc
, 0, sizeof(surface_desc
));
7250 surface_desc
.dwSize
= sizeof(surface_desc
);
7251 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
7252 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
7253 U5(surface_desc
).dwBackBufferCount
= 1;
7254 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
7255 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7256 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
7257 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
7259 memset(palette_entries
, 0, sizeof(palette_entries
));
7260 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
7261 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7262 refcount
= get_refcount((IUnknown
*)palette
);
7263 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7265 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7266 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7267 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
7269 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
7270 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7272 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
7273 * and is generally somewhat broken with respect to 8 bpp / palette
7275 if (SUCCEEDED(IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
)))
7277 win_skip("Broken palette handling detected, skipping tests.\n");
7278 IDirectDrawPalette_Release(tmp
);
7279 IDirectDrawPalette_Release(palette
);
7280 /* The Windows 8 testbot keeps extra references to the primary and
7281 * backbuffer while in 8 bpp mode. */
7282 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
7283 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
7287 refcount
= get_refcount((IUnknown
*)palette
);
7288 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7290 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7291 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7292 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
7293 "Got unexpected palette caps %#x.\n", palette_caps
);
7295 hr
= IDirectDrawSurface4_SetPalette(primary
, NULL
);
7296 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7297 refcount
= get_refcount((IUnknown
*)palette
);
7298 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7300 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
7301 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
7302 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
7304 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
7305 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7306 refcount
= get_refcount((IUnknown
*)palette
);
7307 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7309 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
7310 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
7311 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
7312 IDirectDrawPalette_Release(tmp
);
7313 hr
= IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
);
7314 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
7316 refcount
= IDirectDrawPalette_Release(palette
);
7317 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7318 refcount
= IDirectDrawPalette_Release(palette
);
7319 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7321 /* Note that this only seems to work when the palette is attached to the
7322 * primary surface. When attached to a regular surface, attempting to get
7323 * the palette here will cause an access violation. */
7324 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
7325 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
7327 hr
= IDirectDrawSurface4_IsLost(primary
);
7328 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
7330 memset(&surface_desc
, 0, sizeof(surface_desc
));
7331 surface_desc
.dwSize
= sizeof(surface_desc
);
7332 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7333 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7334 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7335 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7336 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
7337 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7339 hr
= set_display_mode(ddraw
, 640, 480);
7340 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
7342 memset(&surface_desc
, 0, sizeof(surface_desc
));
7343 surface_desc
.dwSize
= sizeof(surface_desc
);
7344 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7345 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7346 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7347 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7348 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
7349 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
7350 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7352 hr
= IDirectDrawSurface4_IsLost(primary
);
7353 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7354 hr
= IDirectDrawSurface4_Restore(primary
);
7355 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
7356 hr
= IDirectDrawSurface4_IsLost(primary
);
7357 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7359 memset(&surface_desc
, 0, sizeof(surface_desc
));
7360 surface_desc
.dwSize
= sizeof(surface_desc
);
7361 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7362 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7363 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7364 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7365 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
7366 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
7367 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7370 refcount
= IDirectDrawSurface4_Release(backbuffer
);
7371 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7372 refcount
= IDirectDrawSurface4_Release(primary
);
7373 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7374 refcount
= IDirectDraw4_Release(ddraw
);
7375 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7376 DestroyWindow(window
);
7379 static HRESULT WINAPI
surface_counter(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
7381 UINT
*surface_count
= context
;
7384 IDirectDrawSurface_Release(surface
);
7386 return DDENUMRET_OK
;
7389 static void test_surface_attachment(void)
7391 IDirectDrawSurface4
*surface1
, *surface2
, *surface3
, *surface4
;
7392 IDirectDrawSurface
*surface1v1
, *surface2v1
;
7393 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7394 DDSURFACEDESC2 surface_desc
;
7395 IDirectDraw4
*ddraw
;
7401 window
= create_window();
7402 ddraw
= create_ddraw();
7403 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7404 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7405 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7407 memset(&surface_desc
, 0, sizeof(surface_desc
));
7408 surface_desc
.dwSize
= sizeof(surface_desc
);
7409 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
7410 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7411 U2(surface_desc
).dwMipMapCount
= 3;
7412 surface_desc
.dwWidth
= 128;
7413 surface_desc
.dwHeight
= 128;
7414 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7415 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7417 hr
= IDirectDrawSurface4_GetAttachedSurface(surface1
, &caps
, &surface2
);
7418 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7419 hr
= IDirectDrawSurface4_GetAttachedSurface(surface2
, &caps
, &surface3
);
7420 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7421 hr
= IDirectDrawSurface4_GetAttachedSurface(surface3
, &caps
, &surface4
);
7422 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7425 IDirectDrawSurface4_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
7426 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7428 IDirectDrawSurface4_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
7429 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7431 IDirectDrawSurface4_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
7432 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
7434 memset(&surface_desc
, 0, sizeof(surface_desc
));
7435 surface_desc
.dwSize
= sizeof(surface_desc
);
7436 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7437 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7438 surface_desc
.dwWidth
= 16;
7439 surface_desc
.dwHeight
= 16;
7440 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7441 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7443 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7444 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7445 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7446 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7447 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7448 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7449 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7450 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7451 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7452 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7453 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7454 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7456 IDirectDrawSurface4_Release(surface4
);
7458 memset(&surface_desc
, 0, sizeof(surface_desc
));
7459 surface_desc
.dwSize
= sizeof(surface_desc
);
7460 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7461 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7462 surface_desc
.dwWidth
= 16;
7463 surface_desc
.dwHeight
= 16;
7464 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7465 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7467 if (SUCCEEDED(hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
)))
7469 skip("Running on refrast, skipping some tests.\n");
7470 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface4
);
7471 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7475 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7476 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7477 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7478 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7479 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7480 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7481 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7482 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7483 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7484 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7485 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7488 IDirectDrawSurface4_Release(surface4
);
7489 IDirectDrawSurface4_Release(surface3
);
7490 IDirectDrawSurface4_Release(surface2
);
7491 IDirectDrawSurface4_Release(surface1
);
7493 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7494 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7496 /* Try a single primary and two offscreen plain surfaces. */
7497 memset(&surface_desc
, 0, sizeof(surface_desc
));
7498 surface_desc
.dwSize
= sizeof(surface_desc
);
7499 surface_desc
.dwFlags
= DDSD_CAPS
;
7500 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7501 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7502 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7504 memset(&surface_desc
, 0, sizeof(surface_desc
));
7505 surface_desc
.dwSize
= sizeof(surface_desc
);
7506 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7507 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7508 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7509 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7510 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7511 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7513 memset(&surface_desc
, 0, sizeof(surface_desc
));
7514 surface_desc
.dwSize
= sizeof(surface_desc
);
7515 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7516 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7517 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7518 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7519 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7520 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7522 /* This one has a different size. */
7523 memset(&surface_desc
, 0, sizeof(surface_desc
));
7524 surface_desc
.dwSize
= sizeof(surface_desc
);
7525 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7526 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7527 surface_desc
.dwWidth
= 128;
7528 surface_desc
.dwHeight
= 128;
7529 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7530 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7532 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7533 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7534 /* Try the reverse without detaching first. */
7535 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7536 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7537 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7538 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7540 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7541 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7542 /* Try to detach reversed. */
7543 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7544 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7545 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface1
);
7546 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7548 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface3
);
7549 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7550 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface3
);
7551 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7553 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7554 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7555 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7556 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7558 IDirectDrawSurface4_Release(surface4
);
7559 IDirectDrawSurface4_Release(surface3
);
7560 IDirectDrawSurface4_Release(surface2
);
7561 IDirectDrawSurface4_Release(surface1
);
7563 /* Test depth surfaces of different sizes. */
7564 memset(&surface_desc
, 0, sizeof(surface_desc
));
7565 surface_desc
.dwSize
= sizeof(surface_desc
);
7566 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7567 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
7568 surface_desc
.dwWidth
= 64;
7569 surface_desc
.dwHeight
= 64;
7570 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7571 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
7573 memset(&surface_desc
, 0, sizeof(surface_desc
));
7574 surface_desc
.dwSize
= sizeof(surface_desc
);
7575 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
7576 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7577 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7578 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
7579 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
7580 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
7581 surface_desc
.dwWidth
= 32;
7582 surface_desc
.dwHeight
= 32;
7583 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7584 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
7585 surface_desc
.dwWidth
= 64;
7586 surface_desc
.dwHeight
= 64;
7587 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7588 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
7589 surface_desc
.dwWidth
= 128;
7590 surface_desc
.dwHeight
= 128;
7591 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7592 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
7594 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface2
);
7595 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7597 IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface3
);
7598 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface3
);
7599 ok(hr
== D3D_OK
, "Failed to attach depth buffer, hr %#x.\n", hr
);
7600 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface3
);
7601 ok(hr
== D3D_OK
, "Failed to detach depth buffer, hr %#x.\n", hr
);
7602 hr
= IDirectDrawSurface_AddAttachedSurface(surface1
, surface4
);
7603 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7605 IDirectDrawSurface4_Release(surface4
);
7606 IDirectDrawSurface4_Release(surface3
);
7607 IDirectDrawSurface4_Release(surface2
);
7608 IDirectDrawSurface4_Release(surface1
);
7610 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
7611 memset(&surface_desc
, 0, sizeof(surface_desc
));
7612 surface_desc
.dwSize
= sizeof(surface_desc
);
7613 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7614 surface_desc
.dwWidth
= 64;
7615 surface_desc
.dwHeight
= 64;
7616 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
7617 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7618 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
7619 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
7620 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
7621 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
7622 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
7623 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7624 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7625 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7626 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7628 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7629 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
7630 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
7631 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
7632 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7633 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7635 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
7636 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7637 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
7638 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7640 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7641 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7642 refcount
= get_refcount((IUnknown
*)surface2
);
7643 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7644 refcount
= get_refcount((IUnknown
*)surface2v1
);
7645 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7646 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7647 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7648 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7649 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7650 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7651 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7653 /* Attaching while already attached to other surface. */
7654 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface2
);
7655 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7656 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface3
, 0, surface2
);
7657 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7658 IDirectDrawSurface4_Release(surface3
);
7660 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7661 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7662 refcount
= get_refcount((IUnknown
*)surface2
);
7663 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7664 refcount
= get_refcount((IUnknown
*)surface2v1
);
7665 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7667 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
7668 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7669 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7670 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7671 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7672 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7673 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7674 refcount
= IDirectDrawSurface4_Release(surface2
);
7675 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7676 refcount
= IDirectDrawSurface4_Release(surface1
);
7677 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7679 /* Automatic detachment on release. */
7680 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7681 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7682 refcount
= get_refcount((IUnknown
*)surface2v1
);
7683 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7684 refcount
= IDirectDrawSurface_Release(surface1v1
);
7685 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7686 refcount
= IDirectDrawSurface_Release(surface2v1
);
7687 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7688 refcount
= IDirectDraw4_Release(ddraw
);
7689 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7690 DestroyWindow(window
);
7693 static void test_private_data(void)
7695 IDirectDraw4
*ddraw
;
7696 IDirectDrawSurface4
*surface
, *surface2
;
7697 DDSURFACEDESC2 surface_desc
;
7698 ULONG refcount
, refcount2
, refcount3
;
7700 DWORD size
= sizeof(ptr
);
7703 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7704 DWORD data
[] = {1, 2, 3, 4};
7706 static const GUID ddraw_private_data_test_guid
=
7711 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
7713 static const GUID ddraw_private_data_test_guid2
=
7718 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
7721 window
= create_window();
7722 ddraw
= create_ddraw();
7723 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7724 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7725 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7727 reset_ddsd(&surface_desc
);
7728 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
7729 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
7730 surface_desc
.dwHeight
= 4;
7731 surface_desc
.dwWidth
= 4;
7732 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7733 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7735 /* NULL pointers are not valid, but don't cause a crash. */
7736 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
7737 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
7738 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7739 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
7740 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7741 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
7742 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7744 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
7745 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7746 0, DDSPD_IUNKNOWNPOINTER
);
7747 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7748 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7749 5, DDSPD_IUNKNOWNPOINTER
);
7750 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7751 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7752 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
7753 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7755 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
7756 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
7757 * erases the old content and returns an error. This behavior has
7758 * been fixed in d3d8 and d3d9. Unless an application is found
7759 * that depends on this we don't care about this behavior. */
7760 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7761 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7762 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7763 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7764 0, DDSPD_IUNKNOWNPOINTER
);
7765 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7767 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7768 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7769 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7770 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7772 refcount
= get_refcount((IUnknown
*)ddraw
);
7773 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7774 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7775 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7776 refcount2
= get_refcount((IUnknown
*)ddraw
);
7777 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7779 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7780 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7781 refcount2
= get_refcount((IUnknown
*)ddraw
);
7782 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7784 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7785 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7786 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7787 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
7788 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
7789 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7790 refcount2
= get_refcount((IUnknown
*)ddraw
);
7791 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7793 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7794 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7795 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7796 size
= 2 * sizeof(ptr
);
7797 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7798 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7799 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7800 refcount2
= get_refcount(ptr
);
7801 /* Object is NOT addref'ed by the getter. */
7802 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
7803 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7805 ptr
= (IUnknown
*)0xdeadbeef;
7807 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7808 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7809 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7810 size
= 2 * sizeof(ptr
);
7811 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7812 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7813 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %u.\n", size
);
7815 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7816 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7817 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7818 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7819 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
7820 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7822 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
7823 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7824 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7825 ok(size
== 0xdeadbabe, "Got unexpected size %u.\n", size
);
7826 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7827 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7829 refcount3
= IDirectDrawSurface4_Release(surface
);
7830 ok(!refcount3
, "Got unexpected refcount %u.\n", refcount3
);
7832 /* Destroying the surface frees the reference held on the private data. It also frees
7833 * the reference the surface is holding on its creating object. */
7834 refcount2
= get_refcount((IUnknown
*)ddraw
);
7835 ok(refcount2
== refcount
- 1, "Got unexpected refcount %u.\n", refcount2
);
7837 memset(&hal_caps
, 0, sizeof(hal_caps
));
7838 hal_caps
.dwSize
= sizeof(hal_caps
);
7839 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
7840 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7841 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7843 reset_ddsd(&surface_desc
);
7844 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
7845 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7846 surface_desc
.dwHeight
= 4;
7847 surface_desc
.dwWidth
= 4;
7848 U2(surface_desc
).dwMipMapCount
= 2;
7849 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7850 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7851 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7852 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
7854 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
7855 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7856 hr
= IDirectDrawSurface4_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7857 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7859 IDirectDrawSurface4_Release(surface2
);
7860 IDirectDrawSurface4_Release(surface
);
7863 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
7865 refcount
= IDirectDraw4_Release(ddraw
);
7866 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7867 DestroyWindow(window
);
7870 static void test_pixel_format(void)
7872 HWND window
, window2
= NULL
;
7873 HDC hdc
, hdc2
= NULL
;
7875 int format
, test_format
;
7876 PIXELFORMATDESCRIPTOR pfd
;
7877 IDirectDraw4
*ddraw
= NULL
;
7878 IDirectDrawClipper
*clipper
= NULL
;
7879 DDSURFACEDESC2 ddsd
;
7880 IDirectDrawSurface4
*primary
= NULL
;
7884 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7885 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7888 skip("Failed to create window\n");
7892 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7893 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7895 hdc
= GetDC(window
);
7898 skip("Failed to get DC\n");
7903 hdc2
= GetDC(window2
);
7905 gl
= LoadLibraryA("opengl32.dll");
7906 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
7908 format
= GetPixelFormat(hdc
);
7909 ok(format
== 0, "new window has pixel format %d\n", format
);
7911 ZeroMemory(&pfd
, sizeof(pfd
));
7912 pfd
.nSize
= sizeof(pfd
);
7914 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
7915 pfd
.iPixelType
= PFD_TYPE_RGBA
;
7916 pfd
.iLayerType
= PFD_MAIN_PLANE
;
7917 format
= ChoosePixelFormat(hdc
, &pfd
);
7920 skip("no pixel format available\n");
7924 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7926 skip("failed to set pixel format\n");
7930 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7932 skip("failed to set pixel format on second window\n");
7935 ReleaseDC(window2
, hdc2
);
7940 ddraw
= create_ddraw();
7941 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7943 test_format
= GetPixelFormat(hdc
);
7944 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7946 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7949 skip("Failed to set cooperative level, hr %#x.\n", hr
);
7953 test_format
= GetPixelFormat(hdc
);
7954 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7958 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
7959 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
7960 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
7961 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
7963 test_format
= GetPixelFormat(hdc
);
7964 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7966 test_format
= GetPixelFormat(hdc2
);
7967 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7970 memset(&ddsd
, 0, sizeof(ddsd
));
7971 ddsd
.dwSize
= sizeof(ddsd
);
7972 ddsd
.dwFlags
= DDSD_CAPS
;
7973 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7975 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7976 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
7978 test_format
= GetPixelFormat(hdc
);
7979 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7983 test_format
= GetPixelFormat(hdc2
);
7984 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7989 hr
= IDirectDrawSurface4_SetClipper(primary
, clipper
);
7990 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
7992 test_format
= GetPixelFormat(hdc
);
7993 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7995 test_format
= GetPixelFormat(hdc2
);
7996 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7999 memset(&fx
, 0, sizeof(fx
));
8000 fx
.dwSize
= sizeof(fx
);
8001 hr
= IDirectDrawSurface4_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8002 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
8004 test_format
= GetPixelFormat(hdc
);
8005 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
8009 test_format
= GetPixelFormat(hdc2
);
8010 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
8014 if (primary
) IDirectDrawSurface4_Release(primary
);
8015 if (clipper
) IDirectDrawClipper_Release(clipper
);
8016 if (ddraw
) IDirectDraw4_Release(ddraw
);
8017 if (gl
) FreeLibrary(gl
);
8018 if (hdc
) ReleaseDC(window
, hdc
);
8019 if (hdc2
) ReleaseDC(window2
, hdc2
);
8020 DestroyWindow(window
);
8021 if (window2
) DestroyWindow(window2
);
8024 static void test_create_surface_pitch(void)
8026 IDirectDrawSurface4
*surface
;
8027 DDSURFACEDESC2 surface_desc
;
8028 IDirectDraw4
*ddraw
;
8048 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8050 DDSD_PITCH
, 0x100, 0x100},
8051 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8052 DDSD_PITCH
, 0x104, DD_OK
,
8053 DDSD_PITCH
, 0x100, 0x100},
8054 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8055 DDSD_PITCH
, 0x0f8, DD_OK
,
8056 DDSD_PITCH
, 0x100, 0x100},
8057 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8058 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8060 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8062 DDSD_PITCH
, 0x100, 0x0fc},
8064 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8065 DDSD_PITCH
, 0x104, DD_OK
,
8066 DDSD_PITCH
, 0x100, 0x0fc},
8067 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8068 DDSD_PITCH
, 0x0f8, DD_OK
,
8069 DDSD_PITCH
, 0x100, 0x0fc},
8070 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8071 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
8072 DDSD_PITCH
, 0x100, 0x0fc},
8073 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8074 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
8076 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8077 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8078 DDSD_PITCH
, 0x100, 0x100},
8080 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8081 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
8083 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8084 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
8085 DDSD_PITCH
, 0x0fc, 0x0fc},
8086 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8087 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
8089 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8090 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
8092 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8093 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
8096 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
8097 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
8098 DDSD_PITCH
, 0x100, 0x100},
8099 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8100 0, 0, DDERR_INVALIDCAPS
,
8102 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8104 DDSD_PITCH
, 0x100, 0 },
8105 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8106 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
8108 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
8109 0, 0, DDERR_INVALIDCAPS
,
8112 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8114 DDSD_PITCH
, 0x100, 0 },
8115 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
8116 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
8117 DDSD_PITCH
, 0x100, 0 },
8119 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
8121 window
= create_window();
8122 ddraw
= create_ddraw();
8123 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8124 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8125 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8127 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
8129 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8131 memset(&surface_desc
, 0, sizeof(surface_desc
));
8132 surface_desc
.dwSize
= sizeof(surface_desc
);
8133 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
8134 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8135 surface_desc
.dwWidth
= 63;
8136 surface_desc
.dwHeight
= 63;
8137 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
8138 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8139 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8140 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8141 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8142 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8143 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8144 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8145 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
8147 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
8148 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
8149 surface_desc
.lpSurface
= mem
;
8150 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8152 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
8154 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
8158 memset(&surface_desc
, 0, sizeof(surface_desc
));
8159 surface_desc
.dwSize
= sizeof(surface_desc
);
8160 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
8161 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
8162 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
8163 "Test %u: Got unexpected flags %#x, expected %#x.\n",
8164 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
8165 /* The pitch for textures seems to be implementation specific. */
8166 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
8168 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
8169 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
8170 "Test %u: Got unexpected pitch %u, expected %u.\n",
8171 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
8173 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
8174 "Test %u: Got unexpected pitch %u, expected %u.\n",
8175 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
8177 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
8179 IDirectDrawSurface4_Release(surface
);
8182 HeapFree(GetProcessHeap(), 0, mem
);
8183 refcount
= IDirectDraw4_Release(ddraw
);
8184 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8185 DestroyWindow(window
);
8188 static void test_mipmap(void)
8190 IDirectDrawSurface4
*surface
, *surface_base
, *surface_mip
;
8191 unsigned int i
, mipmap_count
;
8192 DDSURFACEDESC2 surface_desc
;
8193 IDirectDraw4
*ddraw
;
8197 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8206 DWORD mipmap_count_in
;
8208 DWORD mipmap_count_out
;
8212 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
8213 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
8214 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
8215 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
8216 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
8217 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
8220 window
= create_window();
8221 ddraw
= create_ddraw();
8222 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8223 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8224 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8226 memset(&hal_caps
, 0, sizeof(hal_caps
));
8227 hal_caps
.dwSize
= sizeof(hal_caps
);
8228 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
8229 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8230 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
8232 skip("Mipmapped textures not supported, skipping tests.\n");
8233 IDirectDraw4_Release(ddraw
);
8234 DestroyWindow(window
);
8238 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8240 memset(&surface_desc
, 0, sizeof(surface_desc
));
8241 surface_desc
.dwSize
= sizeof(surface_desc
);
8242 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
8243 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
8244 surface_desc
.dwWidth
= tests
[i
].width
;
8245 surface_desc
.dwHeight
= tests
[i
].height
;
8246 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
8247 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
8248 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8249 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
8253 memset(&surface_desc
, 0, sizeof(surface_desc
));
8254 surface_desc
.dwSize
= sizeof(surface_desc
);
8255 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
8256 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
8257 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
8258 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
8259 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
8260 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
8262 surface_base
= surface
;
8263 IDirectDrawSurface4_AddRef(surface_base
);
8264 mipmap_count
= U2(surface_desc
).dwMipMapCount
;
8265 while (mipmap_count
> 1)
8267 hr
= IDirectDrawSurface4_GetAttachedSurface(surface_base
, &caps
, &surface_mip
);
8268 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get attached surface, hr %#x.\n", i
, mipmap_count
, hr
);
8270 memset(&surface_desc
, 0, sizeof(surface_desc
));
8271 surface_desc
.dwSize
= sizeof(surface_desc
);
8272 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface_base
, &surface_desc
);
8273 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to get surface desc, hr %#x.\n", i
, mipmap_count
, hr
);
8274 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
8275 "Test %u, %u: Got unexpected flags %#x.\n", i
, mipmap_count
, surface_desc
.dwFlags
);
8276 ok(U2(surface_desc
).dwMipMapCount
== mipmap_count
,
8277 "Test %u, %u: Got unexpected mipmap count %u.\n",
8278 i
, mipmap_count
, U2(surface_desc
).dwMipMapCount
);
8280 memset(&surface_desc
, 0, sizeof(surface_desc
));
8281 surface_desc
.dwSize
= sizeof(surface_desc
);
8282 hr
= IDirectDrawSurface4_Lock(surface_base
, NULL
, &surface_desc
, 0, NULL
);
8283 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
8284 ok(surface_desc
.dwMipMapCount
== mipmap_count
,
8285 "Test %u, %u: unexpected change of mipmap count %u.\n",
8286 i
, mipmap_count
, surface_desc
.dwMipMapCount
);
8287 memset(&surface_desc
, 0, sizeof(surface_desc
));
8288 surface_desc
.dwSize
= sizeof(surface_desc
);
8289 hr
= IDirectDrawSurface4_Lock(surface_mip
, NULL
, &surface_desc
, 0, NULL
);
8290 ok(SUCCEEDED(hr
), "Test %u, %u: Failed to lock surface, hr %#x.\n", i
, mipmap_count
, hr
);
8291 ok(surface_desc
.dwMipMapCount
== mipmap_count
- 1,
8292 "Test %u, %u: Child mipmap count unexpected %u\n", i
, mipmap_count
, surface_desc
.dwMipMapCount
);
8293 IDirectDrawSurface4_Unlock(surface_mip
, NULL
);
8294 IDirectDrawSurface4_Unlock(surface_base
, NULL
);
8296 IDirectDrawSurface4_Release(surface_base
);
8297 surface_base
= surface_mip
;
8300 IDirectDrawSurface4_Release(surface_base
);
8302 IDirectDrawSurface4_Release(surface
);
8305 refcount
= IDirectDraw4_Release(ddraw
);
8306 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8307 DestroyWindow(window
);
8310 static void test_palette_complex(void)
8312 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
8313 DDSURFACEDESC2 surface_desc
;
8314 IDirectDraw4
*ddraw
;
8315 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
8319 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
8321 PALETTEENTRY palette_entries
[256];
8327 window
= create_window();
8328 ddraw
= create_ddraw();
8329 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8330 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8331 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8333 memset(&hal_caps
, 0, sizeof(hal_caps
));
8334 hal_caps
.dwSize
= sizeof(hal_caps
);
8335 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
8336 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
8337 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
8339 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
8340 IDirectDraw4_Release(ddraw
);
8341 DestroyWindow(window
);
8345 memset(&surface_desc
, 0, sizeof(surface_desc
));
8346 surface_desc
.dwSize
= sizeof(surface_desc
);
8347 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8348 surface_desc
.dwWidth
= 128;
8349 surface_desc
.dwHeight
= 128;
8350 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
8351 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8352 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8353 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8354 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8355 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8357 memset(palette_entries
, 0, sizeof(palette_entries
));
8358 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8359 palette_entries
, &palette
, NULL
);
8360 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8362 memset(palette_entries
, 0, sizeof(palette_entries
));
8363 palette_entries
[1].peRed
= 0xff;
8364 palette_entries
[1].peGreen
= 0x80;
8365 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8366 palette_entries
, &palette_mipmap
, NULL
);
8367 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8369 palette2
= (void *)0xdeadbeef;
8370 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
8371 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
8372 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
8373 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8374 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8375 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
8376 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
8377 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
8378 IDirectDrawPalette_Release(palette2
);
8381 IDirectDrawSurface4_AddRef(mipmap
);
8382 for (i
= 0; i
< 7; ++i
)
8384 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
8385 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
8386 palette2
= (void *)0xdeadbeef;
8387 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
8388 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
8389 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
8391 hr
= IDirectDrawSurface4_SetPalette(tmp
, palette_mipmap
);
8392 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
8394 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
8395 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
8396 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
8397 IDirectDrawPalette_Release(palette2
);
8399 hr
= IDirectDrawSurface4_GetDC(tmp
, &dc
);
8400 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
8401 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8402 ok(count
== 1, "Expected count 1, got %u.\n", count
);
8403 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
8404 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
8405 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
8406 hr
= IDirectDrawSurface4_ReleaseDC(tmp
, dc
);
8407 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
8409 IDirectDrawSurface4_Release(mipmap
);
8413 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
8414 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
8415 IDirectDrawSurface4_Release(mipmap
);
8416 refcount
= IDirectDrawSurface4_Release(surface
);
8417 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8418 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
8419 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8420 refcount
= IDirectDrawPalette_Release(palette
);
8421 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8423 refcount
= IDirectDraw4_Release(ddraw
);
8424 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8425 DestroyWindow(window
);
8428 static void test_p8_blit(void)
8430 IDirectDrawSurface4
*src
, *dst
, *dst_p8
;
8431 DDSURFACEDESC2 surface_desc
;
8432 IDirectDraw4
*ddraw
;
8433 IDirectDrawPalette
*palette
, *palette2
;
8437 PALETTEENTRY palette_entries
[256];
8441 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
8442 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
8443 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
8444 static const D3DCOLOR expected
[] =
8446 0x00101010, 0x00010101, 0x00020202, 0x00030303,
8447 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
8451 window
= create_window();
8452 ddraw
= create_ddraw();
8453 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8454 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8455 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8456 is_warp
= ddraw_is_warp(ddraw
);
8458 memset(palette_entries
, 0, sizeof(palette_entries
));
8459 palette_entries
[1].peGreen
= 0xff;
8460 palette_entries
[2].peBlue
= 0xff;
8461 palette_entries
[3].peFlags
= 0xff;
8462 palette_entries
[4].peRed
= 0xff;
8463 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8464 palette_entries
, &palette
, NULL
);
8465 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8466 palette_entries
[1].peBlue
= 0xff;
8467 palette_entries
[2].peGreen
= 0xff;
8468 palette_entries
[3].peRed
= 0xff;
8469 palette_entries
[4].peFlags
= 0x0;
8470 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8471 palette_entries
, &palette2
, NULL
);
8472 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8474 memset(&surface_desc
, 0, sizeof(surface_desc
));
8475 surface_desc
.dwSize
= sizeof(surface_desc
);
8476 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8477 surface_desc
.dwWidth
= 8;
8478 surface_desc
.dwHeight
= 1;
8479 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8480 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8481 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8482 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8483 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
8484 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8485 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
8486 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8487 hr
= IDirectDrawSurface4_SetPalette(dst_p8
, palette2
);
8488 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8490 memset(&surface_desc
, 0, sizeof(surface_desc
));
8491 surface_desc
.dwSize
= sizeof(surface_desc
);
8492 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8493 surface_desc
.dwWidth
= 8;
8494 surface_desc
.dwHeight
= 1;
8495 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8496 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8497 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8498 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8499 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8500 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8501 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8502 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8503 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
8504 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8506 memset(&surface_desc
, 0, sizeof(surface_desc
));
8507 surface_desc
.dwSize
= sizeof(surface_desc
);
8508 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8509 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
8510 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
8511 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
8512 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
8514 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8515 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8516 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
8517 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8518 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8520 hr
= IDirectDrawSurface4_SetPalette(src
, palette
);
8521 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8522 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
8523 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
8524 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
8525 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
8526 "Failed to blit, hr %#x.\n", hr
);
8530 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
8532 color
= get_surface_color(dst
, x
, 0);
8533 todo_wine
ok(compare_color(color
, expected
[x
], 0),
8534 "Pixel %u: Got color %#x, expected %#x.\n",
8535 x
, color
, expected
[x
]);
8539 memset(&fx
, 0, sizeof(fx
));
8540 fx
.dwSize
= sizeof(fx
);
8541 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
8542 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
8543 hr
= IDirectDrawSurface4_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
8544 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8546 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
8547 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8548 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
8549 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
8550 * for example) also works as expected.
8552 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
8553 * the display mode set to P8 doesn't help either. */
8554 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
8555 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
8556 "Got unexpected P8 color key blit result.\n");
8557 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8558 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8560 IDirectDrawSurface4_Release(src
);
8561 IDirectDrawSurface4_Release(dst
);
8562 IDirectDrawSurface4_Release(dst_p8
);
8563 IDirectDrawPalette_Release(palette
);
8564 IDirectDrawPalette_Release(palette2
);
8566 refcount
= IDirectDraw4_Release(ddraw
);
8567 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8568 DestroyWindow(window
);
8571 static void test_material(void)
8573 D3DMATERIALHANDLE mat_handle
, tmp
;
8574 IDirect3DMaterial3
*material
;
8575 IDirect3DViewport3
*viewport
;
8576 IDirect3DDevice3
*device
;
8577 IDirectDrawSurface4
*rt
;
8587 struct vec3 position
;
8593 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8594 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8595 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8596 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8600 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8601 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8602 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8603 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8609 D3DCOLOR expected_color
;
8613 {quad1
, TRUE
, 0x0000ff00},
8614 {quad2
, TRUE
, 0x0000ff00},
8615 {quad1
, FALSE
, 0x00ffffff},
8616 {quad2
, FALSE
, 0x00ff0000},
8618 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8620 window
= create_window();
8621 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
8623 skip("Failed to create a 3D device, skipping test.\n");
8624 DestroyWindow(window
);
8628 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
8629 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8631 viewport
= create_viewport(device
, 0, 0, 640, 480);
8632 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
8633 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
8635 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
8636 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8637 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8639 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8640 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8641 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8642 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8643 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8644 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8645 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8646 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8647 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
8648 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8649 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8650 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8651 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8653 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8655 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
8656 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
8657 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8659 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
8660 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8662 hr
= IDirect3DDevice3_BeginScene(device
);
8663 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8664 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
8665 D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
, test_data
[i
].data
, 4, 0);
8666 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8667 hr
= IDirect3DDevice3_EndScene(device
);
8668 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8669 color
= get_surface_color(rt
, 320, 240);
8670 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
8671 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
8674 destroy_material(material
);
8675 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8676 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8677 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8679 hr
= IDirect3DViewport3_SetBackground(viewport
, mat_handle
);
8680 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
8681 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8682 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8683 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8684 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8685 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8686 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8687 color
= get_surface_color(rt
, 320, 240);
8688 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8690 hr
= IDirect3DViewport3_SetBackground(viewport
, 0);
8691 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8692 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8693 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8694 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8695 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8696 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8697 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8698 color
= get_surface_color(rt
, 320, 240);
8699 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8701 destroy_viewport(device
, viewport
);
8702 viewport
= create_viewport(device
, 0, 0, 640, 480);
8704 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8705 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8706 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8707 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
8708 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8709 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8710 color
= get_surface_color(rt
, 320, 240);
8711 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
8713 destroy_viewport(device
, viewport
);
8714 destroy_material(material
);
8715 IDirectDrawSurface4_Release(rt
);
8716 refcount
= IDirect3DDevice3_Release(device
);
8717 ok(!refcount
, "Device has %u references left.\n", refcount
);
8718 DestroyWindow(window
);
8721 static void test_palette_gdi(void)
8723 IDirectDrawSurface4
*surface
, *primary
;
8724 DDSURFACEDESC2 surface_desc
;
8725 IDirectDraw4
*ddraw
;
8726 IDirectDrawPalette
*palette
, *palette2
;
8730 PALETTEENTRY palette_entries
[256];
8736 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8737 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8738 * not the point of this test. */
8739 static const RGBQUAD expected1
[] =
8741 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8742 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8744 static const RGBQUAD expected2
[] =
8746 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8747 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8749 static const RGBQUAD expected3
[] =
8751 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8752 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8754 HPALETTE ddraw_palette_handle
;
8755 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8756 RGBQUAD rgbquad
[255];
8757 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8759 window
= create_window();
8760 ddraw
= create_ddraw();
8761 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8762 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8763 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8765 memset(&surface_desc
, 0, sizeof(surface_desc
));
8766 surface_desc
.dwSize
= sizeof(surface_desc
);
8767 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8768 surface_desc
.dwWidth
= 16;
8769 surface_desc
.dwHeight
= 16;
8770 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8771 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8772 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8773 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8774 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8775 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8777 /* Avoid colors from the Windows default palette. */
8778 memset(palette_entries
, 0, sizeof(palette_entries
));
8779 palette_entries
[1].peRed
= 0x01;
8780 palette_entries
[2].peGreen
= 0x02;
8781 palette_entries
[3].peBlue
= 0x03;
8782 palette_entries
[4].peRed
= 0x13;
8783 palette_entries
[4].peGreen
= 0x14;
8784 palette_entries
[4].peBlue
= 0x15;
8785 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8786 palette_entries
, &palette
, NULL
);
8787 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8789 /* If there is no palette assigned and the display mode is not 8 bpp, some
8790 * drivers refuse to create a DC while others allow it. If a DC is created,
8791 * the DIB color table is uninitialized and contains random colors. No error
8792 * is generated when trying to read pixels and random garbage is returned.
8794 * The most likely explanation is that if the driver creates a DC, it (or
8795 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8796 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8797 * contains uninitialized garbage. See comments below for the P8 case. */
8799 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8800 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8801 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8802 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8803 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8804 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8805 "Got unexpected palette %p, expected %p.\n",
8806 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8808 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8809 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8810 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8812 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8813 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8814 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8815 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8817 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8819 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8820 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8821 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8824 /* Update the palette while the DC is in use. This does not modify the DC. */
8825 palette_entries
[4].peRed
= 0x23;
8826 palette_entries
[4].peGreen
= 0x24;
8827 palette_entries
[4].peBlue
= 0x25;
8828 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8829 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
8831 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8832 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8833 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8834 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8835 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8836 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8838 /* Neither does re-setting the palette. */
8839 hr
= IDirectDrawSurface4_SetPalette(surface
, NULL
);
8840 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8841 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8842 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8844 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8845 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8846 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8847 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8848 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8849 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8851 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8852 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8854 /* Refresh the DC. This updates the palette. */
8855 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8856 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8857 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8858 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8859 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8861 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8862 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8863 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8864 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8866 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8868 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8869 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8870 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8872 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8873 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8875 refcount
= IDirectDrawSurface4_Release(surface
);
8876 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8878 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8879 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8880 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8882 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8883 IDirectDrawPalette_Release(palette
);
8884 IDirectDraw4_Release(ddraw
);
8885 DestroyWindow(window
);
8888 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8890 memset(&surface_desc
, 0, sizeof(surface_desc
));
8891 surface_desc
.dwSize
= sizeof(surface_desc
);
8892 surface_desc
.dwFlags
= DDSD_CAPS
;
8893 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8894 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8895 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8897 memset(&fx
, 0, sizeof(fx
));
8898 fx
.dwSize
= sizeof(fx
);
8899 U5(fx
).dwFillColor
= 3;
8900 SetRect(&r
, 0, 0, 319, 479);
8901 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8902 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8903 SetRect(&r
, 320, 0, 639, 479);
8904 U5(fx
).dwFillColor
= 4;
8905 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8906 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8908 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
8909 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8910 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
8911 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8913 color
= GetPixel(dc
, 160, 240);
8914 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8915 color
= GetPixel(dc
, 480, 240);
8916 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8918 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8919 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8920 "Got unexpected palette %p, expected %p.\n",
8921 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8922 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8924 /* The primary uses the system palette. In exclusive mode, the system palette matches
8925 * the ddraw palette attached to the primary, so the result is what you would expect
8926 * from a regular surface. Tests for the interaction between the ddraw palette and
8927 * the system palette are not included pending an application that depends on this.
8928 * The relation between those causes problems on Windows Vista and newer for games
8929 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8930 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8931 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8932 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8934 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8935 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8936 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8937 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8939 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8941 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8942 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8943 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8945 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
8946 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8948 memset(&surface_desc
, 0, sizeof(surface_desc
));
8949 surface_desc
.dwSize
= sizeof(surface_desc
);
8950 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8951 surface_desc
.dwWidth
= 16;
8952 surface_desc
.dwHeight
= 16;
8953 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8954 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8955 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8957 /* Here the offscreen surface appears to use the primary's palette,
8958 * but in all likelihood it is actually the system palette. */
8959 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8960 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8961 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8962 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8963 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8965 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8966 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8967 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8968 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8970 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8972 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8973 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8974 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8976 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8977 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8979 /* On real hardware a change to the primary surface's palette applies immediately,
8980 * even on device contexts from offscreen surfaces that do not have their own
8981 * palette. On the testbot VMs this is not the case. Don't test this until we
8982 * know of an application that depends on this. */
8984 memset(palette_entries
, 0, sizeof(palette_entries
));
8985 palette_entries
[1].peBlue
= 0x40;
8986 palette_entries
[2].peRed
= 0x40;
8987 palette_entries
[3].peGreen
= 0x40;
8988 palette_entries
[4].peRed
= 0x12;
8989 palette_entries
[4].peGreen
= 0x34;
8990 palette_entries
[4].peBlue
= 0x56;
8991 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8992 palette_entries
, &palette2
, NULL
);
8993 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8994 hr
= IDirectDrawSurface4_SetPalette(surface
, palette2
);
8995 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8997 /* A palette assigned to the offscreen surface overrides the primary / system
8999 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
9000 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
9001 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
9002 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
9003 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
9005 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
9006 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
9007 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
9008 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
9010 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
9012 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
9013 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
9014 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
9016 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
9017 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9019 refcount
= IDirectDrawSurface4_Release(surface
);
9020 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9022 /* The Windows 8 testbot keeps extra references to the primary and
9023 * backbuffer while in 8 bpp mode. */
9024 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
9025 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9027 refcount
= IDirectDrawSurface4_Release(primary
);
9028 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9029 refcount
= IDirectDrawPalette_Release(palette2
);
9030 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9031 refcount
= IDirectDrawPalette_Release(palette
);
9032 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9033 refcount
= IDirectDraw4_Release(ddraw
);
9034 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9035 DestroyWindow(window
);
9038 static void test_palette_alpha(void)
9040 IDirectDrawSurface4
*surface
;
9041 DDSURFACEDESC2 surface_desc
;
9042 IDirectDraw4
*ddraw
;
9043 IDirectDrawPalette
*palette
;
9047 PALETTEENTRY palette_entries
[256];
9052 BOOL attach_allowed
;
9057 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
9058 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
9059 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
9062 window
= create_window();
9063 ddraw
= create_ddraw();
9064 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9065 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
9067 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
9068 IDirectDraw4_Release(ddraw
);
9069 DestroyWindow(window
);
9072 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9073 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9075 memset(palette_entries
, 0, sizeof(palette_entries
));
9076 palette_entries
[1].peFlags
= 0x42;
9077 palette_entries
[2].peFlags
= 0xff;
9078 palette_entries
[3].peFlags
= 0x80;
9079 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
9080 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9082 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9083 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9084 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9085 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9086 palette_entries
[0].peFlags
);
9087 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9088 palette_entries
[1].peFlags
);
9089 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9090 palette_entries
[2].peFlags
);
9091 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9092 palette_entries
[3].peFlags
);
9094 IDirectDrawPalette_Release(palette
);
9096 memset(palette_entries
, 0, sizeof(palette_entries
));
9097 palette_entries
[1].peFlags
= 0x42;
9098 palette_entries
[1].peRed
= 0xff;
9099 palette_entries
[2].peFlags
= 0xff;
9100 palette_entries
[3].peFlags
= 0x80;
9101 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
9102 palette_entries
, &palette
, NULL
);
9103 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
9105 memset(palette_entries
, 0x66, sizeof(palette_entries
));
9106 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
9107 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
9108 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9109 palette_entries
[0].peFlags
);
9110 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
9111 palette_entries
[1].peFlags
);
9112 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
9113 palette_entries
[2].peFlags
);
9114 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
9115 palette_entries
[3].peFlags
);
9117 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
9119 memset(&surface_desc
, 0, sizeof(surface_desc
));
9120 surface_desc
.dwSize
= sizeof(surface_desc
);
9121 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
9122 surface_desc
.dwWidth
= 128;
9123 surface_desc
.dwHeight
= 128;
9124 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
9125 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9126 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
9128 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
9129 if (test_data
[i
].attach_allowed
)
9130 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
9132 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9140 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
9141 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
9142 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
9143 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
9144 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
9145 rgbquad
.rgbRed
, test_data
[i
].name
);
9146 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
9147 rgbquad
.rgbGreen
, test_data
[i
].name
);
9148 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
9149 rgbquad
.rgbBlue
, test_data
[i
].name
);
9150 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
9151 rgbquad
.rgbReserved
, test_data
[i
].name
);
9152 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
9153 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
9155 IDirectDrawSurface4_Release(surface
);
9158 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
9159 memset(&surface_desc
, 0, sizeof(surface_desc
));
9160 surface_desc
.dwSize
= sizeof(surface_desc
);
9161 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9162 surface_desc
.dwWidth
= 128;
9163 surface_desc
.dwHeight
= 128;
9164 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9165 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9166 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9167 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9168 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9169 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9170 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9171 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9172 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9173 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
9174 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
9175 IDirectDrawSurface4_Release(surface
);
9177 /* The Windows 8 testbot keeps extra references to the primary
9178 * while in 8 bpp mode. */
9179 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
9180 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
9182 refcount
= IDirectDrawPalette_Release(palette
);
9183 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9184 refcount
= IDirectDraw4_Release(ddraw
);
9185 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9186 DestroyWindow(window
);
9189 static void test_vb_writeonly(void)
9191 IDirect3DDevice3
*device
;
9193 IDirect3DVertexBuffer
*buffer
;
9196 D3DVERTEXBUFFERDESC desc
;
9198 static const struct vec4 quad
[] =
9200 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
9201 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
9202 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
9203 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
9206 window
= create_window();
9207 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9209 skip("Failed to create a 3D device, skipping test.\n");
9210 DestroyWindow(window
);
9214 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9215 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9217 memset(&desc
, 0, sizeof(desc
));
9218 desc
.dwSize
= sizeof(desc
);
9219 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
9220 desc
.dwFVF
= D3DFVF_XYZRHW
;
9221 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
9222 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
9223 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
9225 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
9226 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9227 memcpy(ptr
, quad
, sizeof(quad
));
9228 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
9229 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9231 hr
= IDirect3DDevice3_BeginScene(device
);
9232 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9233 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
9234 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9235 hr
= IDirect3DDevice3_EndScene(device
);
9236 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9238 hr
= IDirect3DVertexBuffer_Lock(buffer
, 0, &ptr
, NULL
);
9239 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9240 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9241 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
9242 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9244 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
9245 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
9246 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
9247 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
9248 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
9250 IDirect3DVertexBuffer_Release(buffer
);
9251 IDirect3D3_Release(d3d
);
9252 IDirect3DDevice3_Release(device
);
9253 DestroyWindow(window
);
9256 static void test_lost_device(void)
9258 IDirectDrawSurface4
*surface
;
9259 DDSURFACEDESC2 surface_desc
;
9260 HWND window1
, window2
;
9261 IDirectDraw4
*ddraw
;
9266 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9267 0, 0, 640, 480, 0, 0, 0, 0);
9268 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
9269 0, 0, 640, 480, 0, 0, 0, 0);
9270 ddraw
= create_ddraw();
9271 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9272 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9273 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9275 memset(&surface_desc
, 0, sizeof(surface_desc
));
9276 surface_desc
.dwSize
= sizeof(surface_desc
);
9277 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9278 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9279 U5(surface_desc
).dwBackBufferCount
= 1;
9280 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9281 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9283 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9284 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9285 hr
= IDirectDrawSurface4_IsLost(surface
);
9286 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9287 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9288 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9290 ret
= SetForegroundWindow(GetDesktopWindow());
9291 ok(ret
, "Failed to set foreground window.\n");
9292 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9293 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9294 hr
= IDirectDrawSurface4_IsLost(surface
);
9295 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9296 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9297 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9299 ret
= SetForegroundWindow(window1
);
9300 ok(ret
, "Failed to set foreground window.\n");
9301 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9302 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9303 hr
= IDirectDrawSurface4_IsLost(surface
);
9304 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9305 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9306 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9308 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
9309 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9310 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9311 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9312 hr
= IDirectDrawSurface4_IsLost(surface
);
9313 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9314 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9315 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9317 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9318 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9319 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9320 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9321 hr
= IDirectDrawSurface4_IsLost(surface
);
9322 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9323 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9324 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9326 /* Trying to restore the primary will crash, probably because flippable
9327 * surfaces can't exist in DDSCL_NORMAL. */
9328 IDirectDrawSurface4_Release(surface
);
9329 memset(&surface_desc
, 0, sizeof(surface_desc
));
9330 surface_desc
.dwSize
= sizeof(surface_desc
);
9331 surface_desc
.dwFlags
= DDSD_CAPS
;
9332 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
9333 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9334 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9336 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9337 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9338 hr
= IDirectDrawSurface4_IsLost(surface
);
9339 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9341 ret
= SetForegroundWindow(GetDesktopWindow());
9342 ok(ret
, "Failed to set foreground window.\n");
9343 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9344 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9345 hr
= IDirectDrawSurface4_IsLost(surface
);
9346 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9348 ret
= SetForegroundWindow(window1
);
9349 ok(ret
, "Failed to set foreground window.\n");
9350 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9351 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9352 hr
= IDirectDrawSurface4_IsLost(surface
);
9353 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9355 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9356 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9357 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9358 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9359 hr
= IDirectDrawSurface4_IsLost(surface
);
9360 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9362 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
9363 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9364 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9365 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9366 hr
= IDirectDrawSurface4_IsLost(surface
);
9367 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9369 IDirectDrawSurface4_Release(surface
);
9370 memset(&surface_desc
, 0, sizeof(surface_desc
));
9371 surface_desc
.dwSize
= sizeof(surface_desc
);
9372 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
9373 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
9374 U5(surface_desc
).dwBackBufferCount
= 1;
9375 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9376 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9378 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9379 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9380 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9381 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9382 hr
= IDirectDrawSurface4_IsLost(surface
);
9383 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9384 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9385 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9387 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9388 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9389 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9390 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9391 hr
= IDirectDrawSurface4_IsLost(surface
);
9392 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9393 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9394 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9396 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
9397 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9398 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9399 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9400 hr
= IDirectDrawSurface4_IsLost(surface
);
9401 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9402 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9403 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9405 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
9406 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9407 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9408 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9409 hr
= IDirectDrawSurface4_IsLost(surface
);
9410 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9411 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9412 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9414 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
9415 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9416 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9417 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9418 hr
= IDirectDrawSurface4_IsLost(surface
);
9419 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9420 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9421 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9423 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9424 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9425 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9426 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9427 hr
= IDirectDrawSurface4_IsLost(surface
);
9428 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9429 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9430 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9432 IDirectDrawSurface4_Release(surface
);
9433 refcount
= IDirectDraw4_Release(ddraw
);
9434 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9435 DestroyWindow(window2
);
9436 DestroyWindow(window1
);
9439 static void test_surface_desc_lock(void)
9441 IDirectDrawSurface4
*surface
;
9442 DDSURFACEDESC2 surface_desc
;
9443 IDirectDraw4
*ddraw
;
9448 window
= create_window();
9449 ddraw
= create_ddraw();
9450 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9451 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9452 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9454 memset(&surface_desc
, 0, sizeof(surface_desc
));
9455 surface_desc
.dwSize
= sizeof(surface_desc
);
9456 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9457 surface_desc
.dwWidth
= 16;
9458 surface_desc
.dwHeight
= 16;
9459 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9460 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9461 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9463 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9464 surface_desc
.dwSize
= sizeof(surface_desc
);
9465 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9466 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9467 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9469 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9470 surface_desc
.dwSize
= sizeof(surface_desc
);
9471 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9472 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9473 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9474 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9475 surface_desc
.dwSize
= sizeof(surface_desc
);
9476 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9477 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9478 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9479 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9480 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9482 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9483 surface_desc
.dwSize
= sizeof(surface_desc
);
9484 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9485 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9486 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9488 IDirectDrawSurface4_Release(surface
);
9489 refcount
= IDirectDraw4_Release(ddraw
);
9490 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9491 DestroyWindow(window
);
9494 static void test_texturemapblend(void)
9496 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9497 static RECT rect
= {0, 0, 64, 128};
9498 IDirectDrawSurface4
*surface
, *rt
;
9499 IDirect3DViewport3
*viewport
;
9500 DDSURFACEDESC2 surface_desc
;
9501 IDirect3DTexture2
*texture
;
9502 IDirect3DDevice3
*device
;
9503 DWORD texturemapblend
;
9504 IDirectDraw4
*ddraw
;
9516 struct vec4 position
;
9518 struct vec2 texcoord
;
9522 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 0.0f
}},
9523 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 1.0f
}},
9524 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 0.0f
}},
9525 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 1.0f
}},
9526 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 0.0f
}},
9527 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 1.0f
}},
9528 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 0.0f
}},
9529 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 1.0f
}},
9533 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 0.0f
}},
9534 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 1.0f
}},
9535 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 0.0f
}},
9536 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 1.0f
}},
9537 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 0.0f
}},
9538 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 1.0f
}},
9539 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 0.0f
}},
9540 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 1.0f
}},
9543 window
= create_window();
9544 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9546 skip("Failed to create a 3D device, skipping test.\n");
9547 DestroyWindow(window
);
9551 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9552 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9553 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9554 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9555 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9556 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9558 viewport
= create_viewport(device
, 0, 0, 640, 480);
9559 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9560 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9562 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texturemapblend
);
9563 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9564 ok(texturemapblend
== D3DTBLEND_MODULATE
, "Got unexpected texture map blend %#x.\n", texturemapblend
);
9566 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
9567 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9568 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#x.\n", value
);
9570 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture
9573 * The vertex alpha is completely ignored in this case, so case 1 and 2
9574 * combined are not a D3DTOP_MODULATE with texture alpha = 0xff in case 2
9575 * (no alpha in texture). */
9576 memset(&surface_desc
, 0, sizeof(surface_desc
));
9577 surface_desc
.dwSize
= sizeof(surface_desc
);
9578 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9579 surface_desc
.dwHeight
= 128;
9580 surface_desc
.dwWidth
= 128;
9581 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9582 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9583 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9584 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9585 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9586 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9587 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9588 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9589 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9590 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9592 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9593 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9594 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9595 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9597 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
9598 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9599 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#x.\n", value
);
9601 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9602 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9604 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
9605 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9606 ok(value
== D3DTOP_SELECTARG1
, "Got unexpected D3DTSS_ALPHAOP value %#x.\n", value
);
9608 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9609 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9611 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9612 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9614 memset(&fx
, 0, sizeof(fx
));
9615 fx
.dwSize
= sizeof(fx
);
9616 U5(fx
).dwFillColor
= 0xff0000ff;
9617 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9618 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9619 U5(fx
).dwFillColor
= 0x800000ff;
9620 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9621 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9623 /* Note that the ddraw1 version of this test runs tests 1-3 with
9624 * D3DRENDERSTATE_COLORKEYENABLE enabled, whereas this version only runs
9625 * test 4 with color keying on. Because no color key is set on the texture
9626 * this should not result in different behavior. */
9627 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9628 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9629 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9630 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9631 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9632 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9633 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9634 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9635 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9636 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9639 /* Disable the call to test that the device has this state by default. */
9640 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9641 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9644 /* Texture stage state does not change so legacy texture blending stays enabled. */
9645 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
9646 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9648 hr
= IDirect3DDevice3_BeginScene(device
);
9649 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9650 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9651 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9652 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9653 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9654 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9655 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9656 hr
= IDirect3DDevice3_EndScene(device
);
9657 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9659 color
= get_surface_color(rt
, 5, 5);
9660 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9661 color
= get_surface_color(rt
, 400, 5);
9662 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9663 color
= get_surface_color(rt
, 5, 245);
9664 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9665 color
= get_surface_color(rt
, 400, 245);
9666 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9668 /* Turn legacy texture blending off. */
9669 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG2
);
9670 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9671 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9672 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9673 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9674 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9675 hr
= IDirect3DDevice3_BeginScene(device
);
9676 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9677 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9678 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9679 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9680 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9681 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9682 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9683 hr
= IDirect3DDevice3_EndScene(device
);
9684 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9686 color
= get_surface_color(rt
, 5, 5);
9687 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9688 color
= get_surface_color(rt
, 400, 5);
9689 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9690 color
= get_surface_color(rt
, 5, 245);
9691 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9692 color
= get_surface_color(rt
, 400, 245);
9693 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9695 /* This doesn't turn legacy texture blending on again, as setting the same
9696 * _TEXTUREMAPBLEND value. */
9697 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9698 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9699 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9700 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9701 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9702 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9703 hr
= IDirect3DDevice3_BeginScene(device
);
9704 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9705 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9706 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9707 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9708 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9709 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9710 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9711 hr
= IDirect3DDevice3_EndScene(device
);
9712 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9714 color
= get_surface_color(rt
, 5, 5);
9715 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9716 color
= get_surface_color(rt
, 400, 5);
9717 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9718 color
= get_surface_color(rt
, 5, 245);
9719 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9720 color
= get_surface_color(rt
, 400, 245);
9721 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9723 /* Turn legacy texture blending on again. */
9724 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_ADD
);
9725 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9726 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9727 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9728 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9729 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9730 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9731 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9732 hr
= IDirect3DDevice3_BeginScene(device
);
9733 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9734 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9735 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9736 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9737 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9738 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9739 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9740 hr
= IDirect3DDevice3_EndScene(device
);
9741 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9743 color
= get_surface_color(rt
, 5, 5);
9744 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9745 color
= get_surface_color(rt
, 400, 5);
9746 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9747 color
= get_surface_color(rt
, 5, 245);
9748 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9749 color
= get_surface_color(rt
, 400, 245);
9750 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9752 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9753 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9754 IDirect3DTexture2_Release(texture
);
9755 refcount
= IDirectDrawSurface4_Release(surface
);
9756 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9758 /* Test alpha with texture that has no alpha channel - alpha should be
9759 * taken from diffuse vertex color. */
9760 memset(&surface_desc
, 0, sizeof(surface_desc
));
9761 surface_desc
.dwSize
= sizeof(surface_desc
);
9762 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9763 surface_desc
.dwHeight
= 128;
9764 surface_desc
.dwWidth
= 128;
9765 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9766 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9767 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9768 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9769 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9770 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9771 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9773 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9774 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9776 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9777 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9778 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9779 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9781 hr
= IDirect3DDevice3_GetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, &value
);
9782 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9783 ok(value
== D3DTOP_SELECTARG2
, "Got unexpected D3DTSS_ALPHAOP value %#x.\n", value
);
9785 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9786 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9788 U5(fx
).dwFillColor
= 0xff0000ff;
9789 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9790 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9791 U5(fx
).dwFillColor
= 0x800000ff;
9792 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9793 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9795 hr
= IDirect3DDevice3_BeginScene(device
);
9796 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9797 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9798 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9799 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9800 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9801 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9802 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9803 hr
= IDirect3DDevice3_EndScene(device
);
9804 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
9806 color
= get_surface_color(rt
, 5, 5);
9807 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9808 color
= get_surface_color(rt
, 400, 5);
9809 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9810 color
= get_surface_color(rt
, 5, 245);
9811 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9812 color
= get_surface_color(rt
, 400, 245);
9813 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9815 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9816 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9817 IDirect3DTexture2_Release(texture
);
9818 refcount
= IDirectDrawSurface4_Release(surface
);
9819 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9821 /* Test RGB - should multiply color components from diffuse vertex color
9823 memset(&surface_desc
, 0, sizeof(surface_desc
));
9824 surface_desc
.dwSize
= sizeof(surface_desc
);
9825 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9826 surface_desc
.dwHeight
= 128;
9827 surface_desc
.dwWidth
= 128;
9828 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9829 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9830 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9831 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9832 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9833 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9834 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9835 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9836 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9837 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9839 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9840 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9841 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9842 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9844 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9845 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9847 U5(fx
).dwFillColor
= 0x00ffffff;
9848 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9849 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9850 U5(fx
).dwFillColor
= 0x00ffff80;
9851 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9852 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9854 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9855 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9857 hr
= IDirect3DDevice3_BeginScene(device
);
9858 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9859 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9860 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[0], 4, 0);
9861 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9862 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9863 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[4], 4, 0);
9864 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9865 hr
= IDirect3DDevice3_EndScene(device
);
9866 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9868 color
= get_surface_color(rt
, 5, 5);
9869 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9870 color
= get_surface_color(rt
, 400, 5);
9871 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9872 color
= get_surface_color(rt
, 5, 245);
9873 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9874 color
= get_surface_color(rt
, 400, 245);
9875 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9877 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9878 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9879 IDirect3DTexture2_Release(texture
);
9880 refcount
= IDirectDrawSurface4_Release(surface
);
9881 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9883 /* Test alpha again, now with color keyed texture (colorkey emulation in
9884 * wine can interfere). */
9885 memset(&surface_desc
, 0, sizeof(surface_desc
));
9886 surface_desc
.dwSize
= sizeof(surface_desc
);
9887 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9888 surface_desc
.dwHeight
= 128;
9889 surface_desc
.dwWidth
= 128;
9890 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9891 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9892 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9893 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
9894 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
9895 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9896 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
9898 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9899 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9901 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9902 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9903 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9904 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9906 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9907 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9909 U5(fx
).dwFillColor
= 0xf800;
9910 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9911 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9912 U5(fx
).dwFillColor
= 0x001f;
9913 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9914 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9916 ckey
.dwColorSpaceLowValue
= 0x001f;
9917 ckey
.dwColorSpaceHighValue
= 0x001f;
9918 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9919 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9921 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9922 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9923 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9924 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9926 hr
= IDirect3DDevice3_BeginScene(device
);
9927 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9928 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9929 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9930 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9931 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9932 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9933 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9934 hr
= IDirect3DDevice3_EndScene(device
);
9935 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9937 color
= get_surface_color(rt
, 5, 5);
9938 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9939 color
= get_surface_color(rt
, 400, 5);
9940 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9941 color
= get_surface_color(rt
, 5, 245);
9942 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9943 color
= get_surface_color(rt
, 400, 245);
9944 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9946 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9947 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9948 IDirect3DTexture2_Release(texture
);
9949 refcount
= IDirectDrawSurface4_Release(surface
);
9950 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9952 destroy_viewport(device
, viewport
);
9953 IDirectDrawSurface4_Release(rt
);
9954 IDirect3DDevice3_Release(device
);
9955 IDirect3D3_Release(d3d
);
9956 refcount
= IDirectDraw4_Release(ddraw
);
9957 ok(!refcount
, "Ddraw object not properly released, refcount %u.\n", refcount
);
9958 DestroyWindow(window
);
9961 static void test_signed_formats(void)
9964 IDirect3DDevice3
*device
;
9966 IDirectDraw4
*ddraw
;
9967 IDirectDrawSurface4
*surface
, *rt
;
9968 IDirect3DTexture2
*texture
;
9969 IDirect3DViewport3
*viewport
;
9970 DDSURFACEDESC2 surface_desc
;
9973 D3DCOLOR color
, expected_color
;
9977 struct vec3 position
;
9978 struct vec2 texcoord
;
9982 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
9983 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
9984 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
9985 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
9987 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
9988 * of these values. */
9989 static const USHORT content_v8u8
[4][4] =
9991 {0x0000, 0x7f7f, 0x8880, 0x0000},
9992 {0x0080, 0x8000, 0x7f00, 0x007f},
9993 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
9994 {0x4444, 0xc0c0, 0xa066, 0x22e0},
9996 static const DWORD content_x8l8v8u8
[4][4] =
9998 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
9999 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
10000 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
10001 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
10003 static const USHORT content_l6v5u5
[4][4] =
10005 {0x0000, 0xfdef, 0x0230, 0xfc00},
10006 {0x0010, 0x0200, 0x01e0, 0x000f},
10007 {0x4067, 0x53b9, 0x0421, 0xffff},
10008 {0x8108, 0x0318, 0xc28c, 0x909c},
10010 static const struct
10013 const void *content
;
10016 unsigned int slop
, slop_broken
;
10017 DDPIXELFORMAT format
;
10022 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
10024 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
10025 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
10029 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
10031 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
10032 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
10036 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
10038 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
10039 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
10043 /* No V16U16 or Q8W8V8U8 support in ddraw. */
10045 static const D3DCOLOR expected_colors
[4][4] =
10047 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
10048 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
10049 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
10050 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
10052 unsigned int i
, width
, x
, y
;
10053 D3DDEVICEDESC device_desc
, hel_desc
;
10055 window
= create_window();
10056 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10058 skip("Failed to create a 3D device, skipping test.\n");
10059 DestroyWindow(window
);
10063 memset(&device_desc
, 0, sizeof(device_desc
));
10064 device_desc
.dwSize
= sizeof(device_desc
);
10065 memset(&hel_desc
, 0, sizeof(hel_desc
));
10066 hel_desc
.dwSize
= sizeof(hel_desc
);
10067 hr
= IDirect3DDevice3_GetCaps(device
, &device_desc
, &hel_desc
);
10068 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
10069 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
10071 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
10075 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10076 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
10077 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10078 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
10079 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10080 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10082 memset(&surface_desc
, 0, sizeof(surface_desc
));
10083 surface_desc
.dwSize
= sizeof(surface_desc
);
10084 hr
= IDirectDrawSurface4_GetSurfaceDesc(rt
, &surface_desc
);
10085 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
10086 viewport
= create_viewport(device
, 0, 0, surface_desc
.dwWidth
, surface_desc
.dwHeight
);
10087 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10088 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10089 U1(clear_rect
).x1
= 0;
10090 U2(clear_rect
).y1
= 0;
10091 U3(clear_rect
).x2
= surface_desc
.dwWidth
;
10092 U4(clear_rect
).y2
= surface_desc
.dwHeight
;
10094 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10095 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10097 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
10098 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
10099 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10100 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
10101 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10102 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10103 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10104 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
10105 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
10107 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
10109 for (width
= 1; width
< 5; width
+= 3)
10111 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
10112 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10114 memset(&surface_desc
, 0, sizeof(surface_desc
));
10115 surface_desc
.dwSize
= sizeof(surface_desc
);
10116 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
10117 surface_desc
.dwWidth
= width
;
10118 surface_desc
.dwHeight
= 4;
10119 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
10120 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10121 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10124 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
10127 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
10129 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
10130 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x, format %s.\n",
10131 hr
, formats
[i
].name
);
10132 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
10133 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
10134 IDirect3DTexture2_Release(texture
);
10136 memset(&surface_desc
, 0, sizeof(surface_desc
));
10137 surface_desc
.dwSize
= sizeof(surface_desc
);
10138 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
10139 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
10140 for (y
= 0; y
< 4; y
++)
10142 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
10143 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
10144 width
* formats
[i
].pixel_size
);
10146 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10147 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
10149 hr
= IDirect3DDevice3_BeginScene(device
);
10150 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10151 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
10152 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
10153 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10154 hr
= IDirect3DDevice3_EndScene(device
);
10155 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10157 for (y
= 0; y
< 4; y
++)
10159 for (x
= 0; x
< width
; x
++)
10161 expected_color
= expected_colors
[y
][x
];
10162 if (!formats
[i
].blue
)
10163 expected_color
|= 0x000000ff;
10165 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
10166 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
10167 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
10168 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
10169 expected_color
, color
, formats
[i
].name
, x
, y
);
10173 IDirectDrawSurface4_Release(surface
);
10177 destroy_viewport(device
, viewport
);
10178 IDirectDrawSurface4_Release(rt
);
10179 IDirectDraw4_Release(ddraw
);
10180 IDirect3D3_Release(d3d
);
10183 refcount
= IDirect3DDevice3_Release(device
);
10184 ok(!refcount
, "Device has %u references left.\n", refcount
);
10185 DestroyWindow(window
);
10188 static void test_color_fill(void)
10191 IDirect3DDevice3
*device
;
10193 IDirectDraw4
*ddraw
;
10194 IDirectDrawSurface4
*surface
, *surface2
;
10195 DDSURFACEDESC2 surface_desc
;
10196 DDPIXELFORMAT z_fmt
;
10201 RECT rect
= {5, 5, 7, 7};
10203 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
10205 static const struct
10208 HRESULT colorfill_hr
, depthfill_hr
;
10213 DDPIXELFORMAT format
;
10218 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
10219 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
10221 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10222 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
10226 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
10227 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
10229 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10230 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
10234 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
10235 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
10237 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10238 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
10242 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
10243 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
10245 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10246 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
10250 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
10251 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
10253 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10254 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
10258 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
10259 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
10260 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
10263 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
10264 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
10265 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
10268 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
10269 * different afterwards. DX9+ GPUs set one of the two luminance values
10270 * in each block, but AMD and Nvidia GPUs disagree on which luminance
10271 * value they set. r200 (dx8) just sets the entire block to the clear
10273 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
10274 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
10276 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
10277 {0}, {0}, {0}, {0}, {0}
10281 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
10282 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
10284 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
10285 {0}, {0}, {0}, {0}, {0}
10289 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
10290 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
10292 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
10293 {0}, {0}, {0}, {0}, {0}
10297 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
10298 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
10300 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
10301 {0}, {0}, {0}, {0}, {0}
10305 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
10306 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
10308 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
10309 {0}, {0}, {0}, {0}, {0}
10313 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
10314 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
10316 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
10317 {0}, {0}, {0}, {0}, {0}
10321 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
10322 * surface works, presumably because it is handled by the runtime instead of
10324 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
10325 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
10327 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
10328 {8}, {0}, {0}, {0}, {0}
10332 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
10333 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
10335 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
10336 {8}, {0}, {0}, {0}, {0}
10340 static const struct
10348 {SRCCOPY
, "SRCCOPY", DD_OK
},
10349 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
10350 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
10351 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
10352 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
10353 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
10354 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
10355 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
10356 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
10357 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
10358 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
10359 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
10360 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
10361 {BLACKNESS
, "BLACKNESS", DD_OK
},
10362 {WHITENESS
, "WHITENESS", DD_OK
},
10363 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
10366 window
= create_window();
10367 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10369 skip("Failed to create a 3D device, skipping test.\n");
10370 DestroyWindow(window
);
10374 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10375 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
10376 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10377 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
10379 memset(&z_fmt
, 0, sizeof(z_fmt
));
10380 IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
10382 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
10384 IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
10385 if (!(supported_fmts
& SUPPORT_DXT1
))
10386 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
10388 IDirect3D3_Release(d3d
);
10390 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
10391 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
10392 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
10393 num_fourcc_codes
* sizeof(*fourcc_codes
));
10396 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
10397 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
10398 for (i
= 0; i
< num_fourcc_codes
; i
++)
10400 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
10401 supported_fmts
|= SUPPORT_YUY2
;
10402 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
10403 supported_fmts
|= SUPPORT_UYVY
;
10405 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
10407 memset(&hal_caps
, 0, sizeof(hal_caps
));
10408 hal_caps
.dwSize
= sizeof(hal_caps
);
10409 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
10410 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
10412 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
10413 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
10415 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
10417 DWORD expected_broken
= tests
[i
].result
;
10419 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
10420 memset(&fx
, 0, sizeof(fx
));
10421 fx
.dwSize
= sizeof(fx
);
10422 U5(fx
).dwFillColor
= 0xdeadbeef;
10424 memset(&surface_desc
, 0, sizeof(surface_desc
));
10425 surface_desc
.dwSize
= sizeof(surface_desc
);
10426 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10427 surface_desc
.dwWidth
= 64;
10428 surface_desc
.dwHeight
= 64;
10429 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
10430 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
10431 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
10433 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
10435 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
10437 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
10439 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
10442 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
10447 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
10448 /* Some drivers seem to convert depth values incorrectly or not at
10449 * all. Affects at least AMD PALM, 8.17.10.1247. */
10450 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
10455 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
10456 f
= ceilf(log2f(expected
+ 1.0f
));
10457 g
= (f
+ 1.0f
) / 2.0f
;
10459 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
10460 expected_broken
*= 0x01010101;
10464 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10465 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10467 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10468 todo_wine_if (tests
[i
].format
.dwFourCC
)
10469 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
10470 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
10472 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10473 todo_wine_if (tests
[i
].format
.dwFourCC
)
10474 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
10475 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
10477 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10479 memset(&surface_desc
, 0, sizeof(surface_desc
));
10480 surface_desc
.dwSize
= sizeof(surface_desc
);
10481 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10482 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10483 color
= surface_desc
.lpSurface
;
10484 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10485 *color
, tests
[i
].result
, tests
[i
].name
);
10486 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10487 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10490 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10491 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
10492 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10493 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10494 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
10495 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
10497 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10499 memset(&surface_desc
, 0, sizeof(surface_desc
));
10500 surface_desc
.dwSize
= sizeof(surface_desc
);
10501 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10502 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10503 color
= surface_desc
.lpSurface
;
10504 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
10505 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
10506 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
10507 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
10508 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10509 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10512 U5(fx
).dwFillColor
= 0xdeadbeef;
10513 fx
.dwROP
= BLACKNESS
;
10514 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10515 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
10516 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10517 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
10518 U5(fx
).dwFillColor
, tests
[i
].name
);
10520 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10522 memset(&surface_desc
, 0, sizeof(surface_desc
));
10523 surface_desc
.dwSize
= sizeof(surface_desc
);
10524 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10525 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10526 color
= surface_desc
.lpSurface
;
10527 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
10528 *color
, tests
[i
].name
);
10529 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10530 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10533 fx
.dwROP
= WHITENESS
;
10534 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10535 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
10536 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
10537 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
10538 U5(fx
).dwFillColor
, tests
[i
].name
);
10540 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10542 memset(&surface_desc
, 0, sizeof(surface_desc
));
10543 surface_desc
.dwSize
= sizeof(surface_desc
);
10544 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10545 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10546 color
= surface_desc
.lpSurface
;
10547 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
10548 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
10549 *color
, tests
[i
].name
);
10550 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10551 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10554 IDirectDrawSurface4_Release(surface
);
10557 memset(&fx
, 0, sizeof(fx
));
10558 fx
.dwSize
= sizeof(fx
);
10559 U5(fx
).dwFillColor
= 0xdeadbeef;
10560 fx
.dwROP
= WHITENESS
;
10562 memset(&surface_desc
, 0, sizeof(surface_desc
));
10563 surface_desc
.dwSize
= sizeof(surface_desc
);
10564 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10565 surface_desc
.dwWidth
= 64;
10566 surface_desc
.dwHeight
= 64;
10567 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10568 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10569 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10570 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10571 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10572 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10573 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10574 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10575 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10576 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10577 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10580 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
10581 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10582 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
10583 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10585 /* Unused source rectangle. */
10586 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10587 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10588 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10589 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10591 /* Unused source surface. */
10592 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10593 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10594 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10595 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10596 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10597 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10598 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10599 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10601 /* Inverted destination or source rectangle. */
10602 SetRect(&rect
, 5, 7, 7, 5);
10603 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10604 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10605 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10606 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10607 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10608 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10609 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10610 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10611 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10612 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10614 /* Negative rectangle. */
10615 SetRect(&rect
, -1, -1, 5, 5);
10616 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10617 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10618 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10619 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10620 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10621 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10622 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10623 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10624 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10625 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10627 /* Out of bounds rectangle. */
10628 SetRect(&rect
, 0, 0, 65, 65);
10629 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10630 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10631 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10632 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10634 /* Combine multiple flags. */
10635 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10636 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10637 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10638 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10639 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10640 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10642 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
10644 fx
.dwROP
= rops
[i
].rop
;
10645 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10646 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
10649 IDirectDrawSurface4_Release(surface2
);
10650 IDirectDrawSurface4_Release(surface
);
10655 memset(&surface_desc
, 0, sizeof(surface_desc
));
10656 surface_desc
.dwSize
= sizeof(surface_desc
);
10657 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10658 surface_desc
.dwWidth
= 64;
10659 surface_desc
.dwHeight
= 64;
10660 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
10661 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10662 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10663 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10664 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10665 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10668 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
10669 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10671 /* Unused source rectangle. */
10672 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10673 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10675 /* Unused source surface. */
10676 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10677 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10678 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10679 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10681 /* Inverted destination or source rectangle. */
10682 SetRect(&rect
, 5, 7, 7, 5);
10683 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10684 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10685 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10686 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10687 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10688 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10689 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10690 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10692 /* Negative rectangle. */
10693 SetRect(&rect
, -1, -1, 5, 5);
10694 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10695 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10696 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10697 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10698 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10699 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10700 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10701 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10703 /* Out of bounds rectangle. */
10704 SetRect(&rect
, 0, 0, 65, 65);
10705 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10706 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10708 /* Combine multiple flags. */
10709 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10710 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10712 IDirectDrawSurface4_Release(surface2
);
10713 IDirectDrawSurface4_Release(surface
);
10716 IDirectDraw4_Release(ddraw
);
10717 refcount
= IDirect3DDevice3_Release(device
);
10718 ok(!refcount
, "Device has %u references left.\n", refcount
);
10719 DestroyWindow(window
);
10722 static void test_texcoordindex(void)
10727 struct vec2 texcoord1
;
10728 struct vec2 texcoord2
;
10729 struct vec2 texcoord3
;
10733 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10734 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
10735 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10736 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
10738 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
10739 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10740 IDirect3DDevice3
*device
;
10742 IDirectDraw4
*ddraw
;
10743 IDirectDrawSurface4
*rt
;
10744 IDirect3DViewport3
*viewport
;
10747 IDirectDrawSurface4
*surface1
, *surface2
;
10748 IDirect3DTexture2
*texture1
, *texture2
;
10749 DDSURFACEDESC2 surface_desc
;
10754 window
= create_window();
10755 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10757 skip("Failed to create a 3D device, skipping test.\n");
10758 DestroyWindow(window
);
10762 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10763 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10764 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10765 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10766 IDirect3D3_Release(d3d
);
10768 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10769 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10771 memset(&surface_desc
, 0, sizeof(surface_desc
));
10772 surface_desc
.dwSize
= sizeof(surface_desc
);
10773 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10774 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10775 surface_desc
.dwWidth
= 2;
10776 surface_desc
.dwHeight
= 2;
10777 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10778 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10779 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10780 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10781 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10782 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10783 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10784 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
10785 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10786 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10787 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10789 memset(&surface_desc
, 0, sizeof(surface_desc
));
10790 surface_desc
.dwSize
= sizeof(surface_desc
);
10791 hr
= IDirectDrawSurface4_Lock(surface1
, 0, &surface_desc
, 0, NULL
);
10792 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10793 ptr
= surface_desc
.lpSurface
;
10794 ptr
[0] = 0xff000000;
10795 ptr
[1] = 0xff00ff00;
10796 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10797 ptr
[0] = 0xff0000ff;
10798 ptr
[1] = 0xff00ffff;
10799 hr
= IDirectDrawSurface4_Unlock(surface1
, NULL
);
10800 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10802 memset(&surface_desc
, 0, sizeof(surface_desc
));
10803 surface_desc
.dwSize
= sizeof(surface_desc
);
10804 hr
= IDirectDrawSurface4_Lock(surface2
, 0, &surface_desc
, 0, NULL
);
10805 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10806 ptr
= surface_desc
.lpSurface
;
10807 ptr
[0] = 0xff000000;
10808 ptr
[1] = 0xff0000ff;
10809 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10810 ptr
[0] = 0xffff0000;
10811 ptr
[1] = 0xffff00ff;
10812 hr
= IDirectDrawSurface4_Unlock(surface2
, 0);
10813 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10815 viewport
= create_viewport(device
, 0, 0, 640, 480);
10816 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10817 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
10819 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirect3DTexture2
, (void **)&texture1
);
10820 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10821 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirect3DTexture2
, (void **)&texture2
);
10822 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10823 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture1
);
10824 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10825 hr
= IDirect3DDevice3_SetTexture(device
, 1, texture2
);
10826 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10827 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10828 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10829 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10830 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10831 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
10832 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10833 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10834 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10835 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
10836 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10837 hr
= IDirect3DDevice3_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
10838 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10840 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
10841 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10842 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
10843 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10845 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10846 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10848 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10849 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10851 hr
= IDirect3DDevice3_BeginScene(device
);
10852 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10853 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10854 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10855 hr
= IDirect3DDevice3_EndScene(device
);
10856 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10858 color
= get_surface_color(rt
, 160, 120);
10859 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10860 color
= get_surface_color(rt
, 480, 120);
10861 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10862 color
= get_surface_color(rt
, 160, 360);
10863 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
10864 color
= get_surface_color(rt
, 480, 360);
10865 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
10867 /* D3DTSS_TEXTURETRANSFORMFLAGS was introduced in D3D7, can't test it here. */
10869 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
10870 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10872 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10873 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10875 hr
= IDirect3DDevice3_BeginScene(device
);
10876 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10877 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10878 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10879 hr
= IDirect3DDevice3_EndScene(device
);
10880 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10882 color
= get_surface_color(rt
, 160, 120);
10883 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10884 color
= get_surface_color(rt
, 480, 120);
10885 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10886 color
= get_surface_color(rt
, 160, 360);
10887 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
10888 color
= get_surface_color(rt
, 480, 360);
10889 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
10891 IDirect3DTexture2_Release(texture2
);
10892 IDirect3DTexture2_Release(texture1
);
10893 IDirectDrawSurface4_Release(surface2
);
10894 IDirectDrawSurface4_Release(surface1
);
10896 destroy_viewport(device
, viewport
);
10898 IDirectDrawSurface4_Release(rt
);
10899 IDirectDraw_Release(ddraw
);
10900 refcount
= IDirect3DDevice3_Release(device
);
10901 ok(!refcount
, "Device has %u references left.\n", refcount
);
10902 DestroyWindow(window
);
10905 static void test_colorkey_precision(void)
10910 struct vec2 texcoord
;
10914 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10915 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
10916 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10917 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
10919 IDirect3DDevice3
*device
;
10921 IDirectDraw4
*ddraw
;
10922 IDirectDrawSurface4
*rt
;
10923 IDirect3DViewport3
*viewport
;
10926 IDirectDrawSurface4
*src
, *dst
, *texture
;
10927 IDirect3DTexture2
*d3d_texture
;
10928 DDSURFACEDESC2 surface_desc
, lock_desc
;
10934 DWORD data
[4] = {0}, color_mask
;
10935 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10936 BOOL is_nvidia
, is_warp
;
10937 static const struct
10939 unsigned int max
, shift
, bpp
, clear
;
10947 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10949 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10950 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10955 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10957 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10958 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10963 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10965 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10966 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10971 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10973 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10974 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10979 window
= create_window();
10980 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10982 skip("Failed to create a 3D device, skipping test.\n");
10983 DestroyWindow(window
);
10987 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10988 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10989 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10990 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10991 IDirect3D3_Release(d3d
);
10992 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10993 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10995 is_nvidia
= ddraw_is_nvidia(ddraw
);
10996 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10997 * (color key doesn't match although the values are equal), and a false
10998 * positive when the color key is 0 and the texture contains the value 1.
10999 * I don't want to mark this broken unconditionally since this would
11000 * essentially disable the test on Windows. Also on random occasions
11001 * 254 == 255 and 255 != 255.*/
11002 is_warp
= ddraw_is_warp(ddraw
);
11004 viewport
= create_viewport(device
, 0, 0, 640, 480);
11005 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
11006 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
11008 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
11009 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
11010 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
11011 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
11012 /* Multiply the texture read result with 0, that way the result color if the key doesn't
11013 * match is constant. In theory color keying works without reading the texture result
11014 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
11016 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
11017 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11018 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
11019 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11020 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
11021 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11022 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
11023 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
11025 memset(&fx
, 0, sizeof(fx
));
11026 fx
.dwSize
= sizeof(fx
);
11027 memset(&lock_desc
, 0, sizeof(lock_desc
));
11028 lock_desc
.dwSize
= sizeof(lock_desc
);
11030 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
11032 if (is_nvidia
&& tests
[t
].skip_nv
)
11034 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
11038 memset(&surface_desc
, 0, sizeof(surface_desc
));
11039 surface_desc
.dwSize
= sizeof(surface_desc
);
11040 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11041 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11042 surface_desc
.dwWidth
= 4;
11043 surface_desc
.dwHeight
= 1;
11044 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
11045 /* Windows XP (at least with the r200 driver, other drivers untested) produces
11046 * garbage when doing color keyed texture->texture blits. */
11047 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
11048 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11049 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
11050 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11052 U5(fx
).dwFillColor
= tests
[t
].clear
;
11053 /* On the w8 testbot (WARP driver) the blit result has different values in the
11055 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
11056 | U3(tests
[t
].fmt
).dwGBitMask
11057 | U4(tests
[t
].fmt
).dwBBitMask
;
11059 for (c
= 0; c
<= tests
[t
].max
; ++c
)
11061 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
11062 * texture after it has been set once... */
11063 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
11064 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11065 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
11066 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
11067 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
11068 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11069 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
11070 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
11071 hr
= IDirect3DDevice3_SetTexture(device
, 0, d3d_texture
);
11072 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
11074 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11075 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
11077 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
11078 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11079 switch (tests
[t
].bpp
)
11082 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
11083 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
11084 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
11085 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
11089 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
11090 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
11091 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
11092 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
11095 hr
= IDirectDrawSurface4_Unlock(src
, 0);
11096 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11097 hr
= IDirectDrawSurface4_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
11098 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11100 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
11101 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
11102 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
11103 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
11105 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
11106 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11108 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
11109 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
11110 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11111 switch (tests
[t
].bpp
)
11114 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
11115 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
11116 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
11117 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
11121 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
11122 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
11123 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
11124 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
11127 hr
= IDirectDrawSurface4_Unlock(dst
, 0);
11128 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11132 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
11133 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
11135 if (data
[3] == tests
[t
].clear
)
11137 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
11138 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
11139 * even when a different surface is used. The blit itself doesn't draw anything,
11140 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
11141 * never be masked out by the key.
11143 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
11144 * test is disabled entirely.
11146 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
11147 * terrible on WARP. */
11148 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
11149 IDirect3DTexture2_Release(d3d_texture
);
11150 IDirectDrawSurface4_Release(texture
);
11151 IDirectDrawSurface4_Release(src
);
11152 IDirectDrawSurface4_Release(dst
);
11157 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
11158 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
11160 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
11161 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
11163 if (c
== tests
[t
].max
)
11164 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
11165 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
11167 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
11168 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
11170 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
11171 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
11173 hr
= IDirect3DDevice3_BeginScene(device
);
11174 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11175 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
11176 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11177 hr
= IDirect3DDevice3_EndScene(device
);
11178 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11180 color
= get_surface_color(rt
, 80, 240);
11182 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
11183 "Got unexpected color 0x%08x, format %s, c=%u.\n",
11184 color
, tests
[t
].name
, c
);
11186 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
11187 "Got unexpected color 0x%08x, format %s, c=%u.\n",
11188 color
, tests
[t
].name
, c
);
11190 color
= get_surface_color(rt
, 240, 240);
11191 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
11192 "Got unexpected color 0x%08x, format %s, c=%u.\n",
11193 color
, tests
[t
].name
, c
);
11195 color
= get_surface_color(rt
, 400, 240);
11196 if (c
== tests
[t
].max
)
11197 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
11198 "Got unexpected color 0x%08x, format %s, c=%u.\n",
11199 color
, tests
[t
].name
, c
);
11201 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
11202 "Got unexpected color 0x%08x, format %s, c=%u.\n",
11203 color
, tests
[t
].name
, c
);
11205 IDirect3DTexture2_Release(d3d_texture
);
11206 IDirectDrawSurface4_Release(texture
);
11208 IDirectDrawSurface4_Release(src
);
11209 IDirectDrawSurface4_Release(dst
);
11213 destroy_viewport(device
, viewport
);
11214 IDirectDrawSurface4_Release(rt
);
11215 IDirectDraw4_Release(ddraw
);
11216 refcount
= IDirect3DDevice3_Release(device
);
11217 ok(!refcount
, "Device has %u references left.\n", refcount
);
11218 DestroyWindow(window
);
11221 static void test_range_colorkey(void)
11223 IDirectDraw4
*ddraw
;
11226 IDirectDrawSurface4
*surface
;
11227 DDSURFACEDESC2 surface_desc
;
11231 window
= create_window();
11232 ddraw
= create_ddraw();
11233 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11234 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11235 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11237 memset(&surface_desc
, 0, sizeof(surface_desc
));
11238 surface_desc
.dwSize
= sizeof(surface_desc
);
11239 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
11240 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11241 surface_desc
.dwWidth
= 1;
11242 surface_desc
.dwHeight
= 1;
11243 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11244 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11245 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
11246 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
11247 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
11248 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
11250 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
11251 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
11252 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
11253 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11254 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11256 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
11257 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
11258 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11259 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11261 /* Same for DDSCAPS_OFFSCREENPLAIN. */
11262 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11263 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
11264 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
11265 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11266 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11268 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
11269 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
11270 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11271 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11273 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
11274 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
11275 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11276 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11278 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
11279 ckey
.dwColorSpaceLowValue
= 0x00000000;
11280 ckey
.dwColorSpaceHighValue
= 0x00000001;
11281 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11282 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
11284 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11285 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
11286 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
11287 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
11289 ckey
.dwColorSpaceLowValue
= 0x00000001;
11290 ckey
.dwColorSpaceHighValue
= 0x00000000;
11291 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11292 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
11294 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11295 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
11296 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
11297 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
11299 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
11300 ckey
.dwColorSpaceLowValue
= 0x00000000;
11301 ckey
.dwColorSpaceHighValue
= 0x00000000;
11302 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
11303 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
11305 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
11306 ckey
.dwColorSpaceLowValue
= 0x00000001;
11307 ckey
.dwColorSpaceHighValue
= 0x00000000;
11308 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
11309 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11310 ckey
.dwColorSpaceLowValue
= 0x00000000;
11311 ckey
.dwColorSpaceHighValue
= 0x00000001;
11312 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
11313 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11314 /* Range destination keys don't work either. */
11315 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
11316 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11318 /* Just to show it's not because of A, R, and G having equal values. */
11319 ckey
.dwColorSpaceLowValue
= 0x00000000;
11320 ckey
.dwColorSpaceHighValue
= 0x01010101;
11321 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
11322 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
11324 /* None of these operations modified the key. */
11325 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
11326 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
11327 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
11328 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
11330 IDirectDrawSurface4_Release(surface
);
11331 refcount
= IDirectDraw4_Release(ddraw
);
11332 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
11333 DestroyWindow(window
);
11336 static void test_shademode(void)
11338 IDirect3DVertexBuffer
*vb_strip
, *vb_list
, *buffer
;
11339 IDirect3DViewport3
*viewport
;
11340 IDirect3DDevice3
*device
;
11341 D3DVERTEXBUFFERDESC desc
;
11342 IDirectDrawSurface4
*rt
;
11343 DWORD color0
, color1
;
11350 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11351 static const struct
11353 struct vec3 position
;
11358 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
11359 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
11360 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
11361 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
11365 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
11366 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
11367 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
11369 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
11370 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
11371 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
11373 static const struct
11377 DWORD color0
, color1
;
11381 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
11382 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
11383 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
11384 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
11385 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
11386 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
11389 window
= create_window();
11390 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11392 skip("Failed to create a 3D device, skipping test.\n");
11393 DestroyWindow(window
);
11397 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11398 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
11399 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11400 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11402 viewport
= create_viewport(device
, 0, 0, 640, 480);
11403 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
11404 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11406 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
11407 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
11409 memset(&desc
, 0, sizeof(desc
));
11410 desc
.dwSize
= sizeof(desc
);
11411 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
11412 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
11413 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
11414 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0, NULL
);
11415 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
11416 hr
= IDirect3DVertexBuffer_Lock(vb_strip
, 0, &data
, NULL
);
11417 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
11418 memcpy(data
, quad_strip
, sizeof(quad_strip
));
11419 hr
= IDirect3DVertexBuffer_Unlock(vb_strip
);
11420 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
11422 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
11423 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0, NULL
);
11424 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
11425 hr
= IDirect3DVertexBuffer_Lock(vb_list
, 0, &data
, NULL
);
11426 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
11427 memcpy(data
, quad_list
, sizeof(quad_list
));
11428 hr
= IDirect3DVertexBuffer_Unlock(vb_list
);
11429 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
11431 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
11432 * the color fixups we have to do for FLAT shading will be dependent on that. */
11434 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
11436 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
11437 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
11439 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
11440 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
11442 hr
= IDirect3DDevice3_BeginScene(device
);
11443 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11444 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
11445 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
11446 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
11447 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11448 hr
= IDirect3DDevice3_EndScene(device
);
11449 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11451 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
11452 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
11454 /* For D3DSHADE_FLAT it should take the color of the first vertex of
11455 * each triangle. This requires EXT_provoking_vertex or similar
11456 * functionality being available. */
11457 /* PHONG should be the same as GOURAUD, since no hardware implements
11459 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
11460 i
, color0
, tests
[i
].color0
);
11461 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
11462 i
, color1
, tests
[i
].color1
);
11465 IDirect3DVertexBuffer_Release(vb_strip
);
11466 IDirect3DVertexBuffer_Release(vb_list
);
11467 destroy_viewport(device
, viewport
);
11468 IDirectDrawSurface4_Release(rt
);
11469 IDirect3D3_Release(d3d
);
11470 refcount
= IDirect3DDevice3_Release(device
);
11471 ok(!refcount
, "Device has %u references left.\n", refcount
);
11472 DestroyWindow(window
);
11475 static void test_lockrect_invalid(void)
11478 IDirectDraw4
*ddraw
;
11479 IDirectDrawSurface4
*surface
;
11482 DDSURFACEDESC2 surface_desc
;
11484 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
11485 static RECT valid
[] =
11490 {120, 60, 128, 68},
11491 {60, 120, 68, 128},
11493 static RECT invalid
[] =
11495 {68, 60, 60, 68}, /* left > right */
11496 {60, 68, 68, 60}, /* top > bottom */
11497 {-8, 60, 0, 68}, /* left < surface */
11498 {60, -8, 68, 0}, /* top < surface */
11499 {-16, 60, -8, 68}, /* right < surface */
11500 {60, -16, 68, -8}, /* bottom < surface */
11501 {60, 60, 136, 68}, /* right > surface */
11502 {60, 60, 68, 136}, /* bottom > surface */
11503 {136, 60, 144, 68}, /* left > surface */
11504 {60, 136, 68, 144}, /* top > surface */
11506 static const struct
11515 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
11516 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", TRUE
, DDERR_INVALIDPARAMS
},
11517 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", TRUE
, DDERR_INVALIDPARAMS
},
11518 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", TRUE
, DDERR_INVALIDPARAMS
},
11519 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", TRUE
, DDERR_INVALIDPARAMS
},
11521 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
11522 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem offscreenplain writeonly", FALSE
, DDERR_INVALIDPARAMS
},
11523 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_WRITEONLY
, 0, "sysmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
11524 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_WRITEONLY
, 0, "vidmem texture writeonly", FALSE
, DDERR_INVALIDPARAMS
},
11525 {DDSCAPS_TEXTURE
| DDSCAPS_WRITEONLY
, DDSCAPS2_TEXTUREMANAGE
, "managed texture writeonly", TRUE
, DDERR_INVALIDPARAMS
},
11528 window
= create_window();
11529 ddraw
= create_ddraw();
11530 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11531 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11532 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11534 memset(&hal_caps
, 0, sizeof(hal_caps
));
11535 hal_caps
.dwSize
= sizeof(hal_caps
);
11536 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
11537 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
11538 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
11539 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
11541 skip("Required surface types not supported, skipping test.\n");
11545 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
11547 memset(&surface_desc
, 0, sizeof(surface_desc
));
11548 surface_desc
.dwSize
= sizeof(surface_desc
);
11549 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11550 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
11551 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
11552 surface_desc
.dwWidth
= 128;
11553 surface_desc
.dwHeight
= 128;
11554 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11555 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11556 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11557 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
11558 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
11559 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
11561 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11562 if (!resources
[r
].allowed
)
11564 ok(hr
== DDERR_INVALIDCAPS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
11567 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11569 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
11570 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
11572 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
11574 RECT
*rect
= &valid
[i
];
11576 memset(&surface_desc
, 0, sizeof(surface_desc
));
11577 surface_desc
.dwSize
= sizeof(surface_desc
);
11579 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11580 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
11581 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11583 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11584 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11587 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
11589 RECT
*rect
= &invalid
[i
];
11591 memset(&surface_desc
, 1, sizeof(surface_desc
));
11592 surface_desc
.dwSize
= sizeof(surface_desc
);
11594 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11595 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
11596 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11599 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11600 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11603 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
11606 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11607 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
11608 hr
, resources
[r
].name
);
11609 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11610 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
11611 hr
, resources
[r
].name
);
11612 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11613 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11615 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11616 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
11617 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11618 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
11619 wine_dbgstr_rect(&valid
[0]), hr
);
11621 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
11622 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
11624 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11625 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11627 IDirectDrawSurface4_Release(surface
);
11631 IDirectDraw4_Release(ddraw
);
11632 DestroyWindow(window
);
11635 static void test_yv12_overlay(void)
11637 IDirectDrawSurface4
*src_surface
, *dst_surface
;
11638 RECT rect
= {13, 17, 14, 18};
11639 unsigned int offset
, y
;
11640 DDSURFACEDESC2 desc
;
11641 unsigned char *base
;
11642 IDirectDraw4
*ddraw
;
11646 window
= create_window();
11647 ddraw
= create_ddraw();
11648 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11649 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11650 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11652 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11654 skip("Failed to create a YV12 overlay, skipping test.\n");
11658 memset(&desc
, 0, sizeof(desc
));
11659 desc
.dwSize
= sizeof(desc
);
11660 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11661 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11663 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
11664 "Got unexpected flags %#x.\n", desc
.dwFlags
);
11665 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
11666 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
11667 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
11668 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
11669 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
11670 /* The overlay pitch seems to have 256 byte alignment. */
11671 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
11673 /* Fill the surface with some data for the blit test. */
11674 base
= desc
.lpSurface
;
11676 for (y
= 0; y
< desc
.dwHeight
; ++y
)
11678 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
11681 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
11683 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
11686 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
11688 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
11691 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11692 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11694 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
11695 * other block-based formats like DXT the entire Y channel is stored in
11696 * one big chunk of memory, followed by the chroma channels. So partial
11697 * locks do not really make sense. Show that they are allowed nevertheless
11698 * and the offset points into the luminance data. */
11699 hr
= IDirectDrawSurface4_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
11700 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11701 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
11702 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
11703 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
11704 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11705 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11707 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11709 /* Windows XP with a Radeon X1600 GPU refuses to create a second
11710 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
11711 skip("Failed to create a second YV12 surface, skipping blit test.\n");
11712 IDirectDrawSurface4_Release(src_surface
);
11716 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
11717 /* VMware rejects YV12 blits. This behavior has not been seen on real
11718 * hardware yet, so mark it broken. */
11719 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
11723 memset(&desc
, 0, sizeof(desc
));
11724 desc
.dwSize
= sizeof(desc
);
11725 hr
= IDirectDrawSurface4_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11726 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11728 base
= desc
.lpSurface
;
11729 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
11730 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
11731 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
11732 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
11733 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
11735 hr
= IDirectDrawSurface4_Unlock(dst_surface
, NULL
);
11736 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11739 IDirectDrawSurface4_Release(dst_surface
);
11740 IDirectDrawSurface4_Release(src_surface
);
11742 IDirectDraw4_Release(ddraw
);
11743 DestroyWindow(window
);
11746 static BOOL
dwm_enabled(void)
11750 if (!strcmp(winetest_platform
, "wine"))
11752 if (!pDwmIsCompositionEnabled
)
11754 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
11759 static void test_offscreen_overlay(void)
11761 IDirectDrawSurface4
*overlay
, *offscreen
, *primary
;
11762 DDSURFACEDESC2 surface_desc
;
11763 IDirectDraw4
*ddraw
;
11768 window
= create_window();
11769 ddraw
= create_ddraw();
11770 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11771 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11772 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11774 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11776 skip("Failed to create a UYVY overlay, skipping test.\n");
11780 memset(&surface_desc
, 0, sizeof(surface_desc
));
11781 surface_desc
.dwSize
= sizeof(surface_desc
);
11782 surface_desc
.dwFlags
= DDSD_CAPS
;
11783 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11784 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11785 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11787 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11788 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11789 * surface prevents this by disabling the dwm. */
11790 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11791 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11792 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11793 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11795 /* Try to overlay a NULL surface. */
11796 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
11797 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11798 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
11799 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11801 /* Try to overlay an offscreen surface. */
11802 memset(&surface_desc
, 0, sizeof(surface_desc
));
11803 surface_desc
.dwSize
= sizeof(surface_desc
);
11804 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11805 surface_desc
.dwWidth
= 64;
11806 surface_desc
.dwHeight
= 64;
11807 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11808 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11809 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11810 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
11811 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
11812 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
11813 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
11814 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
11815 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11816 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11818 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
11819 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
11820 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
11821 "Failed to update overlay, hr %#x.\n", hr
);
11823 /* Try to overlay the primary with a non-overlay surface. */
11824 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11825 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11826 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11827 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11829 IDirectDrawSurface4_Release(offscreen
);
11830 IDirectDrawSurface4_Release(primary
);
11831 IDirectDrawSurface4_Release(overlay
);
11833 IDirectDraw4_Release(ddraw
);
11834 DestroyWindow(window
);
11837 static void test_overlay_rect(void)
11839 IDirectDrawSurface4
*overlay
, *primary
= NULL
;
11840 DDSURFACEDESC2 surface_desc
;
11841 RECT rect
= {0, 0, 64, 64};
11842 IDirectDraw4
*ddraw
;
11848 window
= create_window();
11849 ddraw
= create_ddraw();
11850 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11851 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11852 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11854 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11856 skip("Failed to create a UYVY overlay, skipping test.\n");
11860 memset(&surface_desc
, 0, sizeof(surface_desc
));
11861 surface_desc
.dwSize
= sizeof(surface_desc
);
11862 surface_desc
.dwFlags
= DDSD_CAPS
;
11863 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11864 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11865 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11867 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11868 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11869 * surface prevents this by disabling the dwm. */
11870 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11871 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11872 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11873 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11875 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
11878 win_skip("Cannot disable DWM, skipping overlay test.\n");
11882 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
11883 * used. This is not true in Windows Vista and earlier, but changed in
11885 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11886 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11887 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11888 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11889 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11890 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11892 /* Show that the overlay position is the (top, left) coordinate of the
11893 * destination rectangle. */
11894 OffsetRect(&rect
, 32, 16);
11895 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11896 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11897 pos_x
= -1; pos_y
= -1;
11898 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11899 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11900 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
11901 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
11903 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
11904 * seen that the overlay overlays the whole primary(==screen). */
11905 hr2
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
11906 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
11907 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11908 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11909 if (SUCCEEDED(hr2
))
11911 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11912 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11916 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
11917 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
11920 /* The position cannot be retrieved when the overlay is not shown. */
11921 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
11922 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11923 pos_x
= -1; pos_y
= -1;
11924 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11925 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
11926 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11927 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11929 IDirectDrawSurface4_Release(overlay
);
11932 IDirectDrawSurface4_Release(primary
);
11933 IDirectDraw4_Release(ddraw
);
11934 DestroyWindow(window
);
11937 static void test_blt(void)
11939 IDirectDrawSurface4
*surface
, *rt
;
11940 DDSURFACEDESC2 surface_desc
;
11941 IDirect3DDevice3
*device
;
11942 IDirectDraw4
*ddraw
;
11957 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
11958 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
11959 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11960 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11961 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11962 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11963 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11964 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11965 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11966 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11969 window
= create_window();
11970 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11972 skip("Failed to create a 3D device, skipping test.\n");
11973 DestroyWindow(window
);
11977 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11978 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
11979 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
11980 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
11981 IDirect3D3_Release(d3d
);
11982 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11983 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11985 memset(&surface_desc
, 0, sizeof(surface_desc
));
11986 surface_desc
.dwSize
= sizeof(surface_desc
);
11987 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11988 surface_desc
.dwWidth
= 640;
11989 surface_desc
.dwHeight
= 480;
11990 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11991 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11992 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11994 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11995 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11997 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11998 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
12000 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
12002 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
12003 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
12004 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
12006 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
12007 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
12008 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
12010 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
12011 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
12012 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
12014 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
12015 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
12018 IDirectDrawSurface4_Release(surface
);
12019 IDirectDrawSurface4_Release(rt
);
12020 IDirectDraw4_Release(ddraw
);
12021 refcount
= IDirect3DDevice3_Release(device
);
12022 ok(!refcount
, "Device has %u references left.\n", refcount
);
12023 DestroyWindow(window
);
12026 static void test_blt_z_alpha(void)
12028 DWORD blt_flags
[] =
12032 DDBLT_ALPHADESTCONSTOVERRIDE
,
12033 DDBLT_ALPHADESTNEG
,
12034 DDBLT_ALPHADESTSURFACEOVERRIDE
,
12035 DDBLT_ALPHAEDGEBLEND
,
12038 DDBLT_ALPHASRCCONSTOVERRIDE
,
12040 DDBLT_ALPHASRCSURFACEOVERRIDE
,
12043 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
12044 DDBLT_ZBUFFERDESTOVERRIDE
,
12045 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
12046 DDBLT_ZBUFFERSRCOVERRIDE
,
12048 IDirectDrawSurface4
*src_surface
, *dst_surface
;
12049 DDSURFACEDESC2 surface_desc
;
12050 IDirectDraw4
*ddraw
;
12059 window
= create_window();
12060 ddraw
= create_ddraw();
12061 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12062 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12063 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12065 memset(&pf
, 0, sizeof(pf
));
12066 pf
.dwSize
= sizeof(pf
);
12067 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12068 U1(pf
).dwRGBBitCount
= 32;
12069 U2(pf
).dwRBitMask
= 0x00ff0000;
12070 U3(pf
).dwGBitMask
= 0x0000ff00;
12071 U4(pf
).dwBBitMask
= 0x000000ff;
12072 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
12074 memset(&surface_desc
, 0, sizeof(surface_desc
));
12075 surface_desc
.dwSize
= sizeof(surface_desc
);
12076 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12077 surface_desc
.dwWidth
= 64;
12078 surface_desc
.dwHeight
= 64;
12079 U4(surface_desc
).ddpfPixelFormat
= pf
;
12080 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12082 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
12083 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
12084 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
12085 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
12087 memset(&fx
, 0, sizeof(fx
));
12088 fx
.dwSize
= sizeof(fx
);
12089 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
12090 fx
.dwZDestConstBitDepth
= 32;
12091 U1(fx
).dwZDestConst
= 0x11111111;
12092 fx
.dwZSrcConstBitDepth
= 32;
12093 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
12094 fx
.dwAlphaEdgeBlendBitDepth
= 8;
12095 fx
.dwAlphaEdgeBlend
= 0x7f;
12096 fx
.dwAlphaDestConstBitDepth
= 8;
12097 U3(fx
).dwAlphaDestConst
= 0xdd;
12098 fx
.dwAlphaSrcConstBitDepth
= 8;
12099 U4(fx
).dwAlphaSrcConst
= 0x22;
12101 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
12103 U5(fx
).dwFillColor
= 0x3300ff00;
12104 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12105 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
12107 U5(fx
).dwFillColor
= 0xccff0000;
12108 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12109 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
12111 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
12112 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
12114 color
= get_surface_color(dst_surface
, 32, 32);
12115 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
12118 IDirectDrawSurface4_Release(dst_surface
);
12119 IDirectDrawSurface4_Release(src_surface
);
12120 refcount
= IDirectDraw4_Release(ddraw
);
12121 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
12122 DestroyWindow(window
);
12125 static void test_cross_device_blt(void)
12127 IDirectDrawSurface4
*surface
, *surface2
, *sysmem_surface
;
12128 IDirect3DDevice3
*device
, *device2
;
12129 IDirectDraw4
*ddraw
, *ddraw2
;
12130 DDSURFACEDESC2 surface_desc
;
12131 HWND window
, window2
;
12138 window
= create_window();
12139 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
12141 skip("Failed to create a 3D device.\n");
12142 DestroyWindow(window
);
12146 window2
= create_window();
12147 if (!(device2
= create_device(window2
, DDSCL_NORMAL
)))
12149 skip("Failed to create a 3D device.\n");
12150 IDirect3DDevice3_Release(device
);
12151 DestroyWindow(window
);
12152 DestroyWindow(window2
);
12156 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12157 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
12158 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12159 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
12160 IDirect3D3_Release(d3d
);
12162 hr
= IDirect3DDevice3_GetDirect3D(device2
, &d3d
);
12163 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
12164 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw2
);
12165 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
12166 IDirect3D3_Release(d3d
);
12168 memset(&surface_desc
, 0, sizeof(surface_desc
));
12169 surface_desc
.dwSize
= sizeof(surface_desc
);
12170 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
12171 surface_desc
.dwWidth
= 640;
12172 surface_desc
.dwHeight
= 480;
12173 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
12174 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &sysmem_surface
, NULL
);
12175 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12177 memset(&surface_desc
, 0, sizeof(surface_desc
));
12178 surface_desc
.dwSize
= sizeof(surface_desc
);
12179 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
12180 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_VIDEOMEMORY
;
12181 U5(surface_desc
).dwBackBufferCount
= 2;
12182 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
12183 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12185 memset(&surface_desc
, 0, sizeof(surface_desc
));
12186 surface_desc
.dwSize
= sizeof(surface_desc
);
12187 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12188 surface_desc
.dwWidth
= 640;
12189 surface_desc
.dwHeight
= 480;
12190 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
12191 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
12192 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
12193 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
12194 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00007c00;
12195 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x000003e0;
12196 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000001f;
12197 hr
= IDirectDraw4_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
12198 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12200 memset(&fx
, 0, sizeof(fx
));
12201 fx
.dwSize
= sizeof(fx
);
12202 U5(fx
).dwFillColor
= 0xff0000ff;
12203 hr
= IDirectDrawSurface4_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12204 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
12206 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
12207 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
12208 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
12209 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
12210 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
12211 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
12212 color
= get_surface_color(surface
, 320, 240);
12213 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
12215 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
12216 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
12217 color
= get_surface_color(sysmem_surface
, 320, 240);
12218 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
12220 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12221 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12222 hr
= IDirectDrawSurface4_IsLost(sysmem_surface
);
12223 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
12225 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
12226 ok(hr
== E_NOTIMPL
, "Got unexpected hr %#x.\n", hr
);
12227 color
= get_surface_color(sysmem_surface
, 320, 240);
12228 ok(color
== 0x00000000, "Got unexpected color 0x%08x.\n", color
);
12230 IDirectDrawSurface4_Release(surface2
);
12231 memset(&surface_desc
, 0, sizeof(surface_desc
));
12232 surface_desc
.dwSize
= sizeof(surface_desc
);
12233 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
12234 surface_desc
.dwWidth
= 640;
12235 surface_desc
.dwHeight
= 480;
12236 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
12237 hr
= IDirectDraw4_CreateSurface(ddraw2
, &surface_desc
, &surface2
, NULL
);
12238 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
12239 hr
= IDirectDrawSurface4_Blt(surface2
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
12240 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
12242 hr
= IDirectDrawSurface4_Blt(sysmem_surface
, NULL
, surface2
, NULL
, DDBLT_WAIT
, NULL
);
12243 todo_wine
ok(hr
== D3D_OK
, "Failed to blit, hr %#x.\n", hr
);
12244 color
= get_surface_color(sysmem_surface
, 320, 240);
12245 todo_wine
ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12247 IDirectDrawSurface4_Release(surface
);
12248 IDirectDrawSurface4_Release(surface2
);
12249 IDirectDrawSurface4_Release(sysmem_surface
);
12250 IDirectDraw4_Release(ddraw
);
12251 IDirectDraw4_Release(ddraw2
);
12252 refcount
= IDirect3DDevice3_Release(device
);
12253 ok(!refcount
, "Device has %u references left.\n", refcount
);
12254 refcount
= IDirect3DDevice3_Release(device2
);
12255 ok(!refcount
, "Device has %u references left.\n", refcount
);
12256 DestroyWindow(window
);
12257 DestroyWindow(window2
);
12260 static void test_color_clamping(void)
12262 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12263 static D3DMATRIX mat
=
12265 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12266 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12267 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12268 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12270 static struct vec3 quad
[] =
12272 {-1.0f
, -1.0f
, 0.1f
},
12273 {-1.0f
, 1.0f
, 0.1f
},
12274 { 1.0f
, -1.0f
, 0.1f
},
12275 { 1.0f
, 1.0f
, 0.1f
},
12277 IDirect3DViewport3
*viewport
;
12278 IDirect3DDevice3
*device
;
12279 IDirectDrawSurface4
*rt
;
12285 window
= create_window();
12286 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12288 skip("Failed to create a 3D device, skipping test.\n");
12289 DestroyWindow(window
);
12293 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12294 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12296 viewport
= create_viewport(device
, 0, 0, 640, 480);
12297 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12298 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12300 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12301 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12302 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12303 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
12304 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12305 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
12306 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12307 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
12308 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12309 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12310 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
12311 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
12312 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12313 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
12315 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
12316 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
12317 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
12318 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
12319 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
12320 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12321 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
12322 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12323 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
12324 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
12325 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
12326 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12327 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
12328 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12330 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
12331 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12333 hr
= IDirect3DDevice3_BeginScene(device
);
12334 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12336 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
12337 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12339 hr
= IDirect3DDevice3_EndScene(device
);
12340 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12342 color
= get_surface_color(rt
, 320, 240);
12343 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
12345 destroy_viewport(device
, viewport
);
12346 IDirectDrawSurface4_Release(rt
);
12347 refcount
= IDirect3DDevice3_Release(device
);
12348 ok(!refcount
, "Device has %u references left.\n", refcount
);
12349 DestroyWindow(window
);
12352 static void test_getdc(void)
12354 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
12355 IDirectDrawSurface4
*surface
, *surface2
, *tmp
;
12356 DDSURFACEDESC2 surface_desc
, map_desc
;
12357 IDirectDraw4
*ddraw
;
12363 static const struct
12366 DDPIXELFORMAT format
;
12367 BOOL getdc_supported
;
12368 HRESULT alt_result
;
12372 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
12373 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
12374 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
12375 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
12376 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
12377 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
12378 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
12379 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
12380 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
12381 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
12382 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
12383 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
12384 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
12385 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
12386 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
12387 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
12388 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
12389 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
12390 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
12391 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
12392 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
12393 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
12394 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
12395 * This is not implemented in wine yet, so disable the test for now.
12396 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
12397 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
12398 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
12400 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
12401 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12402 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
12403 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
12404 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
12405 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12406 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
12407 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12408 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
12409 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12410 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
12411 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12412 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
12413 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
12416 window
= create_window();
12417 ddraw
= create_ddraw();
12418 ok(!!ddraw
, "Failed to create a ddraw object.\n");
12419 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
12420 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
12422 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
12424 memset(&surface_desc
, 0, sizeof(surface_desc
));
12425 surface_desc
.dwSize
= sizeof(surface_desc
);
12426 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
12427 surface_desc
.dwWidth
= 64;
12428 surface_desc
.dwHeight
= 64;
12429 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
12430 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
12432 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
12434 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
12435 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
12436 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
12438 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
12443 dc
= (void *)0x1234;
12444 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12445 if (test_data
[i
].getdc_supported
)
12446 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
12447 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12449 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12453 unsigned int width_bytes
;
12459 type
= GetObjectType(dc
);
12460 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
12461 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
12462 type
= GetObjectType(bitmap
);
12463 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
12465 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
12466 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
12467 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
12468 dib
.dsBm
.bmType
, test_data
[i
].name
);
12469 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
12470 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
12471 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
12472 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
12473 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
12474 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
12475 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
12476 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
12477 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
12478 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
12479 "Got unexpected bit count %d for format %s.\n",
12480 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
12481 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
12482 dib
.dsBm
.bmBits
, test_data
[i
].name
);
12484 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
12485 dib
.dsBmih
.biSize
, test_data
[i
].name
);
12486 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
12487 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
12488 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
12489 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
12490 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
12491 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
12492 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
12493 "Got unexpected bit count %u for format %s.\n",
12494 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
12495 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
12496 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
12497 "Got unexpected compression %#x for format %s.\n",
12498 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
12499 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
12500 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
12501 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
12502 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
12503 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
12504 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
12505 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
12506 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
12507 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
12508 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
12510 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
12512 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
12513 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
12514 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
12515 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
12516 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
12517 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
12521 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
12522 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
12523 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
12525 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
12526 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
12528 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12529 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12533 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
12536 IDirectDrawSurface4_Release(surface
);
12541 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
12542 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
12543 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
12545 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
12546 test_data
[i
].name
, hr
);
12550 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
12551 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12552 hr
= IDirectDrawSurface4_GetAttachedSurface(tmp
, &caps
, &surface2
);
12553 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12554 IDirectDrawSurface4_Release(tmp
);
12556 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12557 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12558 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12559 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12560 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
12561 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12562 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
12563 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12565 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12566 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12567 dc2
= (void *)0x1234;
12568 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
12569 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12570 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
12571 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12572 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12573 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12574 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12576 map_desc
.dwSize
= sizeof(map_desc
);
12577 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12578 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12579 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12580 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12581 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12582 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12583 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12584 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12586 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12587 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12588 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12589 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12590 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12591 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12593 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12594 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12595 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12596 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12597 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12598 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12599 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12600 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12602 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12603 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12604 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc2
);
12605 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12606 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc2
);
12607 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12608 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12609 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12611 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
12612 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12613 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
12614 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12615 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc2
);
12616 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12617 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
12618 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12620 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12621 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12622 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12623 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12624 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12625 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12626 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12627 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12629 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12630 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12631 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12632 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12633 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12634 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12635 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12636 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12638 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12639 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12640 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12641 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12642 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12643 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12644 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12645 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12647 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12648 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12649 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12650 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12651 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12652 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12653 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12654 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12656 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
12657 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12658 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
12659 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12660 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12661 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12662 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
12663 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12665 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12666 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12667 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
12668 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12669 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12670 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12671 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
12672 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12673 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
12674 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12676 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12677 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12678 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12679 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12680 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12681 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12682 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12683 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12684 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12685 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12687 IDirectDrawSurface4_Release(surface2
);
12688 IDirectDrawSurface4_Release(surface
);
12691 IDirectDraw4_Release(ddraw
);
12692 DestroyWindow(window
);
12695 static void test_draw_primitive(void)
12697 static WORD indices
[] = {0, 1, 2, 3};
12698 static struct vec3 quad
[] =
12700 {-1.0f
, -1.0f
, 0.0f
},
12701 {-1.0f
, 1.0f
, 0.0f
},
12702 { 1.0f
, -1.0f
, 0.0f
},
12703 { 1.0f
, 1.0f
, 0.0f
},
12705 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
12706 IDirect3DViewport3
*viewport
;
12707 D3DVERTEXBUFFERDESC vb_desc
;
12708 IDirect3DVertexBuffer
*vb
;
12709 IDirect3DDevice3
*device
;
12716 window
= create_window();
12717 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12719 skip("Failed to create a 3D device, skipping test.\n");
12720 DestroyWindow(window
);
12724 viewport
= create_viewport(device
, 0, 0, 640, 480);
12725 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12726 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12728 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12729 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12731 memset(&vb_desc
, 0, sizeof(vb_desc
));
12732 vb_desc
.dwSize
= sizeof(vb_desc
);
12733 vb_desc
.dwFVF
= D3DFVF_XYZ
;
12734 vb_desc
.dwNumVertices
= 4;
12735 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
12736 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
12738 IDirect3D3_Release(d3d
);
12740 memset(&strided
, 0, sizeof(strided
));
12742 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
12743 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12744 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12745 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
12746 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12747 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12748 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12749 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
12750 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12751 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
12752 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12753 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
12754 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12756 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
12757 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12758 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12759 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
12760 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12761 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12762 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12764 strided
.position
.lpvData
= quad
;
12765 strided
.position
.dwStride
= sizeof(*quad
);
12766 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, &data
, NULL
);
12767 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
12768 memcpy(data
, quad
, sizeof(quad
));
12769 hr
= IDirect3DVertexBuffer_Unlock(vb
);
12770 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12772 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
12773 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12774 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12775 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
12776 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12777 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12778 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12779 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
12780 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12781 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
12782 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12783 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
12784 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12785 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
12786 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12787 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12788 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
12789 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12790 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12791 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12793 IDirect3DVertexBuffer_Release(vb
);
12794 destroy_viewport(device
, viewport
);
12795 refcount
= IDirect3DDevice3_Release(device
);
12796 ok(!refcount
, "Device has %u references left.\n", refcount
);
12797 DestroyWindow(window
);
12800 static void test_edge_antialiasing_blending(void)
12802 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12803 IDirectDrawSurface4
*offscreen
, *ds
;
12804 D3DDEVICEDESC hal_desc
, hel_desc
;
12805 IDirect3DViewport3
*viewport
;
12806 DDSURFACEDESC2 surface_desc
;
12807 IDirect3DDevice3
*device
;
12808 IDirectDraw4
*ddraw
;
12815 static D3DMATRIX mat
=
12817 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12818 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12819 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12820 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12824 struct vec3 position
;
12829 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12830 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12831 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12832 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12836 struct vec3 position
;
12841 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12842 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12843 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12844 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12847 window
= create_window();
12848 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12850 skip("Failed to create a 3D device.\n");
12851 DestroyWindow(window
);
12855 memset(&hal_desc
, 0, sizeof(hal_desc
));
12856 hal_desc
.dwSize
= sizeof(hal_desc
);
12857 memset(&hel_desc
, 0, sizeof(hel_desc
));
12858 hel_desc
.dwSize
= sizeof(hel_desc
);
12859 hr
= IDirect3DDevice3_GetCaps(device
, &hal_desc
, &hel_desc
);
12860 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
12861 trace("HAL line edge antialiasing support: %#x.\n",
12862 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12863 trace("HAL triangle edge antialiasing support: %#x.\n",
12864 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12865 trace("HEL line edge antialiasing support: %#x.\n",
12866 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12867 trace("HEL triangle edge antialiasing support: %#x.\n",
12868 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12870 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12871 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12872 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12873 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
12874 IDirect3D3_Release(d3d
);
12876 memset(&surface_desc
, 0, sizeof(surface_desc
));
12877 surface_desc
.dwSize
= sizeof(surface_desc
);
12878 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12879 surface_desc
.dwWidth
= 640;
12880 surface_desc
.dwHeight
= 480;
12881 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
12882 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12883 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12884 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12885 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12886 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12887 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12888 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12889 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
12891 ds
= get_depth_stencil(device
);
12892 hr
= IDirectDrawSurface4_AddAttachedSurface(offscreen
, ds
);
12893 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
12894 IDirectDrawSurface4_Release(ds
);
12896 hr
= IDirect3DDevice3_SetRenderTarget(device
, offscreen
, 0);
12897 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
12899 viewport
= create_viewport(device
, 0, 0, 640, 480);
12900 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12901 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12903 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12904 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12905 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12906 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
12907 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12908 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
12909 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12910 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
12911 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12912 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12913 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
12914 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
12915 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12916 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
12918 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
12919 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
12920 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
12921 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
12922 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
12923 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
12925 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
12926 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
12927 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
12928 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12929 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
12930 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
12931 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
12932 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
12934 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12935 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12936 hr
= IDirect3DDevice3_BeginScene(device
);
12937 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12938 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12940 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12941 hr
= IDirect3DDevice3_EndScene(device
);
12942 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12943 color
= get_surface_color(offscreen
, 320, 240);
12944 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12946 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12947 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12948 hr
= IDirect3DDevice3_BeginScene(device
);
12949 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12950 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12952 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12953 hr
= IDirect3DDevice3_EndScene(device
);
12954 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12955 color
= get_surface_color(offscreen
, 320, 240);
12956 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12958 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
12959 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
12961 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12962 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12963 hr
= IDirect3DDevice3_BeginScene(device
);
12964 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12965 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12967 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12968 hr
= IDirect3DDevice3_EndScene(device
);
12969 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12970 color
= get_surface_color(offscreen
, 320, 240);
12971 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12973 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12974 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12975 hr
= IDirect3DDevice3_BeginScene(device
);
12976 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12977 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12979 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12980 hr
= IDirect3DDevice3_EndScene(device
);
12981 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12982 color
= get_surface_color(offscreen
, 320, 240);
12983 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12985 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
12986 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
12988 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12989 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12990 hr
= IDirect3DDevice3_BeginScene(device
);
12991 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12992 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12994 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12995 hr
= IDirect3DDevice3_EndScene(device
);
12996 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12997 color
= get_surface_color(offscreen
, 320, 240);
12998 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13000 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
13001 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
13002 hr
= IDirect3DDevice3_BeginScene(device
);
13003 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13004 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13006 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13007 hr
= IDirect3DDevice3_EndScene(device
);
13008 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13009 color
= get_surface_color(offscreen
, 320, 240);
13010 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
13012 IDirectDrawSurface4_Release(offscreen
);
13013 IDirectDraw4_Release(ddraw
);
13014 destroy_viewport(device
, viewport
);
13015 refcount
= IDirect3DDevice3_Release(device
);
13016 ok(!refcount
, "Device has %u references left.\n", refcount
);
13017 DestroyWindow(window
);
13020 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
13021 * The stride is honored for navigating to the next vertex. 3 floats input position
13022 * are read, and 16 bytes extra vertex data are copied around. */
13023 struct transform_input
13025 float x
, y
, z
, unused1
; /* Position data, transformed. */
13026 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
13030 struct transform_output
13033 DWORD v1
, v2
, v3
, v4
;
13034 DWORD unused3
, unused4
;
13037 static void test_transform_vertices(void)
13039 IDirect3DDevice3
*device
;
13040 IDirectDrawSurface4
*rt
;
13045 IDirect3DViewport3
*viewport
;
13046 static struct transform_input position_tests
[] =
13048 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
13049 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
13050 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
13051 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
13052 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
13053 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
13055 static struct transform_input cliptest
[] =
13057 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
13058 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
13059 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
13060 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
13062 static struct transform_input offscreentest
[] =
13064 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
13066 struct transform_output out
[ARRAY_SIZE(position_tests
)];
13067 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
13068 D3DTRANSFORMDATA transformdata
;
13069 static const D3DVIEWPORT vp_template
=
13071 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
13073 D3DVIEWPORT vp_data
=
13075 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
13077 D3DVIEWPORT2 vp2_data
;
13080 static D3DMATRIX mat_scale
=
13082 2.0f
, 0.0f
, 0.0f
, 0.0f
,
13083 0.0f
, 2.0f
, 0.0f
, 0.0f
,
13084 0.0f
, 0.0f
, 2.0f
, 0.0f
,
13085 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13089 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13090 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13091 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13092 1.0f
, 0.0f
, 0.0f
, 1.0f
,
13096 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13097 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13098 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13099 0.0f
, 1.0f
, 0.0f
, 1.0f
,
13103 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13104 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13105 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13106 0.0f
, 19.2f
, 0.0f
, 2.0f
,
13110 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13111 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13112 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13113 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13117 struct vec3 position
;
13122 {{-0.75f
, -0.5f
, 0.0f
}, 0xffff0000},
13123 {{-0.75f
, 0.25f
, 0.0f
}, 0xffff0000},
13124 {{ 0.5f
, -0.5f
, 0.0f
}, 0xffff0000},
13125 {{ 0.5f
, 0.25f
, 0.0f
}, 0xffff0000},
13127 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
13129 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
13131 out
[i
].unused3
= 0xdeadbeef;
13132 out
[i
].unused4
= 0xcafecafe;
13135 window
= create_window();
13136 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13138 skip("Failed to create a 3D device.\n");
13139 DestroyWindow(window
);
13142 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
13143 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
13145 viewport
= create_viewport(device
, 0, 0, 256, 256);
13146 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13147 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13149 memset(&transformdata
, 0, sizeof(transformdata
));
13150 transformdata
.dwSize
= sizeof(transformdata
);
13151 transformdata
.lpIn
= position_tests
;
13152 transformdata
.dwInSize
= sizeof(position_tests
[0]);
13153 transformdata
.lpOut
= out
;
13154 transformdata
.dwOutSize
= sizeof(out
[0]);
13155 transformdata
.lpHOut
= NULL
;
13157 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13158 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13159 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13160 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13162 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13164 static const struct vec4 cmp
[] =
13166 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
13167 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
13170 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13171 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13172 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13173 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
13174 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
13175 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
13176 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
13177 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
13180 vp_data
= vp_template
;
13181 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13182 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13183 offscreen
= 0xdeadbeef;
13184 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13185 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13186 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13187 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13189 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13191 static const struct vec4 cmp
[] =
13193 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
13194 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
13196 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13197 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13198 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13203 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13204 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13205 offscreen
= 0xdeadbeef;
13206 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13207 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13208 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13209 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13210 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13212 static const struct vec4 cmp
[] =
13214 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
13215 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
13217 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13218 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13219 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13222 transformdata
.lpHOut
= out_h
;
13223 offscreen
= 0xdeadbeef;
13224 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13225 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13226 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13227 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13228 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13230 static const D3DHVERTEX cmp_h
[] =
13232 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
13233 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
13234 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
13236 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
13237 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
13238 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
13239 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
13240 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
13241 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
13243 /* No scheme has been found behind those return values. It seems to be
13244 * whatever data windows has when throwing the vertex away. Modify the
13245 * input test vertices to test this more. Depending on the input data
13246 * it can happen that the z coord gets written into y, or similar things. */
13249 static const struct vec4 cmp
[] =
13251 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
13252 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
13254 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13255 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13256 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13260 transformdata
.lpIn
= cliptest
;
13261 transformdata
.dwInSize
= sizeof(cliptest
[0]);
13262 offscreen
= 0xdeadbeef;
13263 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
13264 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13265 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13266 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13267 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
13269 static const DWORD flags
[] =
13272 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
13274 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
13276 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
13279 vp_data
= vp_template
;
13280 vp_data
.dwWidth
= 10;
13281 vp_data
.dwHeight
= 480;
13282 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13283 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13284 offscreen
= 0xdeadbeef;
13285 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
13286 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13287 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13288 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13289 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
13291 static const DWORD flags
[] =
13294 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
13296 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
13298 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
13301 vp_data
= vp_template
;
13302 vp_data
.dwWidth
= 256;
13303 vp_data
.dwHeight
= 256;
13304 vp_data
.dvScaleX
= 1;
13305 vp_data
.dvScaleY
= 1;
13306 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13307 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13308 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
13309 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13310 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13311 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13312 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
13314 static const DWORD flags
[] =
13321 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
13324 /* Finally try to figure out how the DWORD dwOffscreen works.
13325 * It is a logical AND of the vertices' dwFlags members. */
13326 vp_data
= vp_template
;
13327 vp_data
.dwWidth
= 5;
13328 vp_data
.dwHeight
= 5;
13329 vp_data
.dvScaleX
= 10000.0f
;
13330 vp_data
.dvScaleY
= 10000.0f
;
13331 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13332 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13333 transformdata
.lpIn
= cliptest
;
13334 offscreen
= 0xdeadbeef;
13335 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13336 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13337 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13338 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13340 offscreen
= 0xdeadbeef;
13341 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13342 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13343 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13344 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
13345 offscreen
= 0xdeadbeef;
13346 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
13347 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13348 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13349 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
13350 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
13351 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13352 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13353 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13355 transformdata
.lpIn
= cliptest
+ 1;
13356 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13357 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13358 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13359 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
13361 transformdata
.lpIn
= cliptest
+ 2;
13362 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13363 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13364 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13365 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
13366 offscreen
= 0xdeadbeef;
13367 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
13368 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13369 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13370 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
13372 transformdata
.lpIn
= cliptest
+ 3;
13373 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13374 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13375 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13376 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
13378 transformdata
.lpIn
= offscreentest
;
13379 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
13380 vp_data
= vp_template
;
13381 vp_data
.dwWidth
= 257;
13382 vp_data
.dwHeight
= 257;
13383 vp_data
.dvScaleX
= 1.0f
;
13384 vp_data
.dvScaleY
= 1.0f
;
13385 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13386 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13387 offscreen
= 0xdeadbeef;
13388 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13389 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13390 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13391 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13393 vp_data
.dwWidth
= 256;
13394 vp_data
.dwHeight
= 256;
13395 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13396 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13397 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13398 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13399 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13400 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
13402 /* Test the effect of Matrices.
13404 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
13405 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
13406 * the view matrix and the +1's from the world and projection matrix. */
13409 vp_data
.dwWidth
= 256;
13410 vp_data
.dwHeight
= 256;
13411 vp_data
.dvScaleX
= 5.0f
;
13412 vp_data
.dvScaleY
= 5.0f
;
13413 vp_data
.dvMinZ
= 0.0f
;
13414 vp_data
.dvMaxZ
= 1.0f
;
13415 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
13416 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13418 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
13419 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13420 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
13421 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13422 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
13423 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13425 transformdata
.lpIn
= position_tests
;
13426 transformdata
.dwInSize
= sizeof(position_tests
[0]);
13427 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13428 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13429 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13431 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13433 static const struct vec4 cmp
[] =
13435 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
13436 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
13439 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13440 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13441 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13444 /* Invalid flags. */
13445 offscreen
= 0xdeadbeef;
13446 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13447 &transformdata
, 0, &offscreen
);
13448 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13449 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
13451 /* NULL transform data. */
13452 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13453 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13454 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13455 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
13456 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
13457 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13458 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13459 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
13461 /* NULL transform data and NULL dwOffscreen.
13463 * Valid transform data + NULL dwOffscreen -> crash. */
13464 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13465 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
13466 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13469 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
13470 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13471 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13472 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13473 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
13474 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13475 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13476 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
13478 /* Invalid sizes. */
13479 offscreen
= 0xdeadbeef;
13480 transformdata
.dwSize
= sizeof(transformdata
) - 1;
13481 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13482 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13483 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13484 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
13485 transformdata
.dwSize
= sizeof(transformdata
) + 1;
13486 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
13487 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13488 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
13489 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
13491 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
13492 transformdata
.dwSize
= sizeof(transformdata
);
13493 transformdata
.lpIn
= NULL
;
13494 transformdata
.lpOut
= NULL
;
13495 offscreen
= 0xdeadbeef;
13496 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
13497 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13498 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13499 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
13501 /* Test how vertices are transformed during draws. */
13504 vp_data
.dwWidth
= 200;
13505 vp_data
.dwHeight
= 400;
13506 vp_data
.dvScaleX
= 20.0f
;
13507 vp_data
.dvScaleY
= 50.0f
;
13508 vp_data
.dvMinZ
= 0.0f
;
13509 vp_data
.dvMaxZ
= 1.0f
;
13510 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp_data
);
13511 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
13512 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
13513 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
13515 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
13516 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
13518 hr
= IDirect3DDevice3_BeginScene(device
);
13519 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13520 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13522 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13523 hr
= IDirect3DDevice3_EndScene(device
);
13524 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13526 color
= get_surface_color(rt
, 128, 143);
13527 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13528 color
= get_surface_color(rt
, 132, 143);
13529 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13530 color
= get_surface_color(rt
, 128, 147);
13531 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13532 color
= get_surface_color(rt
, 132, 147);
13533 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
13535 color
= get_surface_color(rt
, 177, 217);
13536 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
13537 color
= get_surface_color(rt
, 181, 217);
13538 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13539 color
= get_surface_color(rt
, 177, 221);
13540 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13541 color
= get_surface_color(rt
, 181, 221);
13542 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
13544 /* Test D3DVIEWPORT2 behavior. */
13545 vp2_data
.dwSize
= sizeof(vp2_data
);
13548 vp2_data
.dwWidth
= 200;
13549 vp2_data
.dwHeight
= 400;
13550 vp2_data
.dvClipX
= -0.5f
;
13551 vp2_data
.dvClipY
= 4.0f
;
13552 vp2_data
.dvClipWidth
= 5.0f
;
13553 vp2_data
.dvClipHeight
= 10.0f
;
13554 vp2_data
.dvMinZ
= 0.0f
;
13555 vp2_data
.dvMaxZ
= 2.0f
;
13556 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
13557 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
13558 transformdata
.lpIn
= position_tests
;
13559 transformdata
.lpOut
= out
;
13560 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
13561 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
13562 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13563 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
13565 static const struct vec4 cmp
[] =
13567 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
13568 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
13571 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
13572 "Vertex %u differs. Got %f %f %f %f.\n", i
,
13573 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
13576 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
13577 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
13579 hr
= IDirect3DDevice3_BeginScene(device
);
13580 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
13581 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
13583 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
13584 hr
= IDirect3DDevice3_EndScene(device
);
13585 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
13587 color
= get_surface_color(rt
, 58, 118);
13588 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13589 color
= get_surface_color(rt
, 62, 118);
13590 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13591 color
= get_surface_color(rt
, 58, 122);
13592 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13593 color
= get_surface_color(rt
, 62, 122);
13594 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
13596 color
= get_surface_color(rt
, 157, 177);
13597 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
13598 color
= get_surface_color(rt
, 161, 177);
13599 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13600 color
= get_surface_color(rt
, 157, 181);
13601 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13602 color
= get_surface_color(rt
, 161, 181);
13603 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
13605 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
13606 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13607 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
13608 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13609 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
13610 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
13612 vp2_data
.dwX
= 0.0;
13613 vp2_data
.dwY
= 0.0;
13614 vp2_data
.dwWidth
= 1;
13615 vp2_data
.dwHeight
= 1;
13616 vp2_data
.dvClipX
= -12.8f
;
13617 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
13618 vp2_data
.dvClipWidth
= 25.6f
;
13619 vp2_data
.dvClipHeight
= 25.6f
;
13620 vp2_data
.dvMinZ
= 0.0f
;
13621 vp2_data
.dvMaxZ
= 0.5f
;
13622 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
13623 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
13624 transformdata
.lpIn
= cliptest
;
13625 transformdata
.dwInSize
= sizeof(cliptest
[0]);
13626 offscreen
= 0xdeadbeef;
13627 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
13628 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
13629 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
13630 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
13631 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
13633 static const D3DHVERTEX cmp_h
[] =
13635 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
13636 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
13637 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
13638 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
13640 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
13641 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
13642 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
13643 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
13644 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
13645 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
13648 destroy_viewport(device
, viewport
);
13649 IDirectDrawSurface4_Release(rt
);
13650 refcount
= IDirect3DDevice3_Release(device
);
13651 ok(!refcount
, "Device has %u references left.\n", refcount
);
13652 DestroyWindow(window
);
13655 static void test_display_mode_surface_pixel_format(void)
13657 unsigned int width
, height
, bpp
;
13658 IDirectDrawSurface4
*surface
;
13659 DDSURFACEDESC2 surface_desc
;
13660 IDirectDraw4
*ddraw
;
13665 if (!(ddraw
= create_ddraw()))
13667 skip("Failed to create ddraw.\n");
13671 surface_desc
.dwSize
= sizeof(surface_desc
);
13672 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13673 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13674 width
= surface_desc
.dwWidth
;
13675 height
= surface_desc
.dwHeight
;
13677 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13678 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
13679 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13680 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13683 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
13685 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
13687 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
13689 ok(bpp
, "Set display mode failed.\n");
13691 surface_desc
.dwSize
= sizeof(surface_desc
);
13692 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13693 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13694 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13695 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13696 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13697 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13699 memset(&surface_desc
, 0, sizeof(surface_desc
));
13700 surface_desc
.dwSize
= sizeof(surface_desc
);
13701 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13702 U5(surface_desc
).dwBackBufferCount
= 1;
13703 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
13704 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13705 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13706 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13707 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13708 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13709 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13710 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13711 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13712 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13713 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13714 IDirectDrawSurface4_Release(surface
);
13716 memset(&surface_desc
, 0, sizeof(surface_desc
));
13717 surface_desc
.dwSize
= sizeof(surface_desc
);
13718 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13719 surface_desc
.dwWidth
= width
;
13720 surface_desc
.dwHeight
= height
;
13721 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13722 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13723 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13724 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13725 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13726 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13727 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13728 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13729 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13730 IDirectDrawSurface4_Release(surface
);
13732 refcount
= IDirectDraw4_Release(ddraw
);
13733 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13734 DestroyWindow(window
);
13737 static void test_surface_desc_size(void)
13742 DDSURFACEDESC desc1
;
13743 DDSURFACEDESC2 desc2
;
13746 IDirectDrawSurface4
*surface4
;
13747 IDirectDrawSurface3
*surface3
;
13748 IDirectDrawSurface
*surface
;
13749 DDSURFACEDESC2 surface_desc
;
13750 HRESULT expected_hr
, hr
;
13751 IDirectDraw4
*ddraw
;
13755 static const struct
13762 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
13763 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
13764 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
13766 static const unsigned int desc_sizes
[] =
13768 sizeof(DDSURFACEDESC
),
13769 sizeof(DDSURFACEDESC2
),
13770 sizeof(DDSURFACEDESC
) + 1,
13771 sizeof(DDSURFACEDESC2
) + 1,
13772 2 * sizeof(DDSURFACEDESC
),
13773 2 * sizeof(DDSURFACEDESC2
),
13774 sizeof(DDSURFACEDESC
) - 1,
13775 sizeof(DDSURFACEDESC2
) - 1,
13776 sizeof(DDSURFACEDESC
) / 2,
13777 sizeof(DDSURFACEDESC2
) / 2,
13782 sizeof(desc
) - 100,
13785 if (!(ddraw
= create_ddraw()))
13787 skip("Failed to create ddraw.\n");
13790 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13791 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13793 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
13795 memset(&surface_desc
, 0, sizeof(surface_desc
));
13796 surface_desc
.dwSize
= sizeof(surface_desc
);
13797 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13798 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
13799 surface_desc
.dwHeight
= 128;
13800 surface_desc
.dwWidth
= 128;
13801 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
)))
13803 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
13806 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface
, (void **)&surface
);
13807 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13808 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
13809 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13811 /* GetSurfaceDesc() */
13812 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13814 memset(&desc
, 0, sizeof(desc
));
13815 desc
.dwSize
= desc_sizes
[j
];
13816 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13817 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
13818 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13819 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13821 memset(&desc
, 0, sizeof(desc
));
13822 desc
.dwSize
= desc_sizes
[j
];
13823 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13824 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
13825 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13826 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13828 memset(&desc
, 0, sizeof(desc
));
13829 desc
.dwSize
= desc_sizes
[j
];
13830 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13831 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface4
, &desc
.desc2
);
13832 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13833 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13837 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13839 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
13840 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
13841 DWORD expected_texture_stage
;
13843 memset(&desc
, 0, sizeof(desc
));
13844 desc
.dwSize
= desc_sizes
[j
];
13845 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13846 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13847 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
13848 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13849 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13850 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13851 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13852 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13853 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13854 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13857 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13858 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13859 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13860 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13861 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13862 todo_wine_if(!expected_texture_stage
)
13863 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13864 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13865 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13866 IDirectDrawSurface_Unlock(surface
, NULL
);
13869 memset(&desc
, 0, sizeof(desc
));
13870 desc
.dwSize
= desc_sizes
[j
];
13871 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13872 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13873 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
13874 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13875 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13876 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13877 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13878 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13879 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13880 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13883 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13884 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13885 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13886 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13887 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13888 todo_wine_if(!expected_texture_stage
)
13889 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13890 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13891 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13892 IDirectDrawSurface3_Unlock(surface3
, NULL
);
13895 memset(&desc
, 0, sizeof(desc
));
13896 desc
.dwSize
= desc_sizes
[j
];
13897 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13898 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13899 hr
= IDirectDrawSurface4_Lock(surface4
, NULL
, &desc
.desc2
, 0, 0);
13900 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13901 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13902 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13903 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13904 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13905 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13906 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13909 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13910 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13911 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13912 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13913 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13914 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13915 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13916 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13917 IDirectDrawSurface4_Unlock(surface4
, NULL
);
13921 IDirectDrawSurface4_Release(surface4
);
13922 IDirectDrawSurface3_Release(surface3
);
13923 IDirectDrawSurface_Release(surface
);
13926 /* GetDisplayMode() */
13927 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13929 memset(&desc
, 0xcc, sizeof(desc
));
13930 desc
.dwSize
= desc_sizes
[j
];
13931 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
13932 ? DD_OK
: DDERR_INVALIDPARAMS
;
13933 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &desc
.desc2
);
13934 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
13937 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
13938 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
13939 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
13943 refcount
= IDirectDraw4_Release(ddraw
);
13944 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13947 static void test_get_surface_from_dc(void)
13949 IDirectDrawSurface
*surface1
, *tmp
;
13950 IDirectDrawSurface4
*surface
;
13951 DDSURFACEDESC2 surface_desc
;
13952 IDirectDraw4
*ddraw
;
13959 window
= create_window();
13960 ddraw
= create_ddraw();
13961 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13962 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13963 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13965 memset(&surface_desc
, 0, sizeof(surface_desc
));
13966 surface_desc
.dwSize
= sizeof(surface_desc
);
13967 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
13968 surface_desc
.dwWidth
= 64;
13969 surface_desc
.dwHeight
= 64;
13970 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13972 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13973 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13974 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
13975 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13977 refcount
= get_refcount((IUnknown
*)surface1
);
13978 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13979 refcount
= get_refcount((IUnknown
*)surface
);
13980 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13982 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13983 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
13985 tmp
= (void *)0xdeadbeef;
13986 device_dc
= (void *)0xdeadbeef;
13987 hr
= GetSurfaceFromDC(NULL
, &tmp
, &device_dc
);
13988 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13989 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13990 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
13992 device_dc
= (void *)0xdeadbeef;
13993 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
13994 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13995 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
13997 tmp
= (void *)0xdeadbeef;
13998 hr
= GetSurfaceFromDC(dc
, &tmp
, NULL
);
13999 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14000 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14002 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
14003 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14004 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
14005 IDirectDrawSurface_Release(tmp
);
14007 ret
= GetObjectType(device_dc
);
14008 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#x.\n", ret
);
14009 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
14010 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#x.\n", ret
);
14012 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, NULL
);
14013 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
14015 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
14016 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
14017 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
14019 refcount
= get_refcount((IUnknown
*)surface1
);
14020 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
14021 refcount
= get_refcount((IUnknown
*)surface
);
14022 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
14024 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
14025 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#x.\n", hr
);
14027 IDirectDrawSurface_Release(tmp
);
14029 dc
= CreateCompatibleDC(NULL
);
14030 ok(!!dc
, "CreateCompatibleDC failed.\n");
14032 tmp
= (void *)0xdeadbeef;
14033 device_dc
= (void *)0xdeadbeef;
14034 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
14035 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14036 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14037 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
14039 tmp
= (void *)0xdeadbeef;
14040 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
14041 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14042 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14044 ok(DeleteDC(dc
), "DeleteDC failed.\n");
14046 tmp
= (void *)0xdeadbeef;
14047 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, NULL
, (IDirectDrawSurface4
**)&tmp
);
14048 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
14049 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
14051 IDirectDrawSurface4_Release(surface
);
14052 IDirectDrawSurface_Release(surface1
);
14053 IDirectDraw4_Release(ddraw
);
14054 DestroyWindow(window
);
14057 static void test_ck_operation(void)
14059 IDirectDrawSurface4
*src
, *dst
;
14060 IDirectDrawSurface
*src1
, *dst1
;
14061 DDSURFACEDESC2 surface_desc
;
14062 IDirectDraw4
*ddraw
;
14071 window
= create_window();
14072 ddraw
= create_ddraw();
14073 ok(!!ddraw
, "Failed to create a ddraw object.\n");
14074 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
14075 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
14077 memset(&surface_desc
, 0, sizeof(surface_desc
));
14078 surface_desc
.dwSize
= sizeof(surface_desc
);
14079 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14080 surface_desc
.dwWidth
= 4;
14081 surface_desc
.dwHeight
= 1;
14082 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14083 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
14084 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14085 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14086 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14087 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14088 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14089 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14091 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
14092 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
14093 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
14094 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14095 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14097 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14098 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14099 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14100 color
= surface_desc
.lpSurface
;
14101 color
[0] = 0x77010203;
14102 color
[1] = 0x00010203;
14103 color
[2] = 0x77ff00ff;
14104 color
[3] = 0x00ff00ff;
14105 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
14106 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14108 for (i
= 0; i
< 2; ++i
)
14110 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14111 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14112 color
= surface_desc
.lpSurface
;
14113 color
[0] = 0xcccccccc;
14114 color
[1] = 0xcccccccc;
14115 color
[2] = 0xcccccccc;
14116 color
[3] = 0xcccccccc;
14117 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14118 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14122 hr
= IDirectDrawSurface4_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
14123 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14127 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
14128 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14131 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
14132 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14133 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
14134 color
= surface_desc
.lpSurface
;
14135 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
14136 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
14137 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
14138 * color keying nor copies it. */
14139 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
14140 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
14141 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14142 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
14143 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
14144 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
14145 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
14146 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
14147 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
14148 color
[0], color
[1], color
[2], color
[3], i
);
14149 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14150 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14153 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14154 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14155 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
14156 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14158 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14159 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14160 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14162 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14163 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14164 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14165 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
14166 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14168 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
14169 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
14170 hr
= IDirectDrawSurface4_GetSurfaceDesc(src
, &surface_desc
);
14171 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
14172 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
14173 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
14174 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
14175 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
14177 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
14178 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14179 ckey
.dwColorSpaceHighValue
= 0x00000000;
14180 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14181 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14183 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14184 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14185 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14186 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14187 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14189 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14190 ckey
.dwColorSpaceHighValue
= 0x00000001;
14191 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14192 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14194 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14195 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14196 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14197 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
14198 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14200 ckey
.dwColorSpaceLowValue
= 0x000000fe;
14201 ckey
.dwColorSpaceHighValue
= 0x000000fd;
14202 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14203 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14205 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
14206 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14207 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
14208 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
14209 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
14211 IDirectDrawSurface4_Release(src
);
14212 IDirectDrawSurface4_Release(dst
);
14214 /* Test source and destination keys and where they are read from. Use a surface with alpha
14215 * to avoid driver-dependent content in the X channel. */
14216 memset(&surface_desc
, 0, sizeof(surface_desc
));
14217 surface_desc
.dwSize
= sizeof(surface_desc
);
14218 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
14219 surface_desc
.dwWidth
= 6;
14220 surface_desc
.dwHeight
= 1;
14221 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
14222 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
14223 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
14224 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
14225 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
14226 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
14227 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
14228 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
14229 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14230 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
14231 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
14233 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
14234 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
14235 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
14236 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14237 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
14238 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
14239 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
14240 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
14243 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
14244 skip("Failed to set destination color key, skipping related tests.\n");
14248 ckey
.dwColorSpaceLowValue
= 0x000000ff;
14249 ckey
.dwColorSpaceHighValue
= 0x000000ff;
14250 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
14251 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14252 ckey
.dwColorSpaceLowValue
= 0x000000aa;
14253 ckey
.dwColorSpaceHighValue
= 0x000000aa;
14254 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
14255 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14257 memset(&fx
, 0, sizeof(fx
));
14258 fx
.dwSize
= sizeof(fx
);
14259 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
14260 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
14261 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
14262 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
14264 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14265 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14266 color
= surface_desc
.lpSurface
;
14267 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
14268 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
14269 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
14270 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
14271 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
14272 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
14273 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
14274 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14276 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14277 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14278 color
= surface_desc
.lpSurface
;
14279 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14280 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14281 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14283 /* Test a blit without keying. */
14284 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
14285 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14287 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14288 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14289 color
= surface_desc
.lpSurface
;
14290 /* Should have copied src data unmodified to dst. */
14291 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14292 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14293 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14294 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14296 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14297 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14298 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14301 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
14302 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14304 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14305 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14306 color
= surface_desc
.lpSurface
;
14307 /* Src key applied to color[0]. It is unmodified, the others are copied. */
14308 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14309 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14310 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14311 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14313 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14314 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14315 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14317 /* Src override. */
14318 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
14319 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14321 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14322 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14323 color
= surface_desc
.lpSurface
;
14324 /* Override key applied to color[5]. It is unmodified, the others are copied. */
14325 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14326 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
14327 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14328 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14330 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
14331 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14332 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14334 /* Src override AND src key. That is not supposed to work. */
14335 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
14336 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14338 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14339 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14340 color
= surface_desc
.lpSurface
;
14341 /* Ensure the destination was not changed. */
14342 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
14343 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
14344 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14345 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14347 /* Use different dst colors for the dst key test. */
14348 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14349 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14350 color
[2] = 0x00001100; /* Dest key in override. */
14351 color
[3] = 0x00001100; /* Dest key in override. */
14352 color
[4] = 0x000000aa; /* Dest key in src surface. */
14353 color
[5] = 0x000000aa; /* Dest key in src surface. */
14354 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14355 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14357 /* Dest key blit. The key is taken from the DESTINATION surface in v4! */
14358 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14359 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14361 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14362 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14363 color
= surface_desc
.lpSurface
;
14364 /* Dst key applied to color[0,1], they are the only changed pixels. */
14365 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
14366 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14367 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14368 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14370 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14371 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14372 color
[2] = 0x00001100; /* Dest key in override. */
14373 color
[3] = 0x00001100; /* Dest key in override. */
14374 color
[4] = 0x000000aa; /* Dest key in src surface. */
14375 color
[5] = 0x000000aa; /* Dest key in src surface. */
14376 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14377 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14379 /* What happens with a QI'd older version of the interface? It takes the key
14380 * from the source surface. */
14381 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
14382 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14383 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
14384 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
14386 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
14387 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14389 IDirectDrawSurface_Release(dst1
);
14390 IDirectDrawSurface_Release(src1
);
14392 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14393 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14394 color
= surface_desc
.lpSurface
;
14395 /* Dst key applied to color[4,5], they are the only changed pixels. */
14396 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14397 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14398 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14399 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14401 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14402 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14403 color
[2] = 0x00001100; /* Dest key in override. */
14404 color
[3] = 0x00001100; /* Dest key in override. */
14405 color
[4] = 0x000000aa; /* Dest key in src surface. */
14406 color
[5] = 0x000000aa; /* Dest key in src surface. */
14407 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
14408 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14410 /* Dest override key blit. */
14411 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
14412 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14414 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14415 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14416 color
= surface_desc
.lpSurface
;
14417 /* Dst key applied to color[2,3], they are the only changed pixels. */
14418 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
14419 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14420 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14421 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14423 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14424 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14425 color
[2] = 0x00001100; /* Dest key in override. */
14426 color
[3] = 0x00001100; /* Dest key in override. */
14427 color
[4] = 0x000000aa; /* Dest key in src surface. */
14428 color
[5] = 0x000000aa; /* Dest key in src surface. */
14429 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14430 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14432 /* Dest override together with surface key. Supposed to fail. */
14433 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
14434 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14436 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14437 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14438 color
= surface_desc
.lpSurface
;
14439 /* Destination is unchanged. */
14440 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
14441 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14442 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14443 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14444 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14445 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14447 /* Source and destination key. This is driver dependent. New HW treats it like
14448 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
14451 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
14452 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14454 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14455 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14456 color
= surface_desc
.lpSurface
;
14457 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
14458 * the driver applies it. */
14459 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
14460 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
14461 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14462 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14464 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
14465 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
14466 color
[2] = 0x00001100; /* Dest key in override. */
14467 color
[3] = 0x00001100; /* Dest key in override. */
14468 color
[4] = 0x000000aa; /* Dest key in src surface. */
14469 color
[5] = 0x000000aa; /* Dest key in src surface. */
14470 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14471 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14474 /* Override keys without ddbltfx parameter fail */
14475 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
14476 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14477 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
14478 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14480 /* Try blitting without keys in the source surface. */
14481 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
14482 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14483 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
14484 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14486 /* That fails now. Do not bother to check that the data is unmodified. */
14487 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
14488 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14490 /* Dest key blit still works, the destination surface key is used in v4. */
14491 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14492 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
14494 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
14495 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14496 color
= surface_desc
.lpSurface
;
14497 /* Dst key applied to color[0,1], they are the only changed pixels. */
14498 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
14499 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
14500 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
14501 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
14502 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
14503 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14505 /* Try blitting without keys in the destination surface. */
14506 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
14507 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14508 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
14509 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
14511 /* This fails, as sanity would dictate. */
14512 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
14513 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
14516 IDirectDrawSurface4_Release(src
);
14517 IDirectDrawSurface4_Release(dst
);
14518 refcount
= IDirectDraw4_Release(ddraw
);
14519 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
14520 DestroyWindow(window
);
14523 static void test_vb_refcount(void)
14525 ULONG prev_d3d_refcount
, prev_device_refcount
;
14526 ULONG cur_d3d_refcount
, cur_device_refcount
;
14527 IDirect3DVertexBuffer
*vb
, *vb1
;
14528 IDirect3DVertexBuffer7
*vb7
;
14529 D3DVERTEXBUFFERDESC vb_desc
;
14530 IDirect3DDevice3
*device
;
14537 window
= create_window();
14538 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14540 skip("Failed to create a 3D device, skipping test.\n");
14541 DestroyWindow(window
);
14545 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14546 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14548 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
14549 prev_device_refcount
= get_refcount((IUnknown
*)device
);
14551 memset(&vb_desc
, 0, sizeof(vb_desc
));
14552 vb_desc
.dwSize
= sizeof(vb_desc
);
14553 vb_desc
.dwFVF
= D3DFVF_XYZ
;
14554 vb_desc
.dwNumVertices
= 4;
14555 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
14556 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14558 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
14559 cur_device_refcount
= get_refcount((IUnknown
*)device
);
14560 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %u to %u.\n",
14561 prev_d3d_refcount
, cur_d3d_refcount
);
14562 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %u to %u.\n",
14563 prev_device_refcount
, cur_device_refcount
);
14565 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
14566 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer, hr %#x.\n", hr
);
14567 IDirect3DVertexBuffer_Release(vb1
);
14569 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
14570 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer7 returned unexpected hr %#x.\n", hr
);
14572 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
14573 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#x.\n", hr
);
14574 ok((IUnknown
*)vb
== unk
,
14575 "IDirect3DVertexBuffer and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
14576 IUnknown_Release(unk
);
14578 refcount
= IDirect3DVertexBuffer_Release(vb
);
14579 ok(!refcount
, "Vertex buffer has %u references left.\n", refcount
);
14580 IDirect3D3_Release(d3d
);
14581 refcount
= IDirect3DDevice3_Release(device
);
14582 ok(!refcount
, "Device has %u references left.\n", refcount
);
14583 DestroyWindow(window
);
14586 static void test_compute_sphere_visibility(void)
14588 static D3DMATRIX proj_1
=
14590 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
14591 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
14592 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
14593 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
14595 static D3DMATRIX proj_2
=
14597 10.0f
, 0.0f
, 0.0f
, 0.0f
,
14598 0.0f
, 10.0f
, 0.0f
, 0.0f
,
14599 0.0f
, 0.0f
, 10.0f
, 0.0f
,
14600 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14602 static D3DMATRIX view_1
=
14604 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
14605 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
14606 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
14607 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
14609 static D3DMATRIX identity
=
14611 1.0f
, 0.0f
, 0.0f
, 0.0f
,
14612 0.0f
, 1.0f
, 0.0f
, 0.0f
,
14613 0.0f
, 0.0f
, 1.0f
, 0.0f
,
14614 0.0f
, 0.0f
, 0.0f
, 1.0f
,
14618 D3DMATRIX
*view
, *proj
;
14619 unsigned int sphere_count
;
14620 D3DVECTOR center
[3];
14621 D3DVALUE radius
[3];
14622 const DWORD expected
[3];
14627 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, {0x1555}},
14628 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
14629 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
14630 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
14631 {4.354097f
, 12.500704f
, 17.251318f
}, {0x154a, 0x1555, 0x1555}},
14632 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, {0x1555}, TRUE
},
14633 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, {0x1401}},
14634 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, {0x401}},
14635 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, {0x1505}, TRUE
}, /* 5 */
14636 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x154a}},
14637 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x1562}},
14638 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, {0x1616}},
14639 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, {0x1496}},
14640 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, {0x956}}, /* 10 */
14641 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, {0x2156}},
14643 IDirect3DViewport3
*viewport
;
14644 IDirect3DDevice3
*device
;
14651 window
= create_window();
14652 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14654 skip("Failed to create a 3D device, skipping test.\n");
14655 DestroyWindow(window
);
14659 viewport
= create_viewport(device
, 0, 0, 640, 480);
14660 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14661 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14663 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
14665 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14667 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
14668 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
14670 hr
= IDirect3DDevice3_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
14671 tests
[i
].sphere_count
, 0, result
);
14672 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14674 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
14675 todo_wine_if(tests
[i
].todo
)
14676 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#x, got %#x.\n",
14677 i
, j
, tests
[i
].expected
[j
], result
[j
]);
14680 destroy_viewport(device
, viewport
);
14681 refcount
= IDirect3DDevice3_Release(device
);
14682 ok(!refcount
, "Device has %u references left.\n", refcount
);
14683 DestroyWindow(window
);
14686 static void test_texture_stages_limits(void)
14688 IDirectDrawSurface4
*surface
;
14689 DDSURFACEDESC2 surface_desc
;
14690 IDirect3DTexture2
*texture
;
14691 IDirect3DDevice3
*device
;
14692 IDirectDraw4
*ddraw
;
14699 window
= create_window();
14700 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14702 skip("Failed to create 3D device.\n");
14703 DestroyWindow(window
);
14706 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14707 ok(SUCCEEDED(hr
), "Failed to get Direct3D interface, hr %#x.\n", hr
);
14708 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14709 ok(SUCCEEDED(hr
), "Failed to get DirectDraw interface, hr %#x.\n", hr
);
14710 IDirect3D3_Release(d3d
);
14712 memset(&surface_desc
, 0, sizeof(surface_desc
));
14713 surface_desc
.dwSize
= sizeof(surface_desc
);
14714 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
14715 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
14716 surface_desc
.dwWidth
= 16;
14717 surface_desc
.dwHeight
= 16;
14718 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
14719 ok(hr
== DD_OK
, "Failed to create surface, hr %#x.\n", hr
);
14720 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
14721 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
14722 IDirectDrawSurface4_Release(surface
);
14724 for (i
= 0; i
< 8; ++i
)
14726 hr
= IDirect3DDevice3_SetTexture(device
, i
, texture
);
14727 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
14728 hr
= IDirect3DDevice3_SetTexture(device
, i
, NULL
);
14729 ok(hr
== D3D_OK
, "Failed to set texture %u, hr %#x.\n", i
, hr
);
14730 hr
= IDirect3DDevice3_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
14731 ok(hr
== D3D_OK
, "Failed to set texture stage state %u, hr %#x.\n", i
, hr
);
14734 IDirectDraw4_Release(ddraw
);
14735 IDirect3DTexture2_Release(texture
);
14736 refcount
= IDirect3DDevice3_Release(device
);
14737 ok(!refcount
, "Device has %u references left.\n", refcount
);
14738 DestroyWindow(window
);
14741 static void test_set_render_state(void)
14743 IDirect3DDevice3
*device
;
14749 window
= create_window();
14750 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14752 skip("Failed to create 3D device.\n");
14753 DestroyWindow(window
);
14757 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, TRUE
);
14758 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14759 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZVISIBLE
, FALSE
);
14760 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14762 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
14763 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14764 state
= 0xdeadbeef;
14765 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREHANDLE
, &state
);
14766 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14767 ok(!state
, "Got unexpected render state %#x.\n", state
);
14768 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
14769 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14770 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &state
);
14771 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14772 ok(state
== D3DTBLEND_MODULATE
, "Got unexpected render state %#x.\n", state
);
14774 refcount
= IDirect3DDevice3_Release(device
);
14775 ok(!refcount
, "Device has %u references left.\n", refcount
);
14776 DestroyWindow(window
);
14779 static void test_map_synchronisation(void)
14781 LARGE_INTEGER frequency
, diff
, ts
[3];
14782 IDirect3DVertexBuffer
*buffer
;
14783 IDirect3DViewport3
*viewport
;
14784 unsigned int i
, j
, tri_count
;
14785 D3DVERTEXBUFFERDESC vb_desc
;
14786 IDirect3DDevice3
*device
;
14787 BOOL unsynchronised
, ret
;
14788 IDirectDrawSurface4
*rt
;
14795 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14797 /* DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE were introduced with
14798 * ddraw7 and are ignored in earlier versions. */
14799 static const struct
14801 unsigned int flags
;
14802 BOOL unsynchronised
;
14807 {DDLOCK_NOOVERWRITE
, FALSE
},
14808 {DDLOCK_DISCARDCONTENTS
, FALSE
},
14809 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, FALSE
},
14812 static const struct quad
14816 struct vec3 position
;
14823 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
14824 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14825 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
14826 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
14832 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14833 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14834 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14835 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14838 struct quad
*quads
;
14840 window
= create_window();
14841 ok(!!window
, "Failed to create a window.\n");
14843 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14845 skip("Failed to create a D3D device, skipping tests.\n");
14846 DestroyWindow(window
);
14850 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14851 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14853 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14854 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14855 viewport
= create_viewport(device
, 0, 0, 640, 480);
14856 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14857 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14859 tri_count
= 0x1000;
14861 ret
= QueryPerformanceFrequency(&frequency
);
14862 ok(ret
, "Failed to get performance counter frequency.\n");
14864 vb_desc
.dwSize
= sizeof(vb_desc
);
14865 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
14866 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
14867 vb_desc
.dwNumVertices
= tri_count
+ 2;
14868 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14869 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14870 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14871 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14872 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14876 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14877 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14879 /* Initial draw to initialise states, compile shaders, etc. */
14880 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14881 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14882 hr
= IDirect3DDevice3_BeginScene(device
);
14883 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14884 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14885 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14886 hr
= IDirect3DDevice3_EndScene(device
);
14887 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14888 /* Read the result to ensure the GPU has finished drawing. */
14889 colour
= get_surface_color(rt
, 320, 240);
14891 /* Time drawing tri_count triangles. */
14892 ret
= QueryPerformanceCounter(&ts
[0]);
14893 ok(ret
, "Failed to read performance counter.\n");
14894 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14895 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14896 hr
= IDirect3DDevice3_BeginScene(device
);
14897 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14898 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14899 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14900 hr
= IDirect3DDevice3_EndScene(device
);
14901 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14902 colour
= get_surface_color(rt
, 320, 240);
14903 /* Time drawing a single triangle. */
14904 ret
= QueryPerformanceCounter(&ts
[1]);
14905 ok(ret
, "Failed to read performance counter.\n");
14906 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14907 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14908 hr
= IDirect3DDevice3_BeginScene(device
);
14909 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14910 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
14911 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14912 hr
= IDirect3DDevice3_EndScene(device
);
14913 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14914 colour
= get_surface_color(rt
, 320, 240);
14915 ret
= QueryPerformanceCounter(&ts
[2]);
14916 ok(ret
, "Failed to read performance counter.\n");
14918 IDirect3DVertexBuffer_Release(buffer
);
14920 /* Estimate the number of triangles we can draw in 100ms. */
14921 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
14922 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
14923 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
14924 vb_desc
.dwNumVertices
= tri_count
+ 2;
14926 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14928 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14929 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14930 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14931 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14932 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14936 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14937 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14939 /* Start a draw operation. */
14940 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14941 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14942 hr
= IDirect3DDevice3_BeginScene(device
);
14943 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14944 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14945 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14946 hr
= IDirect3DDevice3_EndScene(device
);
14947 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14949 /* Map the last quad while the draw is in progress. */
14950 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
14951 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14952 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
14953 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14954 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14956 colour
= get_surface_color(rt
, 320, 240);
14957 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
14958 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
14959 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
14961 IDirect3DVertexBuffer_Release(buffer
);
14964 destroy_viewport(device
, viewport
);
14965 IDirectDrawSurface4_Release(rt
);
14966 IDirect3D3_Release(d3d
);
14967 refcount
= IDirect3DDevice3_Release(device
);
14968 ok(!refcount
, "Device has %u references left.\n", refcount
);
14969 DestroyWindow(window
);
14972 static void test_depth_readback(void)
14974 DWORD depth
, expected_depth
, max_diff
, passed_fmts
= 0;
14975 IDirectDrawSurface4
*rt
, *ds
;
14976 IDirect3DViewport3
*viewport
;
14977 DDSURFACEDESC2 surface_desc
;
14978 IDirect3DDevice3
*device
;
14979 unsigned int i
, x
, y
;
14980 IDirectDraw4
*ddraw
;
14988 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14991 struct vec3 position
;
14996 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
14997 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14998 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
14999 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
15002 static const struct
15004 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
15009 {16, 0, 0x0000ffff, 0x00000000},
15010 {24, 0, 0x00ffffff, 0x00000000},
15011 {32, 0, 0x00ffffff, 0x00000000},
15012 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
15013 {32, 0, 0xffffffff, 0x00000000},
15016 window
= create_window();
15017 ok(!!window
, "Failed to create a window.\n");
15019 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15021 skip("Failed to create a D3D device, skipping tests.\n");
15022 DestroyWindow(window
);
15026 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15027 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
15028 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
15029 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15031 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
15032 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15033 viewport
= create_viewport(device
, 0, 0, 640, 480);
15034 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15035 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
15037 ds
= get_depth_stencil(device
);
15038 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
15039 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15040 IDirectDrawSurface4_Release(ds
);
15042 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15044 memset(&surface_desc
, 0, sizeof(surface_desc
));
15045 surface_desc
.dwSize
= sizeof(surface_desc
);
15046 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
15047 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
15048 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
15049 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
15050 if (tests
[i
].s_depth
)
15051 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
15052 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
15053 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
15054 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
15055 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
15056 surface_desc
.dwWidth
= 640;
15057 surface_desc
.dwHeight
= 480;
15058 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
15061 skip("Format %u not supported, skipping test.\n", i
);
15065 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
15066 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
15067 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
15068 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
15070 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
15071 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
15072 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15073 hr
= IDirect3DDevice3_BeginScene(device
);
15074 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
15075 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
15076 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
15077 hr
= IDirect3DDevice3_EndScene(device
);
15078 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
15081 for (y
= 60; y
< 480; y
+= 120)
15083 for (x
= 80; x
< 640; x
+= 160)
15085 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
15086 memset(&surface_desc
, 0, sizeof(surface_desc
));
15087 surface_desc
.dwSize
= sizeof(surface_desc
);
15088 hr
= IDirectDrawSurface4_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
15089 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
15091 depth
= *((DWORD
*)surface_desc
.lpSurface
) & tests
[i
].z_mask
;
15092 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
15093 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
15094 /* The ddraw4 version of this test behaves similarly to the ddraw7 version on Nvidia GPUs,
15095 * except that Geforce 7 also returns garbage data in D24S8, whereas the ddraw7 version
15096 * returns 0 for that format. Give up on pre-filtering formats, accept Nvidia as generally
15097 * broken here, but still expect at least one format (D16 or D24X8 in practise) to pass. */
15098 todo_wine_if(tests
[i
].todo
)
15099 ok(abs(expected_depth
- depth
) <= max_diff
|| ddraw_is_nvidia(ddraw
),
15100 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
15101 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
15102 if (abs(expected_depth
- depth
) > max_diff
)
15105 hr
= IDirectDrawSurface4_Unlock(ds
, &r
);
15106 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
15113 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
15114 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
15115 IDirectDrawSurface4_Release(ds
);
15118 ok(passed_fmts
, "Not a single format passed the tests, this is bad even by Nvidia's standards.\n");
15120 destroy_viewport(device
, viewport
);
15121 IDirectDrawSurface4_Release(rt
);
15122 IDirectDraw4_Release(ddraw
);
15123 IDirect3D3_Release(d3d
);
15124 refcount
= IDirect3DDevice3_Release(device
);
15125 ok(!refcount
, "Device has %u references left.\n", refcount
);
15126 DestroyWindow(window
);
15129 static void test_clear(void)
15131 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
15132 IDirect3DViewport3
*viewport
, *viewport2
, *viewport3
;
15133 IDirect3DDevice3
*device
;
15134 IDirectDrawSurface4
*rt
;
15135 IDirectDraw4
*ddraw
;
15143 window
= create_window();
15144 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15146 skip("Failed to create 3D device.\n");
15147 DestroyWindow(window
);
15151 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15152 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
15153 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
15154 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15156 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
15157 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15159 viewport
= create_viewport(device
, 0, 0, 640, 480);
15160 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15161 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
15163 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
15164 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15166 /* Positive x, negative y. */
15167 U1(rect
[0]).x1
= 0;
15168 U2(rect
[0]).y1
= 480;
15169 U3(rect
[0]).x2
= 320;
15170 U4(rect
[0]).y2
= 240;
15172 /* Positive x, positive y. */
15173 U1(rect
[1]).x1
= 0;
15174 U2(rect
[1]).y1
= 0;
15175 U3(rect
[1]).x2
= 320;
15176 U4(rect
[1]).y2
= 240;
15178 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
15179 * refuse negative rectangles, but it will not clear them either. */
15180 hr
= IDirect3DViewport3_Clear2(viewport
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
15181 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15183 color
= get_surface_color(rt
, 160, 360);
15184 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
15185 color
= get_surface_color(rt
, 160, 120);
15186 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
15187 color
= get_surface_color(rt
, 480, 360);
15188 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
15189 color
= get_surface_color(rt
, 480, 120);
15190 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
15192 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
15193 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15194 /* negative x, negative y.
15195 * Also ignored, except on WARP, which clears the entire screen. */
15196 U1(rect_negneg
).x1
= 640;
15197 U2(rect_negneg
).y1
= 240;
15198 U3(rect_negneg
).x2
= 320;
15199 U4(rect_negneg
).y2
= 0;
15200 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15201 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15203 color
= get_surface_color(rt
, 160, 360);
15204 ok(compare_color(color
, 0x00ffffff, 0)
15205 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15206 "Got unexpected color 0x%08x.\n", color
);
15207 color
= get_surface_color(rt
, 160, 120);
15208 ok(compare_color(color
, 0x00ffffff, 0)
15209 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15210 "Got unexpected color 0x%08x.\n", color
);
15211 color
= get_surface_color(rt
, 480, 360);
15212 ok(compare_color(color
, 0x00ffffff, 0)
15213 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15214 "Got unexpected color 0x%08x.\n", color
);
15215 color
= get_surface_color(rt
, 480, 120);
15216 ok(compare_color(color
, 0x00ffffff, 0)
15217 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
15218 "Got unexpected color 0x%08x.\n", color
);
15220 /* Test how the viewport affects clears. */
15221 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15222 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15224 viewport2
= create_viewport(device
, 160, 120, 160, 120);
15225 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport2
);
15226 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
15228 hr
= IDirect3DViewport3_Clear2(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
15229 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15231 viewport3
= create_viewport(device
, 320, 240, 320, 240);
15232 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
15233 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
15235 U1(rect
[0]).x1
= 160;
15236 U2(rect
[0]).y1
= 120;
15237 U3(rect
[0]).x2
= 480;
15238 U4(rect
[0]).y2
= 360;
15239 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15240 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15242 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15243 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
15245 color
= get_surface_color(rt
, 158, 118);
15246 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
15247 color
= get_surface_color(rt
, 162, 118);
15248 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
15249 color
= get_surface_color(rt
, 158, 122);
15250 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
15251 color
= get_surface_color(rt
, 162, 122);
15252 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
15254 color
= get_surface_color(rt
, 318, 238);
15255 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
15256 color
= get_surface_color(rt
, 322, 238);
15257 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
15258 color
= get_surface_color(rt
, 318, 242);
15259 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
15260 color
= get_surface_color(rt
, 322, 242);
15261 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
15263 color
= get_surface_color(rt
, 478, 358);
15264 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
15265 color
= get_surface_color(rt
, 482, 358);
15266 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
15267 color
= get_surface_color(rt
, 478, 362);
15268 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
15269 color
= get_surface_color(rt
, 482, 362);
15270 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
15272 /* The clear rectangle is rendertarget absolute, not relative to the
15274 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15275 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15276 U1(rect
[0]).x1
= 330;
15277 U2(rect
[0]).y1
= 250;
15278 U3(rect
[0]).x2
= 340;
15279 U4(rect
[0]).y2
= 260;
15280 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
15281 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
15283 color
= get_surface_color(rt
, 328, 248);
15284 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
15285 color
= get_surface_color(rt
, 332, 248);
15286 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
15287 color
= get_surface_color(rt
, 328, 252);
15288 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
15289 color
= get_surface_color(rt
, 332, 252);
15290 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
15292 color
= get_surface_color(rt
, 338, 248);
15293 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
15294 color
= get_surface_color(rt
, 342, 248);
15295 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
15296 color
= get_surface_color(rt
, 338, 252);
15297 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
15298 color
= get_surface_color(rt
, 342, 252);
15299 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
15301 color
= get_surface_color(rt
, 328, 258);
15302 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
15303 color
= get_surface_color(rt
, 332, 258);
15304 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
15305 color
= get_surface_color(rt
, 328, 262);
15306 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
15307 color
= get_surface_color(rt
, 332, 262);
15308 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
15310 color
= get_surface_color(rt
, 338, 258);
15311 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
15312 color
= get_surface_color(rt
, 342, 258);
15313 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
15314 color
= get_surface_color(rt
, 338, 262);
15315 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
15316 color
= get_surface_color(rt
, 342, 262);
15317 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
15319 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
15322 IDirect3DViewport3_Release(viewport3
);
15323 IDirect3DViewport3_Release(viewport2
);
15324 IDirect3DViewport3_Release(viewport
);
15325 IDirectDrawSurface4_Release(rt
);
15326 IDirectDraw4_Release(ddraw
);
15327 IDirect3D3_Release(d3d
);
15328 refcount
= IDirect3DDevice3_Release(device
);
15329 ok(!refcount
, "Device has %u references left.\n", refcount
);
15330 DestroyWindow(window
);
15333 struct enum_surfaces_param
15335 IDirectDrawSurface4
*surfaces
[8];
15336 unsigned int count
;
15339 static HRESULT WINAPI
enum_surfaces_cb(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
15341 struct enum_surfaces_param
*param
= context
;
15342 BOOL found
= FALSE
;
15345 for (i
= 0; i
< ARRAY_SIZE(param
->surfaces
); ++i
)
15347 if (param
->surfaces
[i
] == surface
)
15354 ok(found
, "Unexpected surface %p enumerated.\n", surface
);
15355 IDirectDrawSurface4_Release(surface
);
15358 return DDENUMRET_OK
;
15361 static void test_enum_surfaces(void)
15363 struct enum_surfaces_param param
= {{0}};
15364 DDSURFACEDESC2 desc
;
15365 IDirectDraw4
*ddraw
;
15368 ddraw
= create_ddraw();
15369 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15371 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
15372 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
15374 memset(&desc
, 0, sizeof(desc
));
15375 desc
.dwSize
= sizeof(desc
);
15376 desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
15377 desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
15378 U2(desc
).dwMipMapCount
= 3;
15380 desc
.dwHeight
= 32;
15381 hr
= IDirectDraw4_CreateSurface(ddraw
, &desc
, ¶m
.surfaces
[0], NULL
);
15382 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
15384 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[0], &desc
.ddsCaps
, ¶m
.surfaces
[1]);
15385 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
15386 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[1], &desc
.ddsCaps
, ¶m
.surfaces
[2]);
15387 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
15388 hr
= IDirectDrawSurface4_GetAttachedSurface(param
.surfaces
[2], &desc
.ddsCaps
, ¶m
.surfaces
[3]);
15389 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
15390 ok(!param
.surfaces
[3], "Got unexpected pointer %p.\n", param
.surfaces
[3]);
15392 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
15393 &desc
, ¶m
, enum_surfaces_cb
);
15394 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
15395 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15398 hr
= IDirectDraw4_EnumSurfaces(ddraw
, DDENUMSURFACES_DOESEXIST
| DDENUMSURFACES_ALL
,
15399 NULL
, ¶m
, enum_surfaces_cb
);
15400 ok(SUCCEEDED(hr
), "Failed to enumerate surfaces, hr %#x.\n", hr
);
15401 ok(param
.count
== 3, "Got unexpected number of enumerated surfaces %u.\n", param
.count
);
15403 IDirectDrawSurface4_Release(param
.surfaces
[2]);
15404 IDirectDrawSurface4_Release(param
.surfaces
[1]);
15405 IDirectDrawSurface4_Release(param
.surfaces
[0]);
15406 IDirectDraw4_Release(ddraw
);
15409 static void test_viewport(void)
15414 RECT expected_rect
;
15415 const char *message
;
15419 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
15420 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
15421 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
15422 {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
15423 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
15424 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
15426 static const struct vec2 rt_sizes
[] =
15428 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
15430 static D3DMATRIX mat
=
15432 1.0f
, 0.0f
, 0.0f
, 0.0f
,
15433 0.0f
, 1.0f
, 0.0f
, 0.0f
,
15434 0.0f
, 0.0f
, 1.0f
, 0.0f
,
15435 0.0f
, 0.0f
, 0.0f
, 1.0f
,
15437 static struct vec3 quad
[] =
15439 {-1.5f
, -0.5f
, 0.1f
},
15440 {-1.5f
, 0.5f
, 0.1f
},
15441 { 0.5f
, -0.5f
, 0.1f
},
15442 { 0.5f
, 0.5f
, 0.1f
},
15444 IDirect3DViewport3
*viewport
, *full_viewport
;
15445 IDirectDrawSurface4
*rt
, *ds
;
15446 DDSURFACEDESC2 surface_desc
;
15447 IDirect3DDevice3
*device
;
15448 BOOL expected_failure
;
15449 IDirectDraw4
*ddraw
;
15450 DDPIXELFORMAT z_fmt
;
15451 D3DRECT clear_rect
;
15459 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
15460 0, 0, 640, 480, 0, 0, 0, 0);
15461 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15463 skip("Failed to create a 3D device, skipping test.\n");
15464 DestroyWindow(window
);
15468 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15469 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
15470 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
15471 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
15473 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
15474 ok(SUCCEEDED(hr
), "Failed to disable depth test, hr %#x.\n", hr
);
15475 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
15476 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
15478 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
15479 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
15480 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
15481 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
15482 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
15483 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
15485 ds
= get_depth_stencil(device
);
15486 memset(&surface_desc
, 0, sizeof(surface_desc
));
15487 surface_desc
.dwSize
= sizeof(surface_desc
);
15488 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds
, &surface_desc
);
15489 z_fmt
= U4(surface_desc
).ddpfPixelFormat
;
15491 for (i
= 0; i
< ARRAY_SIZE(rt_sizes
); ++i
)
15495 memset(&surface_desc
, 0, sizeof(surface_desc
));
15496 surface_desc
.dwSize
= sizeof(surface_desc
);
15497 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
15498 surface_desc
.dwWidth
= rt_sizes
[i
].x
;
15499 surface_desc
.dwHeight
= rt_sizes
[i
].y
;
15500 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
15501 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
15502 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x (i %u).\n", hr
, i
);
15504 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
15505 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
15506 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
15507 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
15508 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x (i %u).\n", hr
, i
);
15509 hr
= IDirectDrawSurface4_AddAttachedSurface(rt
, ds
);
15510 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x (i %u).\n", hr
, i
);
15512 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
15513 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
15517 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
15518 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
15521 full_viewport
= create_viewport(device
, 0, 0, rt_sizes
[i
].x
, rt_sizes
[i
].y
);
15523 U1(clear_rect
).x1
= U2(clear_rect
).y1
= 0;
15524 U3(clear_rect
).x2
= rt_sizes
[i
].x
;
15525 U4(clear_rect
).y2
= rt_sizes
[i
].y
;
15527 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
15529 expected_failure
= tests
[j
].vp
.dwX
+ tests
[j
].vp
.dwWidth
> rt_sizes
[i
].x
15530 || tests
[j
].vp
.dwY
+ tests
[j
].vp
.dwHeight
> rt_sizes
[i
].y
;
15532 hr
= IDirect3DViewport3_Clear2(full_viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff000000, 0.0f
, 0);
15533 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15535 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
15536 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15537 hr
= IDirect3DViewport3_SetViewport2(viewport
, NULL
);
15538 ok(hr
== E_INVALIDARG
, "Setting NULL viewport data returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
15539 memset(&vp
, 0, sizeof(vp
));
15540 vp
.dwSize
= sizeof(vp
);
15541 vp
.dwX
= tests
[j
].vp
.dwX
;
15542 vp
.dwY
= tests
[j
].vp
.dwY
;
15543 vp
.dwWidth
= tests
[j
].vp
.dwWidth
;
15544 vp
.dwHeight
= tests
[j
].vp
.dwHeight
;
15545 vp
.dvClipX
= -1.0f
;
15547 vp
.dvClipWidth
= 2.0f
;
15548 vp
.dvClipHeight
= 2.0f
;
15551 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
15552 ok(hr
== D3DERR_VIEWPORTHASNODEVICE
,
15553 "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
15554 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
15555 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15556 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
15557 if (expected_failure
)
15558 ok(hr
== E_INVALIDARG
,
15559 "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
15561 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15563 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15564 ok(SUCCEEDED(hr
), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15565 if (expected_failure
)
15567 destroy_viewport(device
, viewport
);
15571 hr
= IDirect3DDevice3_BeginScene(device
);
15572 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15573 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
15574 ok(SUCCEEDED(hr
), "Got unexpected hr %#x (i %u, j %u).\n", hr
, i
, j
);
15575 hr
= IDirect3DDevice3_EndScene(device
);
15576 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x (i %u, j %u).\n", hr
, i
, j
);
15578 check_rect(rt
, tests
[j
].expected_rect
, tests
[j
].message
);
15580 destroy_viewport(device
, viewport
);
15583 destroy_viewport(device
, full_viewport
);
15585 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
15586 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x (i %u).\n", hr
, i
);
15587 IDirectDrawSurface4_Release(ds
);
15589 IDirectDrawSurface4_Release(rt
);
15592 refcount
= IDirect3DDevice3_Release(device
);
15593 ok(!refcount
, "Device has %u references left.\n", refcount
);
15594 IDirect3D3_Release(d3d
);
15595 IDirectDraw4_Release(ddraw
);
15596 DestroyWindow(window
);
15599 static void test_find_device(void)
15601 D3DFINDDEVICESEARCH search
= {0};
15602 D3DFINDDEVICERESULT result
= {0};
15603 IDirect3DDevice3
*device
;
15604 IDirectDraw4
*ddraw
;
15614 D3DDEVICEDESC_V1 hw_desc
;
15615 D3DDEVICEDESC_V1 sw_desc
;
15622 D3DDEVICEDESC_V2 hw_desc
;
15623 D3DDEVICEDESC_V2 sw_desc
;
15626 static const struct
15633 {&IID_IDirect3D
, DDERR_NOTFOUND
},
15634 {&IID_IDirect3DRampDevice
, DDERR_NOTFOUND
},
15635 {&IID_IDirect3DRGBDevice
, D3D_OK
},
15636 {&IID_IDirect3DMMXDevice
, DDERR_NOTFOUND
},
15637 {&IID_IDirect3DRefDevice
, DDERR_NOTFOUND
},
15638 {&IID_IDirect3DTnLHalDevice
, DDERR_NOTFOUND
},
15639 {&IID_IDirect3DNullDevice
, DDERR_NOTFOUND
},
15642 ddraw
= create_ddraw();
15643 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15645 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
15647 skip("D3D interface is not available, skipping test.\n");
15648 IDirectDraw4_Release(ddraw
);
15652 result
.dwSize
= sizeof(result
);
15653 search
.dwSize
= sizeof(search
);
15654 hr
= IDirect3D3_FindDevice(d3d
, NULL
, NULL
);
15655 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15656 hr
= IDirect3D3_FindDevice(d3d
, NULL
, &result
);
15657 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15658 hr
= IDirect3D3_FindDevice(d3d
, &search
, NULL
);
15659 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15660 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15661 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15662 ok(result
.dwSize
== sizeof(result
), "Got unexpected result size %u.\n", result
.dwSize
);
15663 ok(result
.ddHwDesc
.dwSize
== sizeof(result
.ddHwDesc
),
15664 "Got unexpected HW desc size %u.\n", result
.ddHwDesc
.dwSize
);
15665 ok(result
.ddSwDesc
.dwSize
== sizeof(result
.ddSwDesc
),
15666 "Got unexpected SW desc size %u.\n", result
.ddSwDesc
.dwSize
);
15668 memset(&search
, 0, sizeof(search
));
15669 memset(&result
, 0, sizeof(result
));
15670 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15671 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15673 search
.dwSize
= sizeof(search
) + 1;
15674 result
.dwSize
= sizeof(result
) + 1;
15675 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15676 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
15678 search
.dwSize
= sizeof(search
);
15680 memset(&result_v1
, 0, sizeof(result_v1
));
15681 result_v1
.size
= sizeof(result_v1
);
15682 hr
= IDirect3D3_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v1
);
15683 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15684 ok(result_v1
.hw_desc
.dwSize
== sizeof(result
.ddHwDesc
),
15685 "Got unexpected HW desc size %u.\n", result_v1
.hw_desc
.dwSize
);
15686 ok(result_v1
.sw_desc
.dwSize
== sizeof(result
.ddSwDesc
),
15687 "Got unexpected SW desc size %u.\n", result_v1
.sw_desc
.dwSize
);
15689 memset(&result_v2
, 0, sizeof(result_v2
));
15690 result_v2
.size
= sizeof(result_v2
);
15691 hr
= IDirect3D3_FindDevice(d3d
, &search
, (D3DFINDDEVICERESULT
*)&result_v2
);
15692 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15693 ok(result_v2
.hw_desc
.dwSize
== sizeof(result
.ddHwDesc
),
15694 "Got unexpected HW desc size %u.\n", result_v2
.hw_desc
.dwSize
);
15695 ok(result_v2
.sw_desc
.dwSize
== sizeof(result
.ddSwDesc
),
15696 "Got unexpected SW desc size %u.\n", result_v2
.sw_desc
.dwSize
);
15698 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
15700 memset(&search
, 0, sizeof(search
));
15701 search
.dwSize
= sizeof(search
);
15702 search
.dwFlags
= D3DFDS_GUID
;
15703 search
.guid
= *tests
[i
].guid
;
15705 memset(&result
, 0, sizeof(result
));
15706 result
.dwSize
= sizeof(result
);
15708 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15709 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
15710 ok(result
.dwSize
== sizeof(result
), "Test %u: Got unexpected result size %u.\n", i
, result
.dwSize
);
15713 ok(result
.ddHwDesc
.dwSize
== sizeof(result
.ddHwDesc
),
15714 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
15715 ok(result
.ddSwDesc
.dwSize
== sizeof(result
.ddSwDesc
),
15716 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
15720 ok(!result
.ddHwDesc
.dwSize
,
15721 "Test %u: Got unexpected HW desc size %u.\n", i
, result
.ddHwDesc
.dwSize
);
15722 ok(!result
.ddSwDesc
.dwSize
,
15723 "Test %u: Got unexpected SW desc size %u.\n", i
, result
.ddSwDesc
.dwSize
);
15727 /* The HAL device can only be enumerated if hardware acceleration is present. */
15728 search
.dwSize
= sizeof(search
);
15729 search
.dwFlags
= D3DFDS_GUID
;
15730 search
.guid
= IID_IDirect3DHALDevice
;
15731 result
.dwSize
= sizeof(result
);
15732 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15734 window
= create_window();
15735 device
= create_device(window
, DDSCL_NORMAL
);
15737 ok(!!device
, "Failed to create a 3D device.\n");
15739 ok(!device
, "Succeeded to create a 3D device.\n");
15741 IDirect3DDevice3_Release(device
);
15742 DestroyWindow(window
);
15744 /* Curiously the colour model criteria seem to be ignored. */
15745 search
.dwSize
= sizeof(search
);
15746 search
.dwFlags
= D3DFDS_COLORMODEL
;
15747 search
.dcmColorModel
= 0xdeadbeef;
15748 result
.dwSize
= sizeof(result
);
15749 hr
= IDirect3D3_FindDevice(d3d
, &search
, &result
);
15750 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15752 IDirect3D3_Release(d3d
);
15753 IDirectDraw4_Release(ddraw
);
15756 static IDirectDraw4
*killfocus_ddraw
;
15757 static IDirectDrawSurface4
*killfocus_surface
;
15759 static LRESULT CALLBACK
killfocus_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
15763 if (message
== WM_KILLFOCUS
)
15765 ref
= IDirectDrawSurface4_Release(killfocus_surface
);
15766 ok(!ref
, "Unexpected surface refcount %u.\n", ref
);
15767 ref
= IDirectDraw4_Release(killfocus_ddraw
);
15768 ok(!ref
, "Unexpected ddraw refcount %u.\n", ref
);
15769 killfocus_ddraw
= NULL
;
15772 return DefWindowProcA(window
, message
, wparam
, lparam
);
15775 static void test_killfocus(void)
15777 DDSURFACEDESC2 surface_desc
;
15780 WNDCLASSA wc
= {0};
15782 wc
.lpfnWndProc
= killfocus_proc
;
15783 wc
.lpszClassName
= "ddraw_killfocus_wndproc_wc";
15784 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
15786 window
= CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW
,
15787 0, 0, 640, 480, 0, 0, 0, 0);
15789 killfocus_ddraw
= create_ddraw();
15790 ok(!!killfocus_ddraw
, "Failed to create a ddraw object.\n");
15792 hr
= IDirectDraw4_SetCooperativeLevel(killfocus_ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
15793 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
15795 memset(&surface_desc
, 0, sizeof(surface_desc
));
15796 surface_desc
.dwSize
= sizeof(surface_desc
);
15797 surface_desc
.dwFlags
= DDSD_CAPS
;
15798 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
15799 hr
= IDirectDraw7_CreateSurface(killfocus_ddraw
, &surface_desc
, &killfocus_surface
, NULL
);
15800 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
15802 SetForegroundWindow(GetDesktopWindow());
15803 ok(!killfocus_ddraw
, "WM_KILLFOCUS was not received.\n");
15805 DestroyWindow(window
);
15806 UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL
));
15809 static void test_sysmem_draw(void)
15811 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
15812 IDirectDrawSurface4
*rt
, *surface
;
15813 IDirect3DViewport3
*viewport
;
15814 DDSURFACEDESC2 surface_desc
;
15815 D3DVERTEXBUFFERDESC vb_desc
;
15816 IDirect3DTexture2
*texture
;
15817 IDirect3DVertexBuffer
*vb
;
15818 IDirect3DDevice3
*device
;
15819 IDirectDraw4
*ddraw
;
15827 static const struct
15829 struct vec3 position
;
15834 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
15835 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
15836 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
15837 {{ 0.0f
, 0.0f
, 0.0f
}, 0x00000000},
15838 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
15839 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
15840 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
15841 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
15843 static WORD indices
[] = {4, 5, 6, 7};
15845 window
= create_window();
15846 ok(!!window
, "Failed to create a window.\n");
15848 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
15850 skip("Failed to create a 3D device, skipping test.\n");
15851 DestroyWindow(window
);
15855 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
15856 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15857 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
15858 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15859 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
15860 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15862 viewport
= create_viewport(device
, 0, 0, 640, 480);
15863 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
15864 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15866 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
15867 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15869 vb_desc
.dwSize
= sizeof(vb_desc
);
15870 vb_desc
.dwCaps
= D3DVBCAPS_SYSTEMMEMORY
;
15871 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
15872 vb_desc
.dwNumVertices
= ARRAY_SIZE(quad
);
15873 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
15874 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15876 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, (void **)&data
, NULL
);
15877 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15878 memcpy(data
, quad
, sizeof(quad
));
15879 hr
= IDirect3DVertexBuffer_Unlock(vb
);
15880 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15882 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15883 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15885 hr
= IDirect3DDevice3_BeginScene(device
);
15886 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15887 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 4, 4, 0);
15888 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15889 hr
= IDirect3DDevice3_EndScene(device
);
15890 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15892 color
= get_surface_color(rt
, 320, 240);
15893 ok(compare_color(color
, 0x00007f7f, 1), "Got unexpected color 0x%08x.\n", color
);
15895 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15896 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15898 hr
= IDirect3DDevice3_BeginScene(device
);
15899 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15900 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
15901 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15902 hr
= IDirect3DDevice3_EndScene(device
);
15903 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15905 color
= get_surface_color(rt
, 320, 240);
15906 ok(compare_color(color
, 0x00007f7f, 1), "Got unexpected color 0x%08x.\n", color
);
15908 memset(&surface_desc
, 0, sizeof(surface_desc
));
15909 surface_desc
.dwSize
= sizeof(surface_desc
);
15910 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
15911 surface_desc
.dwHeight
= 2;
15912 surface_desc
.dwWidth
= 2;
15913 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
15914 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
15915 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
15916 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
15917 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
15918 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
15919 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
15920 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
15921 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
15922 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15923 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
15924 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15925 IDirectDrawSurface4_Release(surface
);
15926 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
15927 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15929 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
15930 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15932 hr
= IDirect3DDevice3_BeginScene(device
);
15933 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15934 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
15935 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
15936 hr
= IDirect3DDevice3_EndScene(device
);
15937 ok(hr
== D3D_OK
|| hr
== D3DERR_SCENE_END_FAILED
, "Got unexpected hr %#x.\n", hr
);
15939 IDirect3DTexture2_Release(texture
);
15940 IDirect3DVertexBuffer_Release(vb
);
15941 IDirect3DViewport3_Release(viewport
);
15942 IDirectDrawSurface4_Release(rt
);
15943 IDirectDraw4_Release(ddraw
);
15944 IDirect3D3_Release(d3d
);
15945 refcount
= IDirect3DDevice3_Release(device
);
15946 ok(!refcount
, "Device has %u references left.\n", refcount
);
15947 DestroyWindow(window
);
15950 static void test_gdi_surface(void)
15952 IDirectDrawSurface4
*primary
, *backbuffer
, *gdi_surface
;
15953 DDSCAPS2 caps
= {DDSCAPS_BACKBUFFER
, 0, 0, {0}};
15954 DDSURFACEDESC2 surface_desc
;
15955 IDirectDraw4
*ddraw
;
15960 window
= create_window();
15961 ddraw
= create_ddraw();
15962 ok(!!ddraw
, "Failed to create a ddraw object.\n");
15963 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
15964 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15966 /* Retrieving the GDI surface requires a primary surface to exist. */
15967 gdi_surface
= (void *)0xc0dec0de;
15968 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
15969 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
15970 ok(!gdi_surface
, "Got unexpected surface %p.\n", gdi_surface
);
15972 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
15973 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
15975 memset(&surface_desc
, 0, sizeof(surface_desc
));
15976 surface_desc
.dwSize
= sizeof(surface_desc
);
15977 surface_desc
.dwFlags
= DDSD_CAPS
;
15978 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
15979 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
15980 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15982 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
15983 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15984 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
15985 IDirectDrawSurface4_Release(gdi_surface
);
15987 /* Flipping to the GDI surface requires the primary surface to be
15989 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
15990 ok(hr
== DDERR_NOTFLIPPABLE
, "Got unexpected hr %#x.\n", hr
);
15992 IDirectDrawSurface4_Release(primary
);
15994 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
15995 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
15997 memset(&surface_desc
, 0, sizeof(surface_desc
));
15998 surface_desc
.dwSize
= sizeof(surface_desc
);
15999 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
16000 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
16001 U5(surface_desc
).dwBackBufferCount
= 1;
16002 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
16003 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16004 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &caps
, &backbuffer
);
16005 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16006 ok(backbuffer
!= primary
, "Got unexpected backbuffer %p.\n", backbuffer
);
16008 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
16009 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16010 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
16011 IDirectDrawSurface4_Release(gdi_surface
);
16013 hr
= IDirectDrawSurface4_Flip(primary
, NULL
, DDFLIP_WAIT
);
16014 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16015 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
16016 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16017 ok(gdi_surface
== backbuffer
|| broken(gdi_surface
== primary
),
16018 "Got unexpected surface %p, expected %p.\n", gdi_surface
, backbuffer
);
16019 IDirectDrawSurface4_Release(gdi_surface
);
16021 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
16022 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16024 hr
= IDirectDraw4_GetGDISurface(ddraw
, &gdi_surface
);
16025 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16026 ok(gdi_surface
== primary
, "Got unexpected surface %p, expected %p.\n", gdi_surface
, primary
);
16027 IDirectDrawSurface4_Release(gdi_surface
);
16029 hr
= IDirectDraw4_FlipToGDISurface(ddraw
);
16030 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16032 IDirectDrawSurface4_Release(backbuffer
);
16033 IDirectDrawSurface4_Release(primary
);
16035 refcount
= IDirectDraw4_Release(ddraw
);
16036 ok(!refcount
, "%u references left.\n", refcount
);
16037 DestroyWindow(window
);
16040 static void test_alphatest(void)
16042 #define ALPHATEST_PASSED 0x0000ff00
16043 #define ALPHATEST_FAILED 0x00ff0000
16044 D3DRECT rect_full
= {{0}, {0}, {640}, {480}};
16045 IDirect3DViewport3
*viewport
;
16046 IDirect3DDevice3
*device
;
16047 IDirectDrawSurface4
*rt
;
16055 static const struct
16058 D3DCOLOR color_less
;
16059 D3DCOLOR color_equal
;
16060 D3DCOLOR color_greater
;
16064 {D3DCMP_NEVER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
16065 {D3DCMP_LESS
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_FAILED
},
16066 {D3DCMP_EQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
16067 {D3DCMP_LESSEQUAL
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_FAILED
},
16068 {D3DCMP_GREATER
, ALPHATEST_FAILED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
16069 {D3DCMP_NOTEQUAL
, ALPHATEST_PASSED
, ALPHATEST_FAILED
, ALPHATEST_PASSED
},
16070 {D3DCMP_GREATEREQUAL
, ALPHATEST_FAILED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
16071 {D3DCMP_ALWAYS
, ALPHATEST_PASSED
, ALPHATEST_PASSED
, ALPHATEST_PASSED
},
16075 struct vec3 position
;
16080 {{-1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
16081 {{-1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
16082 {{ 1.0f
, -1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
16083 {{ 1.0f
, 1.0f
, 0.1f
}, ALPHATEST_PASSED
| 0x80000000},
16086 window
= create_window();
16087 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
16089 skip("Failed to create a 3D device.\n");
16090 DestroyWindow(window
);
16093 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
16094 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16096 viewport
= create_viewport(device
, 0, 0, 640, 480);
16097 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
16098 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16100 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
16101 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16102 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
16103 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16104 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
16105 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16106 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHATESTENABLE
, TRUE
);
16107 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16109 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
16111 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAFUNC
, test_data
[i
].func
);
16112 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16114 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
16115 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16116 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0x70);
16117 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16118 hr
= IDirect3DDevice3_BeginScene(device
);
16119 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16120 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
16121 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
16122 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16123 hr
= IDirect3DDevice3_EndScene(device
);
16124 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16125 color
= get_surface_color(rt
, 320, 240);
16126 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
16127 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
16128 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
16130 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, ALPHATEST_FAILED
, 0.0f
, 0);
16131 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16132 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, 0xff70);
16133 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16134 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHAREF
, &value
);
16135 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16136 ok(value
== 0xff70, "Got unexpected value %#x.\n", value
);
16137 hr
= IDirect3DDevice3_BeginScene(device
);
16138 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16139 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
16140 D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, ARRAY_SIZE(quad
), 0);
16141 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16142 hr
= IDirect3DDevice3_EndScene(device
);
16143 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
16144 color
= get_surface_color(rt
, 320, 240);
16145 ok(compare_color(color
, test_data
[i
].color_greater
, 0),
16146 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
16147 color
, test_data
[i
].color_greater
, test_data
[i
].func
);
16150 destroy_viewport(device
, viewport
);
16151 IDirectDrawSurface4_Release(rt
);
16152 refcount
= IDirect3DDevice3_Release(device
);
16153 ok(!refcount
, "Device has %u references left.\n", refcount
);
16154 DestroyWindow(window
);
16157 static void test_clipper_refcount(void)
16159 IDirectDrawSurface4
*surface
;
16160 IDirectDrawClipper
*clipper
, *clipper2
;
16161 DDSURFACEDESC2 surface_desc
;
16162 IDirectDraw4
*ddraw
;
16163 IDirectDraw
*ddraw1
;
16168 const IDirectDrawClipperVtbl
*orig_vtbl
;
16170 window
= create_window();
16171 ddraw
= create_ddraw();
16172 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16173 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
16174 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16176 memset(&surface_desc
, 0, sizeof(surface_desc
));
16177 surface_desc
.dwSize
= sizeof(surface_desc
);
16178 surface_desc
.dwFlags
= DDSD_CAPS
;
16179 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
16180 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
16181 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16183 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
16184 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
16185 refcount
= get_refcount((IUnknown
*)clipper
);
16186 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
16188 /* Show that clipper validation doesn't somehow happen through per-clipper vtable
16190 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper2
, NULL
);
16191 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
16192 ok(clipper
->lpVtbl
== clipper2
->lpVtbl
, "Got different clipper vtables %p and %p.\n",
16193 clipper
->lpVtbl
, clipper2
->lpVtbl
);
16194 orig_vtbl
= clipper
->lpVtbl
;
16195 IDirectDrawClipper_Release(clipper2
);
16197 /* Surfaces hold a reference to clippers. No surprises there. */
16198 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
16199 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
16200 refcount
= get_refcount((IUnknown
*)clipper
);
16201 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
16203 hr
= IDirectDrawSurface4_GetClipper(surface
, &clipper2
);
16204 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
16205 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
16206 refcount
= IDirectDrawClipper_Release(clipper2
);
16207 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
16209 hr
= IDirectDrawSurface4_SetClipper(surface
, NULL
);
16210 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
16211 refcount
= get_refcount((IUnknown
*)clipper
);
16212 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
16214 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
16215 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
16216 refcount
= get_refcount((IUnknown
*)clipper
);
16217 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
16219 refcount
= IDirectDrawSurface4_Release(surface
);
16220 ok(!refcount
, "%u references left.\n", refcount
);
16221 refcount
= get_refcount((IUnknown
*)clipper
);
16222 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
16224 /* SetClipper with an invalid pointer crashes. */
16226 /* Clipper methods work with a broken vtable, with the exception of Release. */
16227 clipper
->lpVtbl
= (void *)0xdeadbeef;
16228 refcount
= orig_vtbl
->AddRef(clipper
);
16229 todo_wine
ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
16230 refcount
= orig_vtbl
->Release(clipper
);
16231 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
16233 clipper
->lpVtbl
= orig_vtbl
;
16234 refcount
= orig_vtbl
->Release(clipper
);
16235 todo_wine
ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
16237 /* Fix the refcount difference because Wine did not increase the ref in the
16238 * AddRef call above. */
16241 refcount
= IDirectDrawClipper_Release(clipper
);
16242 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
16245 /* Steal the reference and see what happens - releasing the surface works fine.
16246 * The clipper is destroyed and not kept alive by a hidden refcount - trying to
16247 * release it after the GetClipper call is likely to crash, and certain to crash
16248 * if we allocate and zero as much heap memory as we can get. */
16249 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
16250 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16251 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
16252 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
16253 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
16254 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
16256 IDirectDrawClipper_Release(clipper
);
16257 IDirectDrawClipper_Release(clipper
);
16259 hr
= IDirectDrawSurface4_GetClipper(surface
, &clipper2
);
16260 ok(SUCCEEDED(hr
), "Failed to get clipper, hr %#x.\n", hr
);
16261 ok(clipper
== clipper2
, "Got clipper %p, expected %p.\n", clipper2
, clipper
);
16263 /* Show that invoking the Release method does not crash, but don't get the
16264 * vtable through the clipper pointer because it is no longer pointing to
16266 refcount
= orig_vtbl
->Release(clipper
);
16267 ok(!refcount
, "%u references left.\n", refcount
);
16269 refcount
= IDirectDrawSurface4_Release(surface
);
16270 ok(!refcount
, "%u references left.\n", refcount
);
16272 /* It looks like the protection against invalid thispointers is part of
16273 * the IDirectDrawClipper method implementation, not IDirectDrawSurface. */
16274 clipper
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 0x1000);
16275 ok(!!clipper
, "failed to allocate memory\n");
16277 /* Assigning the vtable to our fake clipper does NOT make a difference on
16278 * native - there is a different member of the clipper implementation struct
16279 * that is used to determine if a clipper is valid. */
16280 clipper
->lpVtbl
= orig_vtbl
;
16282 refcount
= orig_vtbl
->AddRef(clipper
);
16283 todo_wine
ok(!refcount
, "Got refcount %u.\n", refcount
);
16284 refcount
= orig_vtbl
->AddRef((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef);
16285 ok(!refcount
, "Got refcount %u.\n", refcount
);
16288 hr
= orig_vtbl
->IsClipListChanged(clipper
, &changed
);
16289 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16290 todo_wine
ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
16293 hr
= orig_vtbl
->IsClipListChanged((IDirectDrawClipper
*)(ULONG_PTR
)0xdeadbeef, &changed
);
16294 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16295 ok(changed
== 0x1234, "'changed' changed: %x.\n", changed
);
16297 /* Nope, we can't initialize our fake clipper. */
16298 hr
= IDirectDraw4_QueryInterface(ddraw
, &IID_IDirectDraw
, (void **)&ddraw1
);
16299 ok(SUCCEEDED(hr
), "Failed to get ddraw1 interface, hr %#x.\n", hr
);
16301 hr
= orig_vtbl
->Initialize(clipper
, ddraw1
, 0);
16302 todo_wine
ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
16304 IDirectDraw_Release(ddraw1
);
16306 HeapFree(GetProcessHeap(), 0, clipper
);
16308 refcount
= IDirectDraw4_Release(ddraw
);
16309 ok(!refcount
, "%u references left.\n", refcount
);
16310 DestroyWindow(window
);
16313 static void test_caps(void)
16315 DDCAPS hal_caps
, hel_caps
;
16316 IDirectDraw4
*ddraw
;
16319 ddraw
= create_ddraw();
16320 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16322 memset(&hal_caps
, 0, sizeof(hal_caps
));
16323 memset(&hel_caps
, 0, sizeof(hel_caps
));
16324 hal_caps
.dwSize
= sizeof(hal_caps
);
16325 hel_caps
.dwSize
= sizeof(hel_caps
);
16326 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
16327 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16328 ok(hal_caps
.ddsOldCaps
.dwCaps
== hal_caps
.ddsCaps
.dwCaps
,
16329 "Got unexpected caps %#x, expected %#x.\n",
16330 hal_caps
.ddsOldCaps
.dwCaps
, hal_caps
.ddsCaps
.dwCaps
);
16331 ok(hel_caps
.ddsOldCaps
.dwCaps
== hel_caps
.ddsCaps
.dwCaps
,
16332 "Got unexpected caps %#x, expected %#x.\n",
16333 hel_caps
.ddsOldCaps
.dwCaps
, hel_caps
.ddsCaps
.dwCaps
);
16335 IDirectDraw4_Release(ddraw
);
16338 static void test_d32_support(void)
16340 IDirectDrawSurface4
*surface
;
16341 DDSURFACEDESC2 surface_desc
;
16342 IDirectDraw4
*ddraw
;
16347 window
= create_window();
16348 ddraw
= create_ddraw();
16349 ok(!!ddraw
, "Failed to create a ddraw object.\n");
16350 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
16351 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16353 memset(&surface_desc
, 0, sizeof(surface_desc
));
16354 surface_desc
.dwSize
= sizeof(surface_desc
);
16355 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
16356 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
16357 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
16358 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
16359 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 32;
16360 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0xffffffff;
16361 surface_desc
.dwWidth
= 64;
16362 surface_desc
.dwHeight
= 64;
16363 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
16364 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16366 memset(&surface_desc
, 0, sizeof(surface_desc
));
16367 surface_desc
.dwSize
= sizeof(surface_desc
);
16368 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
16369 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
16370 ok((surface_desc
.dwFlags
& DDSD_PIXELFORMAT
), "Got unexpected flags %#x.\n", surface_desc
.dwFlags
);
16371 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
& DDPF_ZBUFFER
,
16372 "Got unexpected format flags %#x.\n", U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
16373 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
== 32,
16374 "Got unexpected dwZBufferBitDepth %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
);
16375 ok(U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
== 0xffffffff,
16376 "Got unexpected Z mask 0x%08x.\n", U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
);
16377 ok(!(surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
),
16378 "Got unexpected surface caps %#x.\n", surface_desc
.ddsCaps
.dwCaps
);
16379 IDirectDrawSurface4_Release(surface
);
16381 refcount
= IDirectDraw4_Release(ddraw
);
16382 ok(!refcount
, "%u references left.\n", refcount
);
16383 DestroyWindow(window
);
16388 DDDEVICEIDENTIFIER identifier
;
16389 DEVMODEW current_mode
;
16390 IDirectDraw4
*ddraw
;
16393 if (!(ddraw
= create_ddraw()))
16395 skip("Failed to create a ddraw object, skipping tests.\n");
16399 if (ddraw_get_identifier(ddraw
, &identifier
))
16401 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
16402 trace("Description string: \"%s\"\n", identifier
.szDescription
);
16403 trace("Driver version %d.%d.%d.%d\n",
16404 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
16405 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
16407 IDirectDraw4_Release(ddraw
);
16409 memset(¤t_mode
, 0, sizeof(current_mode
));
16410 current_mode
.dmSize
= sizeof(current_mode
);
16411 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
16412 registry_mode
.dmSize
= sizeof(registry_mode
);
16413 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
16414 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
16415 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
16417 skip("Current mode does not match registry mode, skipping test.\n");
16421 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
16422 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
16424 test_process_vertices();
16425 test_coop_level_create_device_window();
16426 test_clipper_blt();
16427 test_coop_level_d3d_state();
16428 test_surface_interface_mismatch();
16429 test_coop_level_threaded();
16431 test_texture_load_ckey();
16432 test_viewport_object();
16440 test_window_style();
16441 test_redundant_mode_set();
16442 test_coop_level_mode_set();
16443 test_coop_level_mode_set_multi();
16445 test_coop_level_surf_create();
16447 test_coop_level_multi_window();
16448 test_draw_strided();
16450 test_specular_lighting();
16451 test_clear_rect_count();
16452 test_coop_level_versions();
16453 test_lighting_interface_versions();
16454 test_coop_level_activateapp();
16455 test_texturemanage();
16456 test_block_formats_creation();
16457 test_unsupported_formats();
16459 test_primary_caps();
16460 test_surface_lock();
16461 test_surface_discard();
16463 test_set_surface_desc();
16464 test_user_memory_getdc();
16465 test_sysmem_overlay();
16466 test_primary_palette();
16467 test_surface_attachment();
16468 test_private_data();
16469 test_pixel_format();
16470 test_create_surface_pitch();
16472 test_palette_complex();
16475 test_palette_gdi();
16476 test_palette_alpha();
16477 test_vb_writeonly();
16478 test_lost_device();
16479 test_surface_desc_lock();
16480 test_texturemapblend();
16481 test_signed_formats();
16483 test_texcoordindex();
16484 test_colorkey_precision();
16485 test_range_colorkey();
16487 test_lockrect_invalid();
16488 test_yv12_overlay();
16489 test_offscreen_overlay();
16490 test_overlay_rect();
16492 test_blt_z_alpha();
16493 test_cross_device_blt();
16494 test_color_clamping();
16496 test_draw_primitive();
16497 test_edge_antialiasing_blending();
16498 test_transform_vertices();
16499 test_display_mode_surface_pixel_format();
16500 test_surface_desc_size();
16501 test_get_surface_from_dc();
16502 test_ck_operation();
16503 test_vb_refcount();
16504 test_compute_sphere_visibility();
16505 test_texture_stages_limits();
16506 test_set_render_state();
16507 test_map_synchronisation();
16508 test_depth_readback();
16510 test_enum_surfaces();
16512 test_find_device();
16514 test_sysmem_draw();
16515 test_gdi_surface();
16517 test_clipper_refcount();
16519 test_d32_support();