2 * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com)
3 * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
4 * Copyright 2011-2014 Henri Verbeet for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
27 HRESULT WINAPI
GetSurfaceFromDC(HDC dc
, struct IDirectDrawSurface
**surface
, HDC
*device_dc
);
29 static BOOL is_ddraw64
= sizeof(DWORD
) != sizeof(DWORD
*);
30 static DEVMODEW registry_mode
;
32 static HRESULT (WINAPI
*pDwmIsCompositionEnabled
)(BOOL
*);
35 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
53 struct create_window_thread_param
56 HANDLE window_created
;
57 HANDLE destroy_window
;
61 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
71 if (abs(x
- y
) > ulps
)
77 static BOOL
compare_vec4(const struct vec4
*vec
, float x
, float y
, float z
, float w
, unsigned int ulps
)
79 return compare_float(vec
->x
, x
, ulps
)
80 && compare_float(vec
->y
, y
, ulps
)
81 && compare_float(vec
->z
, z
, ulps
)
82 && compare_float(vec
->w
, w
, ulps
);
85 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
87 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
89 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
91 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
93 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
97 static BOOL
ddraw_get_identifier(IDirectDraw4
*ddraw
, DDDEVICEIDENTIFIER
*identifier
)
101 hr
= IDirectDraw4_GetDeviceIdentifier(ddraw
, identifier
, 0);
102 ok(SUCCEEDED(hr
), "Failed to get device identifier, hr %#x.\n", hr
);
104 return SUCCEEDED(hr
);
107 static BOOL
ddraw_is_warp(IDirectDraw4
*ddraw
)
109 DDDEVICEIDENTIFIER identifier
;
111 return strcmp(winetest_platform
, "wine")
112 && ddraw_get_identifier(ddraw
, &identifier
)
113 && strstr(identifier
.szDriver
, "warp");
116 static BOOL
ddraw_is_vendor(IDirectDraw4
*ddraw
, DWORD vendor
)
118 DDDEVICEIDENTIFIER identifier
;
120 return strcmp(winetest_platform
, "wine")
121 && ddraw_get_identifier(ddraw
, &identifier
)
122 && identifier
.dwVendorId
== vendor
;
125 static BOOL
ddraw_is_intel(IDirectDraw4
*ddraw
)
127 return ddraw_is_vendor(ddraw
, 0x8086);
130 static BOOL
ddraw_is_nvidia(IDirectDraw4
*ddraw
)
132 return ddraw_is_vendor(ddraw
, 0x10de);
135 static BOOL
ddraw_is_vmware(IDirectDraw4
*ddraw
)
137 return ddraw_is_vendor(ddraw
, 0x15ad);
140 static IDirectDrawSurface4
*create_overlay(IDirectDraw4
*ddraw
,
141 unsigned int width
, unsigned int height
, DWORD format
)
143 IDirectDrawSurface4
*surface
;
146 memset(&desc
, 0, sizeof(desc
));
147 desc
.dwSize
= sizeof(desc
);
148 desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
149 desc
.dwWidth
= width
;
150 desc
.dwHeight
= height
;
151 desc
.ddsCaps
.dwCaps
= DDSCAPS_OVERLAY
;
152 U4(desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(desc
).ddpfPixelFormat
);
153 U4(desc
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
154 U4(desc
).ddpfPixelFormat
.dwFourCC
= format
;
156 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &desc
, &surface
, NULL
)))
161 static HWND
create_window(void)
163 RECT r
= {0, 0, 640, 480};
165 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
167 return CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
168 CW_USEDEFAULT
, CW_USEDEFAULT
, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
171 static DWORD WINAPI
create_window_thread_proc(void *param
)
173 struct create_window_thread_param
*p
= param
;
177 p
->window
= create_window();
178 ret
= SetEvent(p
->window_created
);
179 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
185 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
186 DispatchMessageA(&msg
);
187 res
= WaitForSingleObject(p
->destroy_window
, 100);
188 if (res
== WAIT_OBJECT_0
)
190 if (res
!= WAIT_TIMEOUT
)
192 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
197 DestroyWindow(p
->window
);
202 static void create_window_thread(struct create_window_thread_param
*p
)
206 p
->window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
207 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
208 p
->destroy_window
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
209 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
210 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
211 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
212 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
213 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
216 static void destroy_window_thread(struct create_window_thread_param
*p
)
218 SetEvent(p
->destroy_window
);
219 WaitForSingleObject(p
->thread
, INFINITE
);
220 CloseHandle(p
->destroy_window
);
221 CloseHandle(p
->window_created
);
222 CloseHandle(p
->thread
);
225 static IDirectDrawSurface4
*get_depth_stencil(IDirect3DDevice3
*device
)
227 IDirectDrawSurface4
*rt
, *ret
;
228 DDSCAPS2 caps
= {DDSCAPS_ZBUFFER
, 0, 0, {0}};
231 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
232 ok(SUCCEEDED(hr
), "Failed to get the render target, hr %#x.\n", hr
);
233 hr
= IDirectDrawSurface4_GetAttachedSurface(rt
, &caps
, &ret
);
234 ok(SUCCEEDED(hr
) || hr
== DDERR_NOTFOUND
, "Failed to get the z buffer, hr %#x.\n", hr
);
235 IDirectDrawSurface4_Release(rt
);
239 static HRESULT
set_display_mode(IDirectDraw4
*ddraw
, DWORD width
, DWORD height
)
241 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
243 return IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0);
246 static D3DCOLOR
get_surface_color(IDirectDrawSurface4
*surface
, UINT x
, UINT y
)
248 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
249 DDSURFACEDESC2 surface_desc
;
253 memset(&surface_desc
, 0, sizeof(surface_desc
));
254 surface_desc
.dwSize
= sizeof(surface_desc
);
256 hr
= IDirectDrawSurface4_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
257 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
261 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
263 hr
= IDirectDrawSurface4_Unlock(surface
, &rect
);
264 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
269 static HRESULT CALLBACK
enum_z_fmt(DDPIXELFORMAT
*format
, void *ctx
)
271 DDPIXELFORMAT
*z_fmt
= ctx
;
273 if (U1(*format
).dwZBufferBitDepth
> U1(*z_fmt
).dwZBufferBitDepth
)
279 static IDirectDraw4
*create_ddraw(void)
281 IDirectDraw4
*ddraw4
;
285 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
288 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw4
, (void **)&ddraw4
);
289 IDirectDraw_Release(ddraw1
);
296 static IDirect3DDevice3
*create_device(HWND window
, DWORD coop_level
)
298 IDirectDrawSurface4
*surface
, *ds
;
299 IDirect3DDevice3
*device
= NULL
;
300 DDSURFACEDESC2 surface_desc
;
301 IDirectDraw4
*ddraw4
;
306 if (!(ddraw4
= create_ddraw()))
309 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, coop_level
);
310 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
312 memset(&surface_desc
, 0, sizeof(surface_desc
));
313 surface_desc
.dwSize
= sizeof(surface_desc
);
314 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
315 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
316 surface_desc
.dwWidth
= 640;
317 surface_desc
.dwHeight
= 480;
319 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &surface
, NULL
);
320 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
322 if (coop_level
& DDSCL_NORMAL
)
324 IDirectDrawClipper
*clipper
;
326 hr
= IDirectDraw4_CreateClipper(ddraw4
, 0, &clipper
, NULL
);
327 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
328 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
329 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
330 hr
= IDirectDrawSurface4_SetClipper(surface
, clipper
);
331 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
332 IDirectDrawClipper_Release(clipper
);
335 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirect3D3
, (void **)&d3d3
);
336 IDirectDraw4_Release(ddraw4
);
339 IDirectDrawSurface4_Release(surface
);
343 memset(&z_fmt
, 0, sizeof(z_fmt
));
344 hr
= IDirect3D3_EnumZBufferFormats(d3d3
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
345 if (FAILED(hr
) || !z_fmt
.dwSize
)
347 IDirect3D3_Release(d3d3
);
348 IDirectDrawSurface4_Release(surface
);
352 memset(&surface_desc
, 0, sizeof(surface_desc
));
353 surface_desc
.dwSize
= sizeof(surface_desc
);
354 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
355 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
356 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
357 surface_desc
.dwWidth
= 640;
358 surface_desc
.dwHeight
= 480;
359 hr
= IDirectDraw4_CreateSurface(ddraw4
, &surface_desc
, &ds
, NULL
);
360 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
363 IDirect3D3_Release(d3d3
);
364 IDirectDrawSurface4_Release(surface
);
368 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
369 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
370 IDirectDrawSurface4_Release(ds
);
373 IDirect3D3_Release(d3d3
);
374 IDirectDrawSurface4_Release(surface
);
378 hr
= IDirect3D3_CreateDevice(d3d3
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
379 IDirect3D3_Release(d3d3
);
380 IDirectDrawSurface4_Release(surface
);
387 static IDirect3DViewport3
*create_viewport(IDirect3DDevice3
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
389 IDirect3DViewport3
*viewport
;
394 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
395 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
396 hr
= IDirect3D3_CreateViewport(d3d
, &viewport
, NULL
);
397 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
398 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
399 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
400 memset(&vp
, 0, sizeof(vp
));
401 vp
.dwSize
= sizeof(vp
);
408 vp
.dvClipWidth
= 2.0f
;
409 vp
.dvClipHeight
= 2.0f
;
412 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp
);
413 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
414 IDirect3D3_Release(d3d
);
419 static void destroy_viewport(IDirect3DDevice3
*device
, IDirect3DViewport3
*viewport
)
423 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
424 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
425 IDirect3DViewport3_Release(viewport
);
428 static IDirect3DMaterial3
*create_material(IDirect3DDevice3
*device
, D3DMATERIAL
*mat
)
430 IDirect3DMaterial3
*material
;
434 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
435 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
436 hr
= IDirect3D3_CreateMaterial(d3d
, &material
, NULL
);
437 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
438 hr
= IDirect3DMaterial3_SetMaterial(material
, mat
);
439 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
440 IDirect3D3_Release(d3d
);
445 static IDirect3DMaterial3
*create_diffuse_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
449 memset(&mat
, 0, sizeof(mat
));
450 mat
.dwSize
= sizeof(mat
);
451 U1(U(mat
).diffuse
).r
= r
;
452 U2(U(mat
).diffuse
).g
= g
;
453 U3(U(mat
).diffuse
).b
= b
;
454 U4(U(mat
).diffuse
).a
= a
;
456 return create_material(device
, &mat
);
459 static IDirect3DMaterial3
*create_specular_material(IDirect3DDevice3
*device
,
460 float r
, float g
, float b
, float a
, float power
)
464 memset(&mat
, 0, sizeof(mat
));
465 mat
.dwSize
= sizeof(mat
);
466 U1(U2(mat
).specular
).r
= r
;
467 U2(U2(mat
).specular
).g
= g
;
468 U3(U2(mat
).specular
).b
= b
;
469 U4(U2(mat
).specular
).a
= a
;
470 U4(mat
).power
= power
;
472 return create_material(device
, &mat
);
475 static IDirect3DMaterial3
*create_emissive_material(IDirect3DDevice3
*device
, float r
, float g
, float b
, float a
)
479 memset(&mat
, 0, sizeof(mat
));
480 mat
.dwSize
= sizeof(mat
);
481 U1(U3(mat
).emissive
).r
= r
;
482 U2(U3(mat
).emissive
).g
= g
;
483 U3(U3(mat
).emissive
).b
= b
;
484 U4(U3(mat
).emissive
).a
= a
;
486 return create_material(device
, &mat
);
489 static void destroy_material(IDirect3DMaterial3
*material
)
491 IDirect3DMaterial3_Release(material
);
498 WPARAM expect_wparam
;
501 static const struct message
*expect_messages
;
503 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
505 if (expect_messages
&& message
== expect_messages
->message
)
507 if (expect_messages
->check_wparam
)
508 ok (wparam
== expect_messages
->expect_wparam
,
509 "Got unexpected wparam %lx for message %x, expected %lx.\n",
510 wparam
, message
, expect_messages
->expect_wparam
);
515 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
518 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
519 * interface. This prevents subsequent SetCooperativeLevel() calls on a
520 * different window from failing with DDERR_HWNDALREADYSET. */
521 static void fix_wndproc(HWND window
, LONG_PTR proc
)
526 if (!(ddraw
= create_ddraw()))
529 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
530 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
531 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
532 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
533 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
535 IDirectDraw4_Release(ddraw
);
538 static void test_process_vertices(void)
540 IDirect3DVertexBuffer
*src_vb
, *dst_vb
;
541 IDirect3DViewport3
*viewport
;
542 D3DVERTEXBUFFERDESC vb_desc
;
543 IDirect3DDevice3
*device
;
544 struct vec3
*src_data
;
545 struct vec4
*dst_data
;
552 static D3DMATRIX identity
=
554 1.0f
, 0.0f
, 0.0f
, 0.0f
,
555 0.0f
, 1.0f
, 0.0f
, 0.0f
,
556 0.0f
, 0.0f
, 1.0f
, 0.0f
,
557 0.0f
, 0.0f
, 0.0f
, 1.0f
,
559 static D3DMATRIX projection
=
561 1.0f
, 0.0f
, 0.0f
, 0.0f
,
562 0.0f
, 1.0f
, 0.0f
, 0.0f
,
563 0.0f
, 0.0f
, 1.0f
, 0.0f
,
564 6.0f
, 7.0f
, 8.0f
, 1.0f
,
567 window
= create_window();
568 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
570 skip("Failed to create a 3D device, skipping test.\n");
571 DestroyWindow(window
);
575 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d3
);
576 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
578 memset(&vb_desc
, 0, sizeof(vb_desc
));
579 vb_desc
.dwSize
= sizeof(vb_desc
);
580 vb_desc
.dwFVF
= D3DFVF_XYZ
;
581 vb_desc
.dwNumVertices
= 3;
582 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &src_vb
, 0, NULL
);
583 ok(SUCCEEDED(hr
), "Failed to create source vertex buffer, hr %#x.\n", hr
);
585 hr
= IDirect3DVertexBuffer_Lock(src_vb
, DDLOCK_WRITEONLY
, (void **)&src_data
, NULL
);
586 ok(SUCCEEDED(hr
), "Failed to lock source vertex buffer, hr %#x.\n", hr
);
587 src_data
[0].x
= -1.0f
;
588 src_data
[0].y
= -1.0f
;
589 src_data
[0].z
= -1.0f
;
590 src_data
[1].x
= 0.0f
;
591 src_data
[1].y
= 0.0f
;
592 src_data
[1].z
= 0.0f
;
593 src_data
[2].x
= 1.0f
;
594 src_data
[2].y
= 1.0f
;
595 src_data
[2].z
= 1.0f
;
596 hr
= IDirect3DVertexBuffer_Unlock(src_vb
);
597 ok(SUCCEEDED(hr
), "Failed to unlock source vertex buffer, hr %#x.\n", hr
);
599 memset(&vb_desc
, 0, sizeof(vb_desc
));
600 vb_desc
.dwSize
= sizeof(vb_desc
);
601 vb_desc
.dwFVF
= D3DFVF_XYZRHW
;
602 vb_desc
.dwNumVertices
= 3;
603 hr
= IDirect3D3_CreateVertexBuffer(d3d3
, &vb_desc
, &dst_vb
, 0, NULL
);
604 ok(SUCCEEDED(hr
), "Failed to create destination vertex buffer, hr %#x.\n", hr
);
606 hr
= IDirect3D3_CreateViewport(d3d3
, &viewport
, NULL
);
607 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
608 hr
= IDirect3DDevice3_AddViewport(device
, viewport
);
609 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
610 vp2
.dwSize
= sizeof(vp2
);
617 vp2
.dvClipWidth
= 4.0f
;
618 vp2
.dvClipHeight
= 5.0f
;
621 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
622 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
623 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
624 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
626 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
627 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
628 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &identity
);
629 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
630 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &identity
);
631 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
633 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
634 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
636 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
637 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
638 ok(compare_vec4(&dst_data
[0], -6.500e+1f
, +1.800e+2f
, +2.000e-1f
, +1.000e+0f
, 4096),
639 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
640 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
641 ok(compare_vec4(&dst_data
[1], -4.000e+1f
, +1.400e+2f
, +4.000e-1f
, +1.000e+0f
, 4096),
642 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
643 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
644 ok(compare_vec4(&dst_data
[2], -1.500e+1f
, +1.000e+2f
, +6.000e-1f
, +1.000e+0f
, 4096),
645 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
646 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
647 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
648 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
650 hr
= IDirect3DDevice3_MultiplyTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &projection
);
651 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
653 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
654 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
656 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
657 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
658 ok(compare_vec4(&dst_data
[0], +8.500e+1f
, -1.000e+2f
, +1.800e+0f
, +1.000e+0f
, 4096),
659 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
660 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
661 ok(compare_vec4(&dst_data
[1], +1.100e+2f
, -1.400e+2f
, +2.000e+0f
, +1.000e+0f
, 4096),
662 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
663 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
664 ok(compare_vec4(&dst_data
[2], +1.350e+2f
, -1.800e+2f
, +2.200e+0f
, +1.000e+0f
, 4096),
665 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
666 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
667 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
668 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
670 vp2
.dwSize
= sizeof(vp2
);
677 vp2
.dvClipWidth
= 2.0f
;
678 vp2
.dvClipHeight
= 4.0f
;
681 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2
);
682 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
684 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
685 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
687 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
688 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
689 ok(compare_vec4(&dst_data
[0], +7.500e+1f
, +4.000e+1f
, -8.000e-1f
, +1.000e+0f
, 4096),
690 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
691 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
692 ok(compare_vec4(&dst_data
[1], +1.200e+2f
, +2.000e+1f
, -1.000e+0f
, +1.000e+0f
, 4096),
693 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
694 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
695 ok(compare_vec4(&dst_data
[2], +1.650e+2f
, +0.000e+0f
, -1.200e+0f
, +1.000e+0f
, 4096),
696 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
697 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
698 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
699 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
701 vp1
.dwSize
= sizeof(vp1
);
712 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp1
);
713 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
715 hr
= IDirect3DVertexBuffer_ProcessVertices(dst_vb
, D3DVOP_TRANSFORM
, 0, 3, src_vb
, 0, device
, 0);
716 ok(SUCCEEDED(hr
), "Failed to process vertices, hr %#x.\n", hr
);
718 hr
= IDirect3DVertexBuffer_Lock(dst_vb
, DDLOCK_READONLY
, (void **)&dst_data
, NULL
);
719 ok(SUCCEEDED(hr
), "Failed to lock destination vertex buffer, hr %#x.\n", hr
);
720 ok(compare_vec4(&dst_data
[0], +1.100e+2f
, +6.800e+1f
, +7.000e+0f
, +1.000e+0f
, 4096),
721 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
722 dst_data
[0].x
, dst_data
[0].y
, dst_data
[0].z
, dst_data
[0].w
);
723 ok(compare_vec4(&dst_data
[1], +1.170e+2f
, +6.600e+1f
, +8.000e+0f
, +1.000e+0f
, 4096),
724 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
725 dst_data
[1].x
, dst_data
[1].y
, dst_data
[1].z
, dst_data
[1].w
);
726 ok(compare_vec4(&dst_data
[2], +1.240e+2f
, +6.400e+1f
, +9.000e+0f
, +1.000e+0f
, 4096),
727 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
728 dst_data
[2].x
, dst_data
[2].y
, dst_data
[2].z
, dst_data
[2].w
);
729 hr
= IDirect3DVertexBuffer_Unlock(dst_vb
);
730 ok(SUCCEEDED(hr
), "Failed to unlock destination vertex buffer, hr %#x.\n", hr
);
732 hr
= IDirect3DDevice3_DeleteViewport(device
, viewport
);
733 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
735 IDirect3DVertexBuffer_Release(dst_vb
);
736 IDirect3DVertexBuffer_Release(src_vb
);
737 IDirect3DViewport3_Release(viewport
);
738 IDirect3D3_Release(d3d3
);
739 IDirect3DDevice3_Release(device
);
740 DestroyWindow(window
);
743 static void test_coop_level_create_device_window(void)
745 HWND focus_window
, device_window
;
749 focus_window
= create_window();
750 ddraw
= create_ddraw();
751 ok(!!ddraw
, "Failed to create a ddraw object.\n");
753 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
754 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
755 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
756 ok(!device_window
, "Unexpected device window found.\n");
757 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
758 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
759 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
760 ok(!device_window
, "Unexpected device window found.\n");
761 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
762 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
763 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
764 ok(!device_window
, "Unexpected device window found.\n");
765 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
766 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
767 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
768 ok(!device_window
, "Unexpected device window found.\n");
769 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
770 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
771 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
772 ok(!device_window
, "Unexpected device window found.\n");
774 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
775 if (broken(hr
== DDERR_INVALIDPARAMS
))
777 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
778 IDirectDraw4_Release(ddraw
);
779 DestroyWindow(focus_window
);
783 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
784 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
785 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
786 ok(!device_window
, "Unexpected device window found.\n");
787 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
788 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
789 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
790 ok(!device_window
, "Unexpected device window found.\n");
792 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
793 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
794 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
795 ok(!device_window
, "Unexpected device window found.\n");
796 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
797 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
798 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
799 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
800 ok(!!device_window
, "Device window not found.\n");
802 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
803 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
804 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
805 ok(!device_window
, "Unexpected device window found.\n");
806 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
807 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
808 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
809 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
810 ok(!!device_window
, "Device window not found.\n");
812 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
813 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
814 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
815 ok(!device_window
, "Unexpected device window found.\n");
816 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
817 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
818 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
819 ok(!device_window
, "Unexpected device window found.\n");
820 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
821 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
822 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
823 ok(!device_window
, "Unexpected device window found.\n");
824 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
825 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
826 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
827 ok(!!device_window
, "Device window not found.\n");
829 IDirectDraw4_Release(ddraw
);
830 DestroyWindow(focus_window
);
833 static void test_clipper_blt(void)
835 IDirectDrawSurface4
*src_surface
, *dst_surface
;
836 RECT client_rect
, src_rect
;
837 IDirectDrawClipper
*clipper
;
838 DDSURFACEDESC2 surface_desc
;
839 unsigned int i
, j
, x
, y
;
851 static const DWORD src_data
[] =
853 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
854 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
855 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
857 static const D3DCOLOR expected1
[] =
859 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
860 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
861 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
862 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
864 /* Nvidia on Windows seems to have an off-by-one error
865 * when processing source rectangles. Our left = 1 and
866 * right = 5 input reads from x = {1, 2, 3}. x = 4 is
867 * read as well, but only for the edge pixels on the
868 * output image. The bug happens on the y axis as well,
869 * but we only read one row there, and all source rows
870 * contain the same data. This bug is not dependent on
871 * the presence of a clipper. */
872 static const D3DCOLOR expected1_broken
[] =
874 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
875 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
876 0x00000000, 0x00000000, 0x00ff0000, 0x00ff0000,
877 0x00000000, 0x00000000, 0x0000ff00, 0x00ff0000,
879 static const D3DCOLOR expected2
[] =
881 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
882 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
883 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
884 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
887 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
888 10, 10, 640, 480, 0, 0, 0, 0);
889 ShowWindow(window
, SW_SHOW
);
890 ddraw
= create_ddraw();
891 ok(!!ddraw
, "Failed to create a ddraw object.\n");
893 ret
= GetClientRect(window
, &client_rect
);
894 ok(ret
, "Failed to get client rect.\n");
895 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
896 ok(ret
, "Failed to map client rect.\n");
898 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
899 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
901 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
902 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
903 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
904 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
905 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
906 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
907 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
908 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
909 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
910 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
911 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
912 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
913 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
914 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
915 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
916 "Got unexpected bounding rect %s, expected %s.\n",
917 wine_dbgstr_rect(&rgn_data
->rdh
.rcBound
), wine_dbgstr_rect(&client_rect
));
918 HeapFree(GetProcessHeap(), 0, rgn_data
);
920 r1
= CreateRectRgn(0, 0, 320, 240);
921 ok(!!r1
, "Failed to create region.\n");
922 r2
= CreateRectRgn(320, 240, 640, 480);
923 ok(!!r2
, "Failed to create region.\n");
924 CombineRgn(r1
, r1
, r2
, RGN_OR
);
925 ret
= GetRegionData(r1
, 0, NULL
);
926 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
927 ret
= GetRegionData(r1
, ret
, rgn_data
);
928 ok(!!ret
, "Failed to get region data.\n");
933 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
934 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
935 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
936 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
937 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
938 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
940 HeapFree(GetProcessHeap(), 0, rgn_data
);
942 memset(&surface_desc
, 0, sizeof(surface_desc
));
943 surface_desc
.dwSize
= sizeof(surface_desc
);
944 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
945 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
946 surface_desc
.dwWidth
= 640;
947 surface_desc
.dwHeight
= 480;
948 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
949 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
950 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
951 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
952 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
953 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
955 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
956 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
957 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
958 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
960 memset(&fx
, 0, sizeof(fx
));
961 fx
.dwSize
= sizeof(fx
);
962 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
963 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
964 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
965 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
967 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
968 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
969 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
970 ptr
= surface_desc
.lpSurface
;
971 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
972 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
973 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
974 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
975 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
977 hr
= IDirectDrawSurface4_SetClipper(dst_surface
, clipper
);
978 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
980 SetRect(&src_rect
, 1, 1, 5, 2);
981 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
982 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
983 for (i
= 0; i
< 4; ++i
)
985 for (j
= 0; j
< 4; ++j
)
987 x
= 80 * ((2 * j
) + 1);
988 y
= 60 * ((2 * i
) + 1);
989 color
= get_surface_color(dst_surface
, x
, y
);
990 ok(compare_color(color
, expected1
[i
* 4 + j
], 1)
991 || broken(compare_color(color
, expected1_broken
[i
* 4 + j
], 1)),
992 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
996 U5(fx
).dwFillColor
= 0xff0000ff;
997 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
998 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
999 for (i
= 0; i
< 4; ++i
)
1001 for (j
= 0; j
< 4; ++j
)
1003 x
= 80 * ((2 * j
) + 1);
1004 y
= 60 * ((2 * i
) + 1);
1005 color
= get_surface_color(dst_surface
, x
, y
);
1006 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
1007 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
1011 hr
= IDirectDrawSurface4_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
1012 ok(hr
== DDERR_BLTFASTCANTCLIP
, "Got unexpected hr %#x.\n", hr
);
1014 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
1015 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1016 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1017 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1018 DestroyWindow(window
);
1019 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1020 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
1021 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
1022 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
1023 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1024 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
1025 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
1026 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
1027 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
1028 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1029 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1030 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
1032 IDirectDrawSurface4_Release(dst_surface
);
1033 IDirectDrawSurface4_Release(src_surface
);
1034 refcount
= IDirectDrawClipper_Release(clipper
);
1035 ok(!refcount
, "Clipper has %u references left.\n", refcount
);
1036 IDirectDraw4_Release(ddraw
);
1039 static void test_coop_level_d3d_state(void)
1041 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1042 IDirectDrawSurface4
*rt
, *surface
;
1043 IDirect3DViewport3
*viewport
;
1044 IDirect3DDevice3
*device
;
1045 IDirectDraw4
*ddraw
;
1052 window
= create_window();
1053 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1055 skip("Failed to create a 3D device, skipping test.\n");
1056 DestroyWindow(window
);
1060 viewport
= create_viewport(device
, 0, 0, 640, 480);
1062 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1063 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1064 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1065 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1066 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1067 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1068 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1069 ok(!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1070 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
1071 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
1072 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1073 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1074 color
= get_surface_color(rt
, 320, 240);
1075 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1077 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1078 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1079 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1080 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1081 IDirect3D3_Release(d3d
);
1082 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1083 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1084 hr
= IDirectDrawSurface4_IsLost(rt
);
1085 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
1086 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
1087 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
1088 IDirectDraw4_Release(ddraw
);
1090 hr
= IDirect3DDevice3_GetRenderTarget(device
, &surface
);
1091 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1092 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
1093 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ZENABLE
, &value
);
1094 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1095 ok(!!value
, "Got unexpected z-enable state %#x.\n", value
);
1096 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, &value
);
1097 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1098 ok(!!value
, "Got unexpected alpha blend enable state %#x.\n", value
);
1099 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
1100 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1101 color
= get_surface_color(rt
, 320, 240);
1102 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1104 destroy_viewport(device
, viewport
);
1105 IDirectDrawSurface4_Release(surface
);
1106 IDirectDrawSurface4_Release(rt
);
1107 IDirect3DDevice3_Release(device
);
1108 DestroyWindow(window
);
1111 static void test_surface_interface_mismatch(void)
1113 IDirectDraw4
*ddraw
= NULL
;
1114 IDirect3D3
*d3d
= NULL
;
1115 IDirectDrawSurface4
*surface
= NULL
, *ds
;
1116 IDirectDrawSurface3
*surface3
= NULL
;
1117 IDirect3DDevice3
*device
= NULL
;
1118 IDirect3DViewport3
*viewport
= NULL
;
1119 DDSURFACEDESC2 surface_desc
;
1120 DDPIXELFORMAT z_fmt
;
1125 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1127 window
= create_window();
1128 ddraw
= create_ddraw();
1129 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1130 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1131 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1133 memset(&surface_desc
, 0, sizeof(surface_desc
));
1134 surface_desc
.dwSize
= sizeof(surface_desc
);
1135 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1136 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
1137 surface_desc
.dwWidth
= 640;
1138 surface_desc
.dwHeight
= 480;
1140 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1141 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1143 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
1144 ok(SUCCEEDED(hr
), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr
);
1146 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
1148 skip("D3D interface is not available, skipping test.\n");
1152 memset(&z_fmt
, 0, sizeof(z_fmt
));
1153 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
1154 if (FAILED(hr
) || !z_fmt
.dwSize
)
1156 skip("No depth buffer formats available, skipping test.\n");
1160 memset(&surface_desc
, 0, sizeof(surface_desc
));
1161 surface_desc
.dwSize
= sizeof(surface_desc
);
1162 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
1163 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1164 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
1165 surface_desc
.dwWidth
= 640;
1166 surface_desc
.dwHeight
= 480;
1167 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
1168 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
1172 /* Using a different surface interface version still works */
1173 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
1174 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
1175 refcount
= IDirectDrawSurface4_Release(ds
);
1176 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
1181 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, (IDirectDrawSurface4
*)surface3
, &device
, NULL
);
1182 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
1186 viewport
= create_viewport(device
, 0, 0, 640, 480);
1188 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
1189 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1190 color
= get_surface_color(surface
, 320, 240);
1191 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
1195 destroy_viewport(device
, viewport
);
1196 if (surface3
) IDirectDrawSurface3_Release(surface3
);
1197 if (surface
) IDirectDrawSurface4_Release(surface
);
1198 if (device
) IDirect3DDevice3_Release(device
);
1199 if (d3d
) IDirect3D3_Release(d3d
);
1200 if (ddraw
) IDirectDraw4_Release(ddraw
);
1201 DestroyWindow(window
);
1204 static void test_coop_level_threaded(void)
1206 struct create_window_thread_param p
;
1207 IDirectDraw4
*ddraw
;
1210 ddraw
= create_ddraw();
1211 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1212 create_window_thread(&p
);
1214 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1215 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1217 IDirectDraw4_Release(ddraw
);
1218 destroy_window_thread(&p
);
1221 static void test_depth_blit(void)
1230 { -1.0, 1.0, 0.50f
, 0xff00ff00},
1231 { 1.0, 1.0, 0.50f
, 0xff00ff00},
1232 { -1.0, -1.0, 0.50f
, 0xff00ff00},
1233 { 1.0, -1.0, 0.50f
, 0xff00ff00},
1235 static const D3DCOLOR expected_colors
[4][4] =
1237 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1238 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1239 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1240 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1242 DDSURFACEDESC2 ddsd_new
, ddsd_existing
;
1244 IDirect3DDevice3
*device
;
1245 IDirectDrawSurface4
*ds1
, *ds2
, *ds3
, *rt
;
1246 IDirect3DViewport3
*viewport
;
1247 RECT src_rect
, dst_rect
;
1252 IDirectDraw4
*ddraw
;
1257 window
= create_window();
1258 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1260 skip("Failed to create a 3D device, skipping test.\n");
1261 DestroyWindow(window
);
1265 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1266 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1267 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1268 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1269 IDirect3D3_Release(d3d
);
1271 ds1
= get_depth_stencil(device
);
1273 memset(&ddsd_new
, 0, sizeof(ddsd_new
));
1274 ddsd_new
.dwSize
= sizeof(ddsd_new
);
1275 memset(&ddsd_existing
, 0, sizeof(ddsd_existing
));
1276 ddsd_existing
.dwSize
= sizeof(ddsd_existing
);
1277 hr
= IDirectDrawSurface4_GetSurfaceDesc(ds1
, &ddsd_existing
);
1278 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1279 ddsd_new
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
1280 ddsd_new
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
1281 ddsd_new
.dwWidth
= ddsd_existing
.dwWidth
;
1282 ddsd_new
.dwHeight
= ddsd_existing
.dwHeight
;
1283 U4(ddsd_new
).ddpfPixelFormat
= U4(ddsd_existing
).ddpfPixelFormat
;
1284 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds2
, NULL
);
1285 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1286 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd_new
, &ds3
, NULL
);
1287 ok(SUCCEEDED(hr
), "Failed to create a surface, hr %#x.\n", hr
);
1288 IDirectDraw4_Release(ddraw
);
1290 viewport
= create_viewport(device
, 0, 0, ddsd_existing
.dwWidth
, ddsd_existing
.dwHeight
);
1291 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1292 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
1294 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_TRUE
);
1295 ok(SUCCEEDED(hr
), "Failed to enable z testing, hr %#x.\n", hr
);
1296 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZFUNC
, D3DCMP_LESSEQUAL
);
1297 ok(SUCCEEDED(hr
), "Failed to set the z function, hr %#x.\n", hr
);
1299 U1(d3drect
).x1
= U2(d3drect
).y1
= 0;
1300 U3(d3drect
).x2
= ddsd_existing
.dwWidth
; U4(d3drect
).y2
= ddsd_existing
.dwHeight
;
1301 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
1302 ok(SUCCEEDED(hr
), "Failed to clear the z buffer, hr %#x.\n", hr
);
1305 SetRect(&src_rect
, 0, 0, 320, 240);
1306 SetRect(&dst_rect
, 0, 0, 320, 240);
1307 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1308 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1309 /* Different locations. */
1310 SetRect(&src_rect
, 0, 0, 320, 240);
1311 SetRect(&dst_rect
, 320, 240, 640, 480);
1312 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1313 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1315 SetRect(&src_rect
, 0, 0, 320, 240);
1316 SetRect(&dst_rect
, 0, 0, 640, 480);
1317 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1318 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1320 SetRect(&src_rect
, 0, 480, 640, 0);
1321 SetRect(&dst_rect
, 0, 0, 640, 480);
1322 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1323 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1324 SetRect(&src_rect
, 0, 0, 640, 480);
1325 SetRect(&dst_rect
, 0, 480, 640, 0);
1326 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1327 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
1328 /* Full, explicit. */
1329 SetRect(&src_rect
, 0, 0, 640, 480);
1330 SetRect(&dst_rect
, 0, 0, 640, 480);
1331 hr
= IDirectDrawSurface4_Blt(ds2
, &dst_rect
, ds1
, &src_rect
, DDBLT_WAIT
, NULL
);
1332 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1333 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1335 /* Depth blit inside a BeginScene / EndScene pair */
1336 hr
= IDirect3DDevice3_BeginScene(device
);
1337 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1338 /* From the current depth stencil */
1339 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, ds1
, NULL
, DDBLT_WAIT
, NULL
);
1340 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1341 /* To the current depth stencil */
1342 hr
= IDirectDrawSurface4_Blt(ds1
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1343 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1344 /* Between unbound surfaces */
1345 hr
= IDirectDrawSurface4_Blt(ds3
, NULL
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1346 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1347 hr
= IDirect3DDevice3_EndScene(device
);
1348 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1350 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1351 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1352 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1353 * a reliable result(z = 0.0) */
1354 memset(&fx
, 0, sizeof(fx
));
1355 fx
.dwSize
= sizeof(fx
);
1356 hr
= IDirectDrawSurface4_Blt(ds2
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
1357 ok(SUCCEEDED(hr
), "Failed to clear the source z buffer, hr %#x.\n", hr
);
1359 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &d3drect
, D3DCLEAR_ZBUFFER
| D3DCLEAR_TARGET
, 0xffff0000, 1.0f
, 0);
1360 ok(SUCCEEDED(hr
), "Failed to clear the color and z buffers, hr %#x.\n", hr
);
1361 SetRect(&dst_rect
, 0, 0, 320, 240);
1362 hr
= IDirectDrawSurface4_Blt(ds1
, &dst_rect
, ds2
, NULL
, DDBLT_WAIT
, NULL
);
1363 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1364 IDirectDrawSurface4_Release(ds3
);
1365 IDirectDrawSurface4_Release(ds2
);
1366 IDirectDrawSurface4_Release(ds1
);
1368 hr
= IDirect3DDevice3_BeginScene(device
);
1369 ok(SUCCEEDED(hr
), "Failed to start a scene, hr %#x.\n", hr
);
1370 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
1372 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1373 hr
= IDirect3DDevice3_EndScene(device
);
1374 ok(SUCCEEDED(hr
), "Failed to end a scene, hr %#x.\n", hr
);
1376 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1377 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1378 for (i
= 0; i
< 4; ++i
)
1380 for (j
= 0; j
< 4; ++j
)
1382 unsigned int x
= 80 * ((2 * j
) + 1);
1383 unsigned int y
= 60 * ((2 * i
) + 1);
1384 color
= get_surface_color(rt
, x
, y
);
1385 ok(compare_color(color
, expected_colors
[i
][j
], 1),
1386 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors
[i
][j
], x
, y
, color
);
1389 IDirectDrawSurface4_Release(rt
);
1391 destroy_viewport(device
, viewport
);
1392 IDirect3DDevice3_Release(device
);
1393 DestroyWindow(window
);
1396 static void test_texture_load_ckey(void)
1398 IDirectDraw4
*ddraw
;
1399 IDirectDrawSurface4
*src
;
1400 IDirectDrawSurface4
*dst
;
1401 IDirect3DTexture2
*src_tex
;
1402 IDirect3DTexture2
*dst_tex
;
1403 DDSURFACEDESC2 ddsd
;
1407 ddraw
= create_ddraw();
1408 ok(!!ddraw
, "Failed to create a ddraw object.\n");
1409 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
1410 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
1412 memset(&ddsd
, 0, sizeof(ddsd
));
1413 ddsd
.dwSize
= sizeof(ddsd
);
1414 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
1415 ddsd
.dwHeight
= 128;
1417 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
;
1418 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &src
, NULL
);
1419 ok(SUCCEEDED(hr
), "Failed to create source texture, hr %#x.\n", hr
);
1420 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1421 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &dst
, NULL
);
1422 ok(SUCCEEDED(hr
), "Failed to create destination texture, hr %#x.\n", hr
);
1424 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirect3DTexture2
, (void **)&src_tex
);
1425 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1428 /* 64 bit ddraw does not support d3d */
1429 skip("Could not get Direct3DTexture2 interface, skipping texture::Load color keying tests.\n");
1430 IDirectDrawSurface4_Release(dst
);
1431 IDirectDrawSurface4_Release(src
);
1432 IDirectDraw4_Release(ddraw
);
1435 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirect3DTexture2
, (void **)&dst_tex
);
1436 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x.\n", hr
);
1438 /* No surface has a color key */
1439 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1440 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1441 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0xdeadbeef;
1442 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1443 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1444 ok(ckey
.dwColorSpaceLowValue
== 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1445 ok(ckey
.dwColorSpaceHighValue
== 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1447 /* Source surface has a color key */
1448 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
1449 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1450 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1451 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1452 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1453 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1454 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1455 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1456 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1458 /* Both surfaces have a color key: Dest ckey is overwritten */
1459 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x000000ff;
1460 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1461 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1462 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1463 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1464 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1465 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1466 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1467 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1469 /* Only the destination has a color key: It is not deleted */
1470 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
1471 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
1472 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
1473 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
1474 hr
= IDirect3DTexture2_Load(dst_tex
, src_tex
);
1475 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1476 hr
= IDirectDrawSurface4_GetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
1477 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
1478 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey
.dwColorSpaceLowValue
);
1479 ok(ckey
.dwColorSpaceHighValue
== 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey
.dwColorSpaceHighValue
);
1481 IDirect3DTexture2_Release(dst_tex
);
1482 IDirect3DTexture2_Release(src_tex
);
1483 IDirectDrawSurface4_Release(dst
);
1484 IDirectDrawSurface4_Release(src
);
1485 IDirectDraw4_Release(ddraw
);
1488 static ULONG
get_refcount(IUnknown
*test_iface
)
1490 IUnknown_AddRef(test_iface
);
1491 return IUnknown_Release(test_iface
);
1494 static void test_viewport(void)
1496 IDirectDraw4
*ddraw
;
1498 HRESULT hr
, old_d3d_ref
;
1500 IDirect3DViewport
*viewport
;
1501 IDirect3DViewport2
*viewport2
;
1502 IDirect3DViewport3
*viewport3
, *another_vp
, *test_vp
;
1503 IDirectDrawGammaControl
*gamma
;
1506 IDirect3DDevice3
*device
;
1508 window
= create_window();
1509 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1511 skip("Failed to create a 3D device, skipping test.\n");
1512 DestroyWindow(window
);
1515 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1516 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
1517 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1518 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
1519 old_d3d_ref
= get_refcount((IUnknown
*) d3d
);
1521 hr
= IDirect3D3_CreateViewport(d3d
, &viewport3
, NULL
);
1522 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1523 ref
= get_refcount((IUnknown
*)viewport3
);
1524 ok(ref
== 1, "Initial IDirect3DViewport3 refcount is %u\n", ref
);
1525 ref
= get_refcount((IUnknown
*)d3d
);
1526 ok(ref
== old_d3d_ref
, "IDirect3D3 refcount is %u\n", ref
);
1528 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
1529 hr
= IDirect3DViewport2_QueryInterface(viewport3
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
1530 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#x.\n", hr
);
1531 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
1532 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
1533 /* NULL iid: Segfaults */
1535 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport
, (void **)&viewport
);
1536 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport, hr %#x.\n", hr
);
1539 ref
= get_refcount((IUnknown
*)viewport
);
1540 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1541 ref
= get_refcount((IUnknown
*)viewport3
);
1542 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1543 IDirect3DViewport_Release(viewport
);
1547 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IDirect3DViewport3
, (void **)&viewport2
);
1548 ok(SUCCEEDED(hr
), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1551 ref
= get_refcount((IUnknown
*)viewport2
);
1552 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
1553 ref
= get_refcount((IUnknown
*)viewport3
);
1554 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1555 IDirect3DViewport3_Release(viewport2
);
1558 hr
= IDirect3DViewport3_QueryInterface(viewport3
, &IID_IUnknown
, (void **)&unknown
);
1559 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1562 ref
= get_refcount((IUnknown
*)viewport3
);
1563 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1564 ref
= get_refcount(unknown
);
1565 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1566 IUnknown_Release(unknown
);
1569 /* AddViewport(NULL): Segfault */
1570 hr
= IDirect3DDevice3_DeleteViewport(device
, NULL
);
1571 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1572 hr
= IDirect3DDevice3_GetCurrentViewport(device
, NULL
);
1573 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1575 hr
= IDirect3D3_CreateViewport(d3d
, &another_vp
, NULL
);
1576 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
1578 /* Setting a viewport not in the viewport list fails */
1579 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1580 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
1582 hr
= IDirect3DDevice3_AddViewport(device
, viewport3
);
1583 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1584 ref
= get_refcount((IUnknown
*) viewport3
);
1585 ok(ref
== 2, "viewport3 refcount is %d\n", ref
);
1586 hr
= IDirect3DDevice3_AddViewport(device
, another_vp
);
1587 ok(SUCCEEDED(hr
), "Failed to add viewport to device, hr %#x.\n", hr
);
1588 ref
= get_refcount((IUnknown
*) another_vp
);
1589 ok(ref
== 2, "another_vp refcount is %d\n", ref
);
1591 test_vp
= (IDirect3DViewport3
*) 0xbaadc0de;
1592 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1593 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1594 ok(test_vp
== (IDirect3DViewport3
*) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp
);
1596 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1597 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1598 ref
= get_refcount((IUnknown
*) viewport3
);
1599 ok(ref
== 3, "viewport3 refcount is %d\n", ref
);
1600 ref
= get_refcount((IUnknown
*) device
);
1601 ok(ref
== 1, "device refcount is %d\n", ref
);
1604 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1605 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1606 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1607 ref
= get_refcount((IUnknown
*) viewport3
);
1608 ok(ref
== 4, "viewport3 refcount is %d\n", ref
);
1609 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1611 /* GetCurrentViewport with a viewport set and NULL input param: Segfault */
1613 /* Cannot set the viewport to NULL */
1614 hr
= IDirect3DDevice3_SetCurrentViewport(device
, NULL
);
1615 ok(hr
== DDERR_INVALIDPARAMS
, "Failed to set viewport to NULL, hr %#x.\n", hr
);
1617 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1618 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
1619 ok(test_vp
== viewport3
, "Got unexpected viewport %p\n", test_vp
);
1620 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1622 /* SetCurrentViewport properly releases the old viewport's reference */
1623 hr
= IDirect3DDevice3_SetCurrentViewport(device
, another_vp
);
1624 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1625 ref
= get_refcount((IUnknown
*) viewport3
);
1626 ok(ref
== 2, "viewport3 refcount is %d\n", ref
);
1627 ref
= get_refcount((IUnknown
*) another_vp
);
1628 ok(ref
== 3, "another_vp refcount is %d\n", ref
);
1630 /* Unlike device2::DeleteViewport, device3::DeleteViewport releases the
1631 * reference held by SetCurrentViewport */
1632 hr
= IDirect3DDevice3_DeleteViewport(device
, another_vp
);
1633 ok(SUCCEEDED(hr
), "Failed to delete viewport from device, hr %#x.\n", hr
);
1634 ref
= get_refcount((IUnknown
*) another_vp
);
1635 ok(ref
== 1, "another_vp refcount is %d\n", ref
);
1637 /* GetCurrentViewport still fails */
1639 hr
= IDirect3DDevice3_GetCurrentViewport(device
, &test_vp
);
1640 ok(hr
== D3DERR_NOCURRENTVIEWPORT
, "Got unexpected hr %#x.\n", hr
);
1641 ok(test_vp
== NULL
, "Got unexpected viewport %p\n", test_vp
);
1642 if(test_vp
) IDirect3DViewport3_Release(test_vp
);
1644 /* Setting a different viewport doesn't have any surprises now */
1645 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
1646 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1647 ref
= get_refcount((IUnknown
*) viewport3
);
1648 ok(ref
== 3, "viewport3 refcount is %d\n", ref
);
1649 ref
= get_refcount((IUnknown
*) another_vp
);
1650 ok(ref
== 1, "another_vp refcount is %d\n", ref
);
1652 /* Destroying the device removes the viewport and releases the reference */
1653 IDirect3DDevice3_Release(device
);
1654 ref
= get_refcount((IUnknown
*) viewport3
);
1655 ok(ref
== 1, "viewport3 refcount is %d\n", ref
);
1657 ref
= IDirect3DViewport3_Release(another_vp
);
1658 ok(ref
== 0, "Got unexpected ref %d\n", ref
);
1659 ref
= IDirect3DViewport3_Release(viewport3
);
1660 ok(ref
== 0, "Got unexpected ref %d\n", ref
);
1661 IDirect3D3_Release(d3d
);
1662 DestroyWindow(window
);
1663 IDirectDraw4_Release(ddraw
);
1666 static void test_zenable(void)
1668 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1671 struct vec4 position
;
1676 {{ 0.0f
, 480.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1677 {{ 0.0f
, 0.0f
, -0.5f
, 1.0f
}, 0xff00ff00},
1678 {{640.0f
, 480.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1679 {{640.0f
, 0.0f
, 1.5f
, 1.0f
}, 0xff00ff00},
1681 IDirect3DViewport3
*viewport
;
1682 IDirect3DDevice3
*device
;
1683 IDirectDrawSurface4
*rt
;
1690 window
= create_window();
1691 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1693 skip("Failed to create a 3D device, skipping test.\n");
1694 DestroyWindow(window
);
1698 viewport
= create_viewport(device
, 0, 0, 640, 480);
1699 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1700 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1702 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1703 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
1705 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 0.0f
, 0);
1706 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1707 hr
= IDirect3DDevice3_BeginScene(device
);
1708 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1709 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
, tquad
, 4, 0);
1710 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1711 hr
= IDirect3DDevice3_EndScene(device
);
1712 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1714 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1715 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1716 for (i
= 0; i
< 4; ++i
)
1718 for (j
= 0; j
< 4; ++j
)
1720 x
= 80 * ((2 * j
) + 1);
1721 y
= 60 * ((2 * i
) + 1);
1722 color
= get_surface_color(rt
, x
, y
);
1723 ok(compare_color(color
, 0x0000ff00, 1),
1724 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1727 IDirectDrawSurface4_Release(rt
);
1729 destroy_viewport(device
, viewport
);
1730 IDirect3DDevice3_Release(device
);
1731 DestroyWindow(window
);
1734 static void test_ck_rgba(void)
1736 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1739 struct vec4 position
;
1740 struct vec2 texcoord
;
1744 {{ 0.0f
, 480.0f
, 0.25f
, 1.0f
}, {0.0f
, 0.0f
}},
1745 {{ 0.0f
, 0.0f
, 0.25f
, 1.0f
}, {0.0f
, 1.0f
}},
1746 {{640.0f
, 480.0f
, 0.25f
, 1.0f
}, {1.0f
, 0.0f
}},
1747 {{640.0f
, 0.0f
, 0.25f
, 1.0f
}, {1.0f
, 1.0f
}},
1748 {{ 0.0f
, 480.0f
, 0.75f
, 1.0f
}, {0.0f
, 0.0f
}},
1749 {{ 0.0f
, 0.0f
, 0.75f
, 1.0f
}, {0.0f
, 1.0f
}},
1750 {{640.0f
, 480.0f
, 0.75f
, 1.0f
}, {1.0f
, 0.0f
}},
1751 {{640.0f
, 0.0f
, 0.75f
, 1.0f
}, {1.0f
, 1.0f
}},
1755 D3DCOLOR fill_color
;
1758 D3DCOLOR result1
, result1_broken
;
1759 D3DCOLOR result2
, result2_broken
;
1763 /* r200 on Windows doesn't check the alpha component when applying the color
1764 * key, so the key matches on every texel. */
1765 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1766 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x00ff0000, 0x000000ff, 0x000000ff},
1767 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1768 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1769 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00ff0000, 0x00807f00, 0x000000ff},
1770 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x00ff0000, 0x0000ff00, 0x000000ff},
1771 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00, 0x00807f00, 0x00807f00},
1772 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1775 IDirectDrawSurface4
*surface
;
1776 IDirect3DViewport3
*viewport
;
1777 DDSURFACEDESC2 surface_desc
;
1778 IDirect3DTexture2
*texture
;
1779 IDirect3DDevice3
*device
;
1780 IDirectDrawSurface4
*rt
;
1781 IDirectDraw4
*ddraw
;
1789 window
= create_window();
1790 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1792 skip("Failed to create a 3D device, skipping test.\n");
1793 DestroyWindow(window
);
1797 viewport
= create_viewport(device
, 0, 0, 640, 480);
1798 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1799 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1801 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1802 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1803 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1804 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1805 IDirect3D3_Release(d3d
);
1807 memset(&surface_desc
, 0, sizeof(surface_desc
));
1808 surface_desc
.dwSize
= sizeof(surface_desc
);
1809 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1810 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1811 surface_desc
.dwWidth
= 256;
1812 surface_desc
.dwHeight
= 256;
1813 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1814 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1815 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1816 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1817 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1818 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1819 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1820 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1821 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1822 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1823 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1824 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1825 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1827 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1828 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1829 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1830 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1831 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1832 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1834 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1835 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1837 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
1839 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1840 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1841 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1842 ok(SUCCEEDED(hr
), "Failed to enable alpha blending, hr %#x.\n", hr
);
1844 memset(&fx
, 0, sizeof(fx
));
1845 fx
.dwSize
= sizeof(fx
);
1846 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1847 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1848 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1850 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
1851 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffff0000, 1.0f
, 0);
1852 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1853 hr
= IDirect3DDevice3_BeginScene(device
);
1854 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1855 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1856 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1857 hr
= IDirect3DDevice3_EndScene(device
);
1858 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1860 color
= get_surface_color(rt
, 320, 240);
1861 ok(compare_color(color
, tests
[i
].result1
, 1) || compare_color(color
, tests
[i
].result1_broken
, 1),
1862 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1863 tests
[i
].result1
, i
, color
);
1865 U5(fx
).dwFillColor
= 0xff0000ff;
1866 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1867 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1869 hr
= IDirect3DDevice3_BeginScene(device
);
1870 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1871 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[4], 4, 0);
1872 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1873 hr
= IDirect3DDevice3_EndScene(device
);
1874 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1876 /* This tests that fragments that are masked out by the color key are
1877 * discarded, instead of just fully transparent. */
1878 color
= get_surface_color(rt
, 320, 240);
1879 ok(compare_color(color
, tests
[i
].result2
, 1) || compare_color(color
, tests
[i
].result2_broken
, 1),
1880 "Expected color 0x%08x for test %u, got 0x%08x.\n",
1881 tests
[i
].result2
, i
, color
);
1884 IDirectDrawSurface4_Release(rt
);
1885 IDirect3DTexture2_Release(texture
);
1886 IDirectDrawSurface4_Release(surface
);
1887 destroy_viewport(device
, viewport
);
1888 IDirectDraw4_Release(ddraw
);
1889 IDirect3DDevice3_Release(device
);
1890 DestroyWindow(window
);
1893 static void test_ck_default(void)
1895 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1898 struct vec4 position
;
1899 struct vec2 texcoord
;
1903 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, {0.0f
, 0.0f
}},
1904 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, {0.0f
, 1.0f
}},
1905 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
1906 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, {1.0f
, 1.0f
}},
1908 IDirectDrawSurface4
*surface
, *rt
;
1909 IDirect3DViewport3
*viewport
;
1910 DDSURFACEDESC2 surface_desc
;
1911 IDirect3DTexture2
*texture
;
1912 IDirect3DDevice3
*device
;
1913 IDirectDraw4
*ddraw
;
1921 window
= create_window();
1922 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
1924 skip("Failed to create a 3D device, skipping test.\n");
1925 DestroyWindow(window
);
1929 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
1930 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
1931 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
1932 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
1933 IDirect3D3_Release(d3d
);
1935 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
1936 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1938 viewport
= create_viewport(device
, 0, 0, 640, 480);
1939 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
1940 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
1942 memset(&surface_desc
, 0, sizeof(surface_desc
));
1943 surface_desc
.dwSize
= sizeof(surface_desc
);
1944 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1945 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1946 surface_desc
.dwWidth
= 256;
1947 surface_desc
.dwHeight
= 256;
1948 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
1949 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1950 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
1951 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1952 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1953 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1954 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1955 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1956 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1957 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1958 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
1959 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1960 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
1961 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
1963 memset(&fx
, 0, sizeof(fx
));
1964 fx
.dwSize
= sizeof(fx
);
1965 U5(fx
).dwFillColor
= 0x000000ff;
1966 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1967 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1969 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1970 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1971 hr
= IDirect3DDevice3_BeginScene(device
);
1972 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1973 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1974 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1975 ok(!value
, "Got unexpected color keying state %#x.\n", value
);
1976 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1977 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1978 hr
= IDirect3DDevice3_EndScene(device
);
1979 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1980 color
= get_surface_color(rt
, 320, 240);
1981 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1983 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 1.0f
, 0);
1984 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1985 hr
= IDirect3DDevice3_BeginScene(device
);
1986 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1987 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1988 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
1989 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZRHW
| D3DFVF_TEX1
, &tquad
[0], 4, 0);
1990 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
1991 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, &value
);
1992 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#x.\n", hr
);
1993 ok(!!value
, "Got unexpected color keying state %#x.\n", value
);
1994 hr
= IDirect3DDevice3_EndScene(device
);
1995 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1996 color
= get_surface_color(rt
, 320, 240);
1997 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1999 IDirect3DTexture_Release(texture
);
2000 IDirectDrawSurface4_Release(surface
);
2001 destroy_viewport(device
, viewport
);
2002 IDirectDrawSurface4_Release(rt
);
2003 IDirect3DDevice3_Release(device
);
2004 IDirectDraw4_Release(ddraw
);
2005 DestroyWindow(window
);
2008 static void test_ck_complex(void)
2010 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
2011 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
2012 DDSURFACEDESC2 surface_desc
;
2013 IDirect3DDevice3
*device
;
2014 DDCOLORKEY color_key
;
2015 IDirectDraw4
*ddraw
;
2022 window
= create_window();
2023 if (!(device
= create_device(window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
)))
2025 skip("Failed to create a 3D device, skipping test.\n");
2026 DestroyWindow(window
);
2029 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
2030 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
2031 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
2032 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
2033 IDirect3D3_Release(d3d
);
2035 memset(&surface_desc
, 0, sizeof(surface_desc
));
2036 surface_desc
.dwSize
= sizeof(surface_desc
);
2037 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2038 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
2039 surface_desc
.dwWidth
= 128;
2040 surface_desc
.dwHeight
= 128;
2041 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2042 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2044 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2045 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2046 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2047 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2048 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2049 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2050 memset(&color_key
, 0, sizeof(color_key
));
2051 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2052 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2053 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2054 color_key
.dwColorSpaceLowValue
);
2055 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2056 color_key
.dwColorSpaceHighValue
);
2059 IDirectDrawSurface_AddRef(mipmap
);
2060 for (i
= 0; i
< 7; ++i
)
2062 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2063 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
2065 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2066 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2067 color_key
.dwColorSpaceLowValue
= 0x000000ff;
2068 color_key
.dwColorSpaceHighValue
= 0x000000ff;
2069 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2070 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x, i %u.\n", hr
, i
);
2071 memset(&color_key
, 0, sizeof(color_key
));
2072 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2073 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x, i %u.\n", hr
, i
);
2074 ok(color_key
.dwColorSpaceLowValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2075 color_key
.dwColorSpaceLowValue
, i
);
2076 ok(color_key
.dwColorSpaceHighValue
== 0x000000ff, "Got unexpected value 0x%08x, i %u.\n",
2077 color_key
.dwColorSpaceHighValue
, i
);
2079 IDirectDrawSurface_Release(mipmap
);
2083 memset(&color_key
, 0, sizeof(color_key
));
2084 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2085 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2086 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2087 color_key
.dwColorSpaceLowValue
);
2088 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2089 color_key
.dwColorSpaceHighValue
);
2091 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
2092 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
2093 IDirectDrawSurface_Release(mipmap
);
2094 refcount
= IDirectDrawSurface4_Release(surface
);
2095 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2097 memset(&surface_desc
, 0, sizeof(surface_desc
));
2098 surface_desc
.dwSize
= sizeof(surface_desc
);
2099 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
2100 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
2101 U5(surface_desc
).dwBackBufferCount
= 1;
2102 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2103 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2105 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2106 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x.\n", hr
);
2107 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2108 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2109 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2110 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2111 memset(&color_key
, 0, sizeof(color_key
));
2112 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &color_key
);
2113 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2114 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2115 color_key
.dwColorSpaceLowValue
);
2116 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2117 color_key
.dwColorSpaceHighValue
);
2119 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
2120 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
2122 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2123 ok(hr
== DDERR_NOCOLORKEY
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
2124 color_key
.dwColorSpaceLowValue
= 0x0000ff00;
2125 color_key
.dwColorSpaceHighValue
= 0x0000ff00;
2126 hr
= IDirectDrawSurface4_SetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2127 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
2128 memset(&color_key
, 0, sizeof(color_key
));
2129 hr
= IDirectDrawSurface4_GetColorKey(tmp
, DDCKEY_SRCBLT
, &color_key
);
2130 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
2131 ok(color_key
.dwColorSpaceLowValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2132 color_key
.dwColorSpaceLowValue
);
2133 ok(color_key
.dwColorSpaceHighValue
== 0x0000ff00, "Got unexpected value 0x%08x.\n",
2134 color_key
.dwColorSpaceHighValue
);
2136 IDirectDrawSurface_Release(tmp
);
2138 refcount
= IDirectDrawSurface4_Release(surface
);
2139 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2140 IDirectDraw4_Release(ddraw
);
2141 refcount
= IDirect3DDevice3_Release(device
);
2142 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
2143 DestroyWindow(window
);
2149 REFIID refcount_iid
;
2153 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
2154 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
2156 ULONG refcount
, expected_refcount
;
2157 IUnknown
*iface1
, *iface2
;
2161 for (i
= 0; i
< entry_count
; ++i
)
2163 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
2164 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
2167 for (j
= 0; j
< entry_count
; ++j
)
2169 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
2170 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
2173 expected_refcount
= 0;
2174 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
2175 ++expected_refcount
;
2176 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
2177 ++expected_refcount
;
2178 refcount
= IUnknown_Release(iface2
);
2179 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
2180 refcount
, test_name
, i
, j
, expected_refcount
);
2184 expected_refcount
= 0;
2185 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
2186 ++expected_refcount
;
2187 refcount
= IUnknown_Release(iface1
);
2188 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
2189 refcount
, test_name
, i
, expected_refcount
);
2194 static void test_surface_qi(void)
2196 static const struct qi_test tests
[] =
2198 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface4
, S_OK
},
2199 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface4
, S_OK
},
2200 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
2201 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2202 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
2203 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
2204 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
2205 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
2206 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
2207 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
2208 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
2209 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
2210 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
2211 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
2212 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
2213 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
2214 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
2215 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
2216 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
2217 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
2218 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
2219 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
2220 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
2221 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
2222 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
2223 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
2224 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
2225 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
2226 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
2227 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
2228 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
2229 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
2230 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
2231 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
2232 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
2233 {NULL
, NULL
, E_INVALIDARG
},
2236 IDirectDrawSurface4
*surface
;
2237 DDSURFACEDESC2 surface_desc
;
2238 IDirect3DDevice3
*device
;
2239 IDirectDraw4
*ddraw
;
2243 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
2245 win_skip("DirectDrawCreateEx not available, skipping test.\n");
2249 window
= create_window();
2250 /* Try to create a D3D device to see if the ddraw implementation supports
2251 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
2252 * doesn't support e.g. the IDirect3DTexture interfaces. */
2253 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2255 skip("Failed to create a 3D device, skipping test.\n");
2256 DestroyWindow(window
);
2259 IDirect3DDevice_Release(device
);
2260 ddraw
= create_ddraw();
2261 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2262 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2263 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
2265 memset(&surface_desc
, 0, sizeof(surface_desc
));
2266 surface_desc
.dwSize
= sizeof(surface_desc
);
2267 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
2268 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
2269 surface_desc
.dwWidth
= 512;
2270 surface_desc
.dwHeight
= 512;
2271 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, (IDirectDrawSurface4
**)0xdeadbeef, NULL
);
2272 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
2273 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
2274 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
2276 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface4
, tests
, ARRAY_SIZE(tests
));
2278 IDirectDrawSurface4_Release(surface
);
2279 IDirectDraw4_Release(ddraw
);
2280 DestroyWindow(window
);
2283 static void test_device_qi(void)
2285 static const struct qi_test tests
[] =
2287 {&IID_IDirect3DTexture2
, NULL
, E_NOINTERFACE
},
2288 {&IID_IDirect3DTexture
, NULL
, E_NOINTERFACE
},
2289 {&IID_IDirectDrawGammaControl
, NULL
, E_NOINTERFACE
},
2290 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
2291 {&IID_IDirectDrawSurface7
, NULL
, E_NOINTERFACE
},
2292 {&IID_IDirectDrawSurface4
, NULL
, E_NOINTERFACE
},
2293 {&IID_IDirectDrawSurface3
, NULL
, E_NOINTERFACE
},
2294 {&IID_IDirectDrawSurface2
, NULL
, E_NOINTERFACE
},
2295 {&IID_IDirectDrawSurface
, NULL
, E_NOINTERFACE
},
2296 {&IID_IDirect3DDevice7
, NULL
, E_NOINTERFACE
},
2297 {&IID_IDirect3DDevice3
, &IID_IDirect3DDevice3
, S_OK
},
2298 {&IID_IDirect3DDevice2
, &IID_IDirect3DDevice3
, S_OK
},
2299 {&IID_IDirect3DDevice
, &IID_IDirect3DDevice3
, S_OK
},
2300 {&IID_IDirect3DRampDevice
, NULL
, E_NOINTERFACE
},
2301 {&IID_IDirect3DRGBDevice
, NULL
, E_NOINTERFACE
},
2302 {&IID_IDirect3DHALDevice
, NULL
, E_NOINTERFACE
},
2303 {&IID_IDirect3DMMXDevice
, NULL
, E_NOINTERFACE
},
2304 {&IID_IDirect3DRefDevice
, NULL
, E_NOINTERFACE
},
2305 {&IID_IDirect3DTnLHalDevice
, NULL
, E_NOINTERFACE
},
2306 {&IID_IDirect3DNullDevice
, NULL
, E_NOINTERFACE
},
2307 {&IID_IDirect3D7
, NULL
, E_NOINTERFACE
},
2308 {&IID_IDirect3D3
, NULL
, E_NOINTERFACE
},
2309 {&IID_IDirect3D2
, NULL
, E_NOINTERFACE
},
2310 {&IID_IDirect3D
, NULL
, E_NOINTERFACE
},
2311 {&IID_IDirectDraw7
, NULL
, E_NOINTERFACE
},
2312 {&IID_IDirectDraw4
, NULL
, E_NOINTERFACE
},
2313 {&IID_IDirectDraw3
, NULL
, E_NOINTERFACE
},
2314 {&IID_IDirectDraw2
, NULL
, E_NOINTERFACE
},
2315 {&IID_IDirectDraw
, NULL
, E_NOINTERFACE
},
2316 {&IID_IDirect3DLight
, NULL
, E_NOINTERFACE
},
2317 {&IID_IDirect3DMaterial
, NULL
, E_NOINTERFACE
},
2318 {&IID_IDirect3DMaterial2
, NULL
, E_NOINTERFACE
},
2319 {&IID_IDirect3DMaterial3
, NULL
, E_NOINTERFACE
},
2320 {&IID_IDirect3DExecuteBuffer
, NULL
, E_NOINTERFACE
},
2321 {&IID_IDirect3DViewport
, NULL
, E_NOINTERFACE
},
2322 {&IID_IDirect3DViewport2
, NULL
, E_NOINTERFACE
},
2323 {&IID_IDirect3DViewport3
, NULL
, E_NOINTERFACE
},
2324 {&IID_IDirect3DVertexBuffer
, NULL
, E_NOINTERFACE
},
2325 {&IID_IDirect3DVertexBuffer7
, NULL
, E_NOINTERFACE
},
2326 {&IID_IDirectDrawPalette
, NULL
, E_NOINTERFACE
},
2327 {&IID_IDirectDrawClipper
, NULL
, E_NOINTERFACE
},
2328 {&IID_IUnknown
, &IID_IDirect3DDevice3
, S_OK
},
2331 IDirect3DDevice3
*device
;
2334 window
= create_window();
2335 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
2337 skip("Failed to create a 3D device, skipping test.\n");
2338 DestroyWindow(window
);
2342 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirect3DDevice3
, tests
, ARRAY_SIZE(tests
));
2344 IDirect3DDevice3_Release(device
);
2345 DestroyWindow(window
);
2348 static void test_wndproc(void)
2350 LONG_PTR proc
, ddraw_proc
;
2351 IDirectDraw4
*ddraw
;
2357 static struct message messages
[] =
2359 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2360 {WM_MOVE
, FALSE
, 0},
2361 {WM_SIZE
, FALSE
, 0},
2362 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2363 {WM_ACTIVATE
, FALSE
, 0},
2364 {WM_SETFOCUS
, FALSE
, 0},
2368 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
2369 ddraw
= create_ddraw();
2370 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2372 wc
.lpfnWndProc
= test_proc
;
2373 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2374 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2376 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
2377 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
2379 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2380 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2381 (LONG_PTR
)test_proc
, proc
);
2382 expect_messages
= messages
;
2383 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2384 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2385 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2386 expect_messages
= NULL
;
2387 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2388 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2389 (LONG_PTR
)test_proc
, proc
);
2390 ref
= IDirectDraw4_Release(ddraw
);
2391 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2392 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2393 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2394 (LONG_PTR
)test_proc
, proc
);
2396 /* DDSCL_NORMAL doesn't. */
2397 ddraw
= create_ddraw();
2398 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2399 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2400 (LONG_PTR
)test_proc
, proc
);
2401 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2402 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2403 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2404 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2405 (LONG_PTR
)test_proc
, proc
);
2406 ref
= IDirectDraw4_Release(ddraw
);
2407 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2408 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2409 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2410 (LONG_PTR
)test_proc
, proc
);
2412 /* The original window proc is only restored by ddraw if the current
2413 * window proc matches the one ddraw set. This also affects switching
2414 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
2415 ddraw
= create_ddraw();
2416 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2417 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2418 (LONG_PTR
)test_proc
, proc
);
2419 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2420 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2421 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2422 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2423 (LONG_PTR
)test_proc
, proc
);
2425 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2426 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2427 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2428 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2429 (LONG_PTR
)test_proc
, proc
);
2430 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2431 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2432 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2433 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2434 (LONG_PTR
)test_proc
, proc
);
2435 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2436 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2437 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2438 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2439 (LONG_PTR
)DefWindowProcA
, proc
);
2440 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2441 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2442 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
2443 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2444 (LONG_PTR
)DefWindowProcA
, proc
);
2445 ref
= IDirectDraw4_Release(ddraw
);
2446 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2447 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2448 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2449 (LONG_PTR
)test_proc
, proc
);
2451 ddraw
= create_ddraw();
2452 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2453 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
2454 (LONG_PTR
)test_proc
, proc
);
2455 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2456 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2457 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
2458 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
2459 (LONG_PTR
)test_proc
, proc
);
2460 ref
= IDirectDraw4_Release(ddraw
);
2461 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2462 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
2463 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
2464 (LONG_PTR
)DefWindowProcA
, proc
);
2466 fix_wndproc(window
, (LONG_PTR
)test_proc
);
2467 expect_messages
= NULL
;
2468 DestroyWindow(window
);
2469 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2472 static void test_window_style(void)
2474 LONG style
, exstyle
, tmp
, expected_style
;
2475 RECT fullscreen_rect
, r
;
2476 IDirectDraw4
*ddraw
;
2482 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2483 0, 0, 100, 100, 0, 0, 0, 0);
2484 ddraw
= create_ddraw();
2485 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2487 style
= GetWindowLongA(window
, GWL_STYLE
);
2488 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
2489 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2491 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2492 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2494 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2495 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2496 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2497 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2499 GetWindowRect(window
, &r
);
2500 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
2501 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
2502 GetClientRect(window
, &r
);
2503 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
2505 ret
= SetForegroundWindow(GetDesktopWindow());
2506 ok(ret
, "Failed to set foreground window.\n");
2508 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2509 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2510 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2511 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2513 ret
= SetForegroundWindow(window
);
2514 ok(ret
, "Failed to set foreground window.\n");
2515 /* Windows 7 (but not Vista and XP) shows the window when it receives focus. Hide it again,
2516 * the next tests expect this. */
2517 ShowWindow(window
, SW_HIDE
);
2519 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2520 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2522 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2523 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
2524 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2525 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
2527 ShowWindow(window
, SW_SHOW
);
2528 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2529 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2531 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2532 expected_style
= style
| WS_VISIBLE
;
2533 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2534 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2535 expected_style
= exstyle
| WS_EX_TOPMOST
;
2536 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2538 ret
= SetForegroundWindow(GetDesktopWindow());
2539 ok(ret
, "Failed to set foreground window.\n");
2540 tmp
= GetWindowLongA(window
, GWL_STYLE
);
2541 expected_style
= style
| WS_VISIBLE
| WS_MINIMIZE
;
2542 todo_wine
ok(tmp
== expected_style
, "Expected window style %#x, got %#x.\n", expected_style
, tmp
);
2543 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
2544 expected_style
= exstyle
| WS_EX_TOPMOST
;
2545 todo_wine
ok(tmp
== expected_style
, "Expected window extended style %#x, got %#x.\n", expected_style
, tmp
);
2547 ref
= IDirectDraw4_Release(ddraw
);
2548 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2550 DestroyWindow(window
);
2553 static void test_redundant_mode_set(void)
2555 DDSURFACEDESC2 surface_desc
= {0};
2556 IDirectDraw4
*ddraw
;
2562 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2563 0, 0, 100, 100, 0, 0, 0, 0);
2564 ddraw
= create_ddraw();
2565 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2567 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2568 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2570 surface_desc
.dwSize
= sizeof(surface_desc
);
2571 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
2572 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
2574 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2575 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2576 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2578 GetWindowRect(window
, &q
);
2582 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
2583 GetWindowRect(window
, &s
);
2584 ok(EqualRect(&r
, &s
), "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2586 hr
= IDirectDraw4_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
2587 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, 0, 0);
2588 ok(SUCCEEDED(hr
), "SetDisplayMode failed, hr %#x.\n", hr
);
2590 GetWindowRect(window
, &s
);
2591 ok(EqualRect(&r
, &s
) || broken(EqualRect(&q
, &s
) /* Windows 10 */),
2592 "Expected %s, got %s.\n", wine_dbgstr_rect(&r
), wine_dbgstr_rect(&s
));
2594 ref
= IDirectDraw4_Release(ddraw
);
2595 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2597 DestroyWindow(window
);
2600 static SIZE screen_size
, screen_size2
;
2602 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2604 if (message
== WM_SIZE
)
2606 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2607 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2610 return test_proc(hwnd
, message
, wparam
, lparam
);
2613 static LRESULT CALLBACK
mode_set_proc2(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2615 if (message
== WM_SIZE
)
2617 screen_size2
.cx
= GetSystemMetrics(SM_CXSCREEN
);
2618 screen_size2
.cy
= GetSystemMetrics(SM_CYSCREEN
);
2621 return test_proc(hwnd
, message
, wparam
, lparam
);
2624 struct test_coop_level_mode_set_enum_param
2626 DWORD ddraw_width
, ddraw_height
, user32_width
, user32_height
;
2629 static HRESULT CALLBACK
test_coop_level_mode_set_enum_cb(DDSURFACEDESC2
*surface_desc
, void *context
)
2631 struct test_coop_level_mode_set_enum_param
*param
= context
;
2633 if (U1(U4(*surface_desc
).ddpfPixelFormat
).dwRGBBitCount
!= registry_mode
.dmBitsPerPel
)
2634 return DDENUMRET_OK
;
2635 if (surface_desc
->dwWidth
== registry_mode
.dmPelsWidth
2636 && surface_desc
->dwHeight
== registry_mode
.dmPelsHeight
)
2637 return DDENUMRET_OK
;
2639 if (!param
->ddraw_width
)
2641 param
->ddraw_width
= surface_desc
->dwWidth
;
2642 param
->ddraw_height
= surface_desc
->dwHeight
;
2643 return DDENUMRET_OK
;
2645 if (surface_desc
->dwWidth
== param
->ddraw_width
&& surface_desc
->dwHeight
== param
->ddraw_height
)
2646 return DDENUMRET_OK
;
2648 param
->user32_width
= surface_desc
->dwWidth
;
2649 param
->user32_height
= surface_desc
->dwHeight
;
2650 return DDENUMRET_CANCEL
;
2653 static void test_coop_level_mode_set(void)
2655 IDirectDrawSurface4
*primary
;
2656 RECT registry_rect
, ddraw_rect
, user32_rect
, r
;
2657 IDirectDraw4
*ddraw
;
2658 DDSURFACEDESC2 ddsd
;
2660 HWND window
, window2
;
2664 struct test_coop_level_mode_set_enum_param param
;
2669 static const struct message exclusive_messages
[] =
2671 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2672 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2673 {WM_SIZE
, FALSE
, 0},
2674 {WM_DISPLAYCHANGE
, FALSE
, 0},
2677 static const struct message exclusive_focus_loss_messages
[] =
2679 {WM_ACTIVATE
, TRUE
, WA_INACTIVE
},
2680 {WM_DISPLAYCHANGE
, FALSE
, 0},
2681 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2682 /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of
2683 * SW_MINIMIZED, causing a recursive window activation that does not
2684 * produce the same result in Wine yet. Ignore the difference for now.
2685 * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */
2686 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2687 {WM_MOVE
, FALSE
, 0},
2688 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2689 {WM_ACTIVATEAPP
, TRUE
, FALSE
},
2692 static const struct message exclusive_focus_restore_messages
[] =
2694 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* From the ShowWindow(SW_RESTORE). */
2695 {WM_WINDOWPOSCHANGING
, FALSE
, 0}, /* Generated by ddraw, matches d3d9 behavior. */
2696 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching previous message. */
2697 {WM_SIZE
, FALSE
, 0}, /* DefWindowProc. */
2698 {WM_DISPLAYCHANGE
, FALSE
, 0}, /* Ddraw restores mode. */
2699 /* Native redundantly sets the window size here. */
2700 {WM_ACTIVATEAPP
, TRUE
, TRUE
}, /* End of ddraw's hooks. */
2701 {WM_WINDOWPOSCHANGED
, FALSE
, 0}, /* Matching the one from ShowWindow. */
2702 {WM_MOVE
, FALSE
, 0}, /* DefWindowProc. */
2703 {WM_SIZE
, TRUE
, SIZE_RESTORED
}, /* DefWindowProc. */
2706 static const struct message sc_restore_messages
[] =
2708 {WM_SYSCOMMAND
, TRUE
, SC_RESTORE
},
2709 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2710 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2711 {WM_SIZE
, TRUE
, SIZE_RESTORED
},
2714 static const struct message sc_minimize_messages
[] =
2716 {WM_SYSCOMMAND
, TRUE
, SC_MINIMIZE
},
2717 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2718 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2719 {WM_SIZE
, TRUE
, SIZE_MINIMIZED
},
2722 static const struct message sc_maximize_messages
[] =
2724 {WM_SYSCOMMAND
, TRUE
, SC_MAXIMIZE
},
2725 {WM_WINDOWPOSCHANGING
, FALSE
, 0},
2726 {WM_WINDOWPOSCHANGED
, FALSE
, 0},
2727 {WM_SIZE
, TRUE
, SIZE_MAXIMIZED
},
2731 static const struct message normal_messages
[] =
2733 {WM_DISPLAYCHANGE
, FALSE
, 0},
2737 ddraw
= create_ddraw();
2738 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2740 memset(¶m
, 0, sizeof(param
));
2741 hr
= IDirectDraw4_EnumDisplayModes(ddraw
, 0, NULL
, ¶m
, test_coop_level_mode_set_enum_cb
);
2742 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#x.\n", hr
);
2743 ref
= IDirectDraw4_Release(ddraw
);
2744 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2746 if (!param
.user32_height
)
2748 skip("Fewer than 3 different modes supported, skipping mode restore test.\n");
2752 SetRect(®istry_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
2753 SetRect(&ddraw_rect
, 0, 0, param
.ddraw_width
, param
.ddraw_height
);
2754 SetRect(&user32_rect
, 0, 0, param
.user32_width
, param
.user32_height
);
2756 memset(&devmode
, 0, sizeof(devmode
));
2757 devmode
.dmSize
= sizeof(devmode
);
2758 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
2759 devmode
.dmPelsWidth
= param
.user32_width
;
2760 devmode
.dmPelsHeight
= param
.user32_height
;
2761 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2762 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2764 ddraw
= create_ddraw();
2765 ok(!!ddraw
, "Failed to create a ddraw object.\n");
2767 wc
.lpfnWndProc
= mode_set_proc
;
2768 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
2769 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2770 wc
.lpfnWndProc
= mode_set_proc2
;
2771 wc
.lpszClassName
= "ddraw_test_wndproc_wc2";
2772 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
2774 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2775 0, 0, 100, 100, 0, 0, 0, 0);
2776 window2
= CreateWindowA("ddraw_test_wndproc_wc2", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2777 0, 0, 100, 100, 0, 0, 0, 0);
2779 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2780 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2782 GetWindowRect(window
, &r
);
2783 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2784 wine_dbgstr_rect(&r
));
2786 memset(&ddsd
, 0, sizeof(ddsd
));
2787 ddsd
.dwSize
= sizeof(ddsd
);
2788 ddsd
.dwFlags
= DDSD_CAPS
;
2789 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2791 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2792 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2793 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2794 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2795 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2796 param
.user32_width
, ddsd
.dwWidth
);
2797 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2798 param
.user32_height
, ddsd
.dwHeight
);
2800 GetWindowRect(window
, &r
);
2801 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2802 wine_dbgstr_rect(&r
));
2804 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2805 expect_messages
= exclusive_messages
;
2809 hr
= IDirectDrawSurface4_IsLost(primary
);
2810 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2811 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
2812 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
2813 hr
= IDirectDrawSurface4_IsLost(primary
);
2814 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2816 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2817 expect_messages
= NULL
;
2818 ok(screen_size
.cx
== param
.ddraw_width
&& screen_size
.cy
== param
.ddraw_height
,
2819 "Expected screen size %ux%u, got %ux%u.\n",
2820 param
.ddraw_width
, param
.ddraw_height
, screen_size
.cx
, screen_size
.cy
);
2822 GetWindowRect(window
, &r
);
2823 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2824 wine_dbgstr_rect(&r
));
2826 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2827 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2828 ok(ddsd
.dwWidth
== param
.user32_width
, "Expected surface width %u, got %u.\n",
2829 param
.user32_width
, ddsd
.dwWidth
);
2830 ok(ddsd
.dwHeight
== param
.user32_height
, "Expected surface height %u, got %u.\n",
2831 param
.user32_height
, ddsd
.dwHeight
);
2832 IDirectDrawSurface4_Release(primary
);
2834 memset(&ddsd
, 0, sizeof(ddsd
));
2835 ddsd
.dwSize
= sizeof(ddsd
);
2836 ddsd
.dwFlags
= DDSD_CAPS
;
2837 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2839 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2840 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2841 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2842 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2843 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2844 param
.ddraw_width
, ddsd
.dwWidth
);
2845 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2846 param
.ddraw_height
, ddsd
.dwHeight
);
2848 GetWindowRect(window
, &r
);
2849 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2850 wine_dbgstr_rect(&r
));
2852 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2853 expect_messages
= exclusive_messages
;
2857 hr
= IDirectDrawSurface4_IsLost(primary
);
2858 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
2859 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
2860 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2861 hr
= IDirectDrawSurface4_IsLost(primary
);
2862 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2864 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2865 expect_messages
= NULL
;
2866 ok(screen_size
.cx
== param
.user32_width
&& screen_size
.cy
== param
.user32_height
,
2867 "Expected screen size %ux%u, got %ux%u.\n",
2868 param
.user32_width
, param
.user32_height
, screen_size
.cx
, screen_size
.cy
);
2870 GetWindowRect(window
, &r
);
2871 ok(EqualRect(&r
, &user32_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&user32_rect
),
2872 wine_dbgstr_rect(&r
));
2874 expect_messages
= exclusive_focus_loss_messages
;
2875 ret
= SetForegroundWindow(GetDesktopWindow());
2876 ok(ret
, "Failed to set foreground window.\n");
2877 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2878 memset(&devmode
, 0, sizeof(devmode
));
2879 devmode
.dmSize
= sizeof(devmode
);
2880 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2881 ok(ret
, "Failed to get display mode.\n");
2882 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
2883 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpect screen size %ux%u.\n",
2884 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2886 expect_messages
= exclusive_focus_restore_messages
;
2887 ShowWindow(window
, SW_RESTORE
);
2888 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2890 GetWindowRect(window
, &r
);
2891 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
2892 wine_dbgstr_rect(&r
));
2893 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
2894 ok(ret
, "Failed to get display mode.\n");
2895 ok(devmode
.dmPelsWidth
== param
.ddraw_width
2896 && devmode
.dmPelsHeight
== param
.ddraw_height
, "Got unexpect screen size %ux%u.\n",
2897 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
2899 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2900 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2901 /* Normally the primary should be restored here. Unfortunately this causes the
2902 * GetSurfaceDesc call after the next display mode change to crash on the Windows 8
2903 * testbot. Another Restore call would presumably avoid the crash, but it also moots
2904 * the point of the GetSurfaceDesc call. */
2906 expect_messages
= sc_minimize_messages
;
2907 SendMessageA(window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
2908 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2909 expect_messages
= NULL
;
2911 expect_messages
= sc_restore_messages
;
2912 SendMessageA(window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
2913 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2914 expect_messages
= NULL
;
2916 expect_messages
= sc_maximize_messages
;
2917 SendMessageA(window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
2918 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2919 expect_messages
= NULL
;
2921 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2922 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2924 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
2925 expect_messages
= exclusive_messages
;
2929 hr
= IDirectDrawSurface4_IsLost(primary
);
2930 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2931 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
2932 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2933 hr
= IDirectDrawSurface4_IsLost(primary
);
2934 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
2936 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
2937 expect_messages
= NULL
;
2938 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
2939 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
2940 "Expected screen size %ux%u, got %ux%u.\n",
2941 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size
.cx
, screen_size
.cy
);
2943 GetWindowRect(window
, &r
);
2944 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2945 wine_dbgstr_rect(&r
));
2947 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2948 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2949 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
2950 param
.ddraw_width
, ddsd
.dwWidth
);
2951 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
2952 param
.ddraw_height
, ddsd
.dwHeight
);
2953 IDirectDrawSurface4_Release(primary
);
2956 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
2957 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
2959 memset(&ddsd
, 0, sizeof(ddsd
));
2960 ddsd
.dwSize
= sizeof(ddsd
);
2961 ddsd
.dwFlags
= DDSD_CAPS
;
2962 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2964 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2965 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2966 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2967 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2968 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2969 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2970 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2971 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2973 GetWindowRect(window
, &r
);
2974 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2975 wine_dbgstr_rect(&r
));
2977 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2978 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2980 GetWindowRect(window
, &r
);
2981 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
2982 wine_dbgstr_rect(&r
));
2984 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
2985 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2986 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
2987 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
2988 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
2989 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
2990 IDirectDrawSurface4_Release(primary
);
2992 memset(&ddsd
, 0, sizeof(ddsd
));
2993 ddsd
.dwSize
= sizeof(ddsd
);
2994 ddsd
.dwFlags
= DDSD_CAPS
;
2995 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2997 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2998 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2999 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3000 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3001 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3002 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3003 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3004 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3006 GetWindowRect(window
, &r
);
3007 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3008 wine_dbgstr_rect(&r
));
3010 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3011 expect_messages
= normal_messages
;
3015 hr
= IDirectDrawSurface4_IsLost(primary
);
3016 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3017 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3018 devmode
.dmPelsWidth
= param
.user32_width
;
3019 devmode
.dmPelsHeight
= param
.user32_height
;
3020 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3021 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3022 hr
= IDirectDrawSurface4_IsLost(primary
);
3023 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3025 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3026 expect_messages
= NULL
;
3027 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3029 GetWindowRect(window
, &r
);
3030 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3031 wine_dbgstr_rect(&r
));
3033 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3034 expect_messages
= normal_messages
;
3038 hr
= IDirectDrawSurface4_Restore(primary
);
3039 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3040 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3041 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3042 hr
= IDirectDrawSurface4_Restore(primary
);
3043 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3044 hr
= IDirectDrawSurface4_IsLost(primary
);
3045 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3047 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3048 expect_messages
= NULL
;
3049 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3051 GetWindowRect(window
, &r
);
3052 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3053 wine_dbgstr_rect(&r
));
3055 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3056 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3057 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3058 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3059 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3060 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3061 IDirectDrawSurface4_Release(primary
);
3063 memset(&ddsd
, 0, sizeof(ddsd
));
3064 ddsd
.dwSize
= sizeof(ddsd
);
3065 ddsd
.dwFlags
= DDSD_CAPS
;
3066 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3068 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3069 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3070 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3071 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3072 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3073 param
.ddraw_width
, ddsd
.dwWidth
);
3074 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3075 param
.ddraw_height
, ddsd
.dwHeight
);
3077 GetWindowRect(window
, &r
);
3078 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3079 wine_dbgstr_rect(&r
));
3081 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3082 expect_messages
= normal_messages
;
3086 hr
= IDirectDrawSurface4_IsLost(primary
);
3087 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3088 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3089 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3090 hr
= IDirectDrawSurface4_IsLost(primary
);
3091 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3093 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3094 expect_messages
= NULL
;
3095 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3097 GetWindowRect(window
, &r
);
3098 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3099 wine_dbgstr_rect(&r
));
3101 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3102 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3103 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3104 param
.ddraw_width
, ddsd
.dwWidth
);
3105 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3106 param
.ddraw_height
, ddsd
.dwHeight
);
3107 IDirectDrawSurface4_Release(primary
);
3109 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3110 ok(ret
, "Failed to get display mode.\n");
3111 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3112 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3113 "Expected resolution %ux%u, got %ux%u.\n",
3114 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3115 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3116 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3117 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3119 memset(&ddsd
, 0, sizeof(ddsd
));
3120 ddsd
.dwSize
= sizeof(ddsd
);
3121 ddsd
.dwFlags
= DDSD_CAPS
;
3122 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3124 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3125 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3126 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3127 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3128 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3129 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3130 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3131 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3133 GetWindowRect(window
, &r
);
3134 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3135 wine_dbgstr_rect(&r
));
3137 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
3138 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
3139 * not DDSCL_FULLSCREEN. */
3140 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3141 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3143 GetWindowRect(window
, &r
);
3144 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3145 wine_dbgstr_rect(&r
));
3147 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3148 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3149 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3150 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3151 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3152 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3153 IDirectDrawSurface4_Release(primary
);
3155 memset(&ddsd
, 0, sizeof(ddsd
));
3156 ddsd
.dwSize
= sizeof(ddsd
);
3157 ddsd
.dwFlags
= DDSD_CAPS
;
3158 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3160 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3161 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3162 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3163 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3164 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3165 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3166 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3167 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3169 GetWindowRect(window
, &r
);
3170 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3171 wine_dbgstr_rect(&r
));
3173 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3174 expect_messages
= normal_messages
;
3178 hr
= IDirectDrawSurface4_IsLost(primary
);
3179 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3180 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3181 devmode
.dmPelsWidth
= param
.user32_width
;
3182 devmode
.dmPelsHeight
= param
.user32_height
;
3183 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3184 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3185 hr
= IDirectDrawSurface4_IsLost(primary
);
3186 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3188 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3189 expect_messages
= NULL
;
3190 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3192 GetWindowRect(window
, &r
);
3193 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3194 wine_dbgstr_rect(&r
));
3196 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3197 expect_messages
= normal_messages
;
3201 hr
= IDirectDrawSurface4_Restore(primary
);
3202 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3203 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3204 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3205 hr
= IDirectDrawSurface4_Restore(primary
);
3206 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
3207 hr
= IDirectDrawSurface4_IsLost(primary
);
3208 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3210 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3211 expect_messages
= NULL
;
3212 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3214 GetWindowRect(window
, &r
);
3215 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3216 wine_dbgstr_rect(&r
));
3218 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3219 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3220 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3221 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3222 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3223 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3224 IDirectDrawSurface4_Release(primary
);
3226 memset(&ddsd
, 0, sizeof(ddsd
));
3227 ddsd
.dwSize
= sizeof(ddsd
);
3228 ddsd
.dwFlags
= DDSD_CAPS
;
3229 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3231 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3232 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3233 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3234 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3235 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3236 param
.ddraw_width
, ddsd
.dwWidth
);
3237 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3238 param
.ddraw_height
, ddsd
.dwHeight
);
3240 GetWindowRect(window
, &r
);
3241 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3242 wine_dbgstr_rect(&r
));
3244 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3245 expect_messages
= normal_messages
;
3249 hr
= IDirectDrawSurface4_IsLost(primary
);
3250 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
3251 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3252 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3253 hr
= IDirectDrawSurface4_IsLost(primary
);
3254 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
3256 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3257 expect_messages
= NULL
;
3258 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
3260 GetWindowRect(window
, &r
);
3261 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3262 wine_dbgstr_rect(&r
));
3264 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3265 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3266 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3267 param
.ddraw_width
, ddsd
.dwWidth
);
3268 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3269 param
.ddraw_height
, ddsd
.dwHeight
);
3270 IDirectDrawSurface4_Release(primary
);
3272 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3273 ok(ret
, "Failed to get display mode.\n");
3274 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3275 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
3276 "Expected resolution %ux%u, got %ux%u.\n",
3277 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3278 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3279 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3280 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#x.\n", change_ret
);
3282 memset(&ddsd
, 0, sizeof(ddsd
));
3283 ddsd
.dwSize
= sizeof(ddsd
);
3284 ddsd
.dwFlags
= DDSD_CAPS
;
3285 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3287 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3288 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3289 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3290 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3291 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3292 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3293 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3294 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3295 IDirectDrawSurface4_Release(primary
);
3297 GetWindowRect(window
, &r
);
3298 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3299 wine_dbgstr_rect(&r
));
3301 /* Changing the coop level from EXCLUSIVE to NORMAL restores the screen resolution */
3302 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3303 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3304 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3305 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3307 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3308 expect_messages
= exclusive_messages
;
3312 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3313 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3315 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3316 expect_messages
= NULL
;
3317 ok(screen_size
.cx
== registry_mode
.dmPelsWidth
3318 && screen_size
.cy
== registry_mode
.dmPelsHeight
,
3319 "Expected screen size %ux%u, got %ux%u.\n",
3320 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
,
3321 screen_size
.cx
, screen_size
.cy
);
3323 GetWindowRect(window
, &r
);
3324 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3325 wine_dbgstr_rect(&r
));
3327 memset(&ddsd
, 0, sizeof(ddsd
));
3328 ddsd
.dwSize
= sizeof(ddsd
);
3329 ddsd
.dwFlags
= DDSD_CAPS
;
3330 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3332 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3333 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3334 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3335 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3336 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3337 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3338 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3339 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3340 IDirectDrawSurface4_Release(primary
);
3342 /* The screen restore is a property of DDSCL_EXCLUSIVE */
3343 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
3344 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3345 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3346 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3348 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
3349 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3351 memset(&ddsd
, 0, sizeof(ddsd
));
3352 ddsd
.dwSize
= sizeof(ddsd
);
3353 ddsd
.dwFlags
= DDSD_CAPS
;
3354 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3356 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3357 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3358 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3359 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3360 ok(ddsd
.dwWidth
== param
.ddraw_width
, "Expected surface width %u, got %u.\n",
3361 param
.ddraw_width
, ddsd
.dwWidth
);
3362 ok(ddsd
.dwHeight
== param
.ddraw_height
, "Expected surface height %u, got %u.\n",
3363 param
.ddraw_height
, ddsd
.dwHeight
);
3364 IDirectDrawSurface4_Release(primary
);
3366 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
3367 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
3369 /* If the window is changed at the same time, messages are sent to the new window. */
3370 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3371 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3372 hr
= set_display_mode(ddraw
, param
.ddraw_width
, param
.ddraw_height
);
3373 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3375 PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
);
3376 expect_messages
= exclusive_messages
;
3379 screen_size2
.cx
= 0;
3380 screen_size2
.cy
= 0;
3382 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3383 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3385 ok(!expect_messages
->message
, "Expected message %#x, but didn't receive it.\n", expect_messages
->message
);
3386 expect_messages
= NULL
;
3387 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unexpected screen size %ux%u.\n",
3388 screen_size
.cx
, screen_size
.cy
);
3389 ok(screen_size2
.cx
== registry_mode
.dmPelsWidth
&& screen_size2
.cy
== registry_mode
.dmPelsHeight
,
3390 "Expected screen size 2 %ux%u, got %ux%u.\n",
3391 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, screen_size2
.cx
, screen_size2
.cy
);
3393 GetWindowRect(window
, &r
);
3394 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3395 wine_dbgstr_rect(&r
));
3396 GetWindowRect(window2
, &r
);
3397 ok(EqualRect(&r
, ®istry_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(®istry_rect
),
3398 wine_dbgstr_rect(&r
));
3400 memset(&ddsd
, 0, sizeof(ddsd
));
3401 ddsd
.dwSize
= sizeof(ddsd
);
3402 ddsd
.dwFlags
= DDSD_CAPS
;
3403 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3405 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
3406 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
3407 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &ddsd
);
3408 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
3409 ok(ddsd
.dwWidth
== registry_mode
.dmPelsWidth
, "Expected surface width %u, got %u.\n",
3410 registry_mode
.dmPelsWidth
, ddsd
.dwWidth
);
3411 ok(ddsd
.dwHeight
== registry_mode
.dmPelsHeight
, "Expected surface height %u, got %u.\n",
3412 registry_mode
.dmPelsHeight
, ddsd
.dwHeight
);
3413 IDirectDrawSurface4_Release(primary
);
3415 ref
= IDirectDraw4_Release(ddraw
);
3416 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3418 GetWindowRect(window
, &r
);
3419 ok(EqualRect(&r
, &ddraw_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&ddraw_rect
),
3420 wine_dbgstr_rect(&r
));
3422 expect_messages
= NULL
;
3423 DestroyWindow(window
);
3424 DestroyWindow(window2
);
3425 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
3426 UnregisterClassA("ddraw_test_wndproc_wc2", GetModuleHandleA(NULL
));
3429 static void test_coop_level_mode_set_multi(void)
3431 IDirectDraw4
*ddraw1
, *ddraw2
;
3437 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
3438 0, 0, 100, 100, 0, 0, 0, 0);
3439 ddraw1
= create_ddraw();
3440 ok(!!ddraw1
, "Failed to create a ddraw object.\n");
3442 /* With just a single ddraw object, the display mode is restored on
3444 hr
= set_display_mode(ddraw1
, 800, 600);
3445 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3446 w
= GetSystemMetrics(SM_CXSCREEN
);
3447 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3448 h
= GetSystemMetrics(SM_CYSCREEN
);
3449 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3451 ref
= IDirectDraw4_Release(ddraw1
);
3452 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3453 w
= GetSystemMetrics(SM_CXSCREEN
);
3454 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3455 h
= GetSystemMetrics(SM_CYSCREEN
);
3456 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3458 /* When there are multiple ddraw objects, the display mode is restored to
3459 * the initial mode, before the first SetDisplayMode() call. */
3460 ddraw1
= create_ddraw();
3461 hr
= set_display_mode(ddraw1
, 800, 600);
3462 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3463 w
= GetSystemMetrics(SM_CXSCREEN
);
3464 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3465 h
= GetSystemMetrics(SM_CYSCREEN
);
3466 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3468 ddraw2
= create_ddraw();
3469 hr
= set_display_mode(ddraw2
, 640, 480);
3470 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3471 w
= GetSystemMetrics(SM_CXSCREEN
);
3472 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3473 h
= GetSystemMetrics(SM_CYSCREEN
);
3474 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3476 ref
= IDirectDraw4_Release(ddraw2
);
3477 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3478 w
= GetSystemMetrics(SM_CXSCREEN
);
3479 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3480 h
= GetSystemMetrics(SM_CYSCREEN
);
3481 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3483 ref
= IDirectDraw4_Release(ddraw1
);
3484 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3485 w
= GetSystemMetrics(SM_CXSCREEN
);
3486 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3487 h
= GetSystemMetrics(SM_CYSCREEN
);
3488 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3490 /* Regardless of release ordering. */
3491 ddraw1
= create_ddraw();
3492 hr
= set_display_mode(ddraw1
, 800, 600);
3493 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3494 w
= GetSystemMetrics(SM_CXSCREEN
);
3495 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3496 h
= GetSystemMetrics(SM_CYSCREEN
);
3497 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3499 ddraw2
= create_ddraw();
3500 hr
= set_display_mode(ddraw2
, 640, 480);
3501 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3502 w
= GetSystemMetrics(SM_CXSCREEN
);
3503 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3504 h
= GetSystemMetrics(SM_CYSCREEN
);
3505 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3507 ref
= IDirectDraw4_Release(ddraw1
);
3508 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3509 w
= GetSystemMetrics(SM_CXSCREEN
);
3510 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3511 h
= GetSystemMetrics(SM_CYSCREEN
);
3512 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3514 ref
= IDirectDraw4_Release(ddraw2
);
3515 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3516 w
= GetSystemMetrics(SM_CXSCREEN
);
3517 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3518 h
= GetSystemMetrics(SM_CYSCREEN
);
3519 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3521 /* But only for ddraw objects that called SetDisplayMode(). */
3522 ddraw1
= create_ddraw();
3523 ddraw2
= create_ddraw();
3524 hr
= set_display_mode(ddraw2
, 640, 480);
3525 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3526 w
= GetSystemMetrics(SM_CXSCREEN
);
3527 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3528 h
= GetSystemMetrics(SM_CYSCREEN
);
3529 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3531 ref
= IDirectDraw4_Release(ddraw1
);
3532 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3533 w
= GetSystemMetrics(SM_CXSCREEN
);
3534 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3535 h
= GetSystemMetrics(SM_CYSCREEN
);
3536 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3538 ref
= IDirectDraw4_Release(ddraw2
);
3539 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3540 w
= GetSystemMetrics(SM_CXSCREEN
);
3541 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3542 h
= GetSystemMetrics(SM_CYSCREEN
);
3543 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3545 /* If there's a ddraw object that's currently in exclusive mode, it blocks
3546 * restoring the display mode. */
3547 ddraw1
= create_ddraw();
3548 hr
= set_display_mode(ddraw1
, 800, 600);
3549 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3550 w
= GetSystemMetrics(SM_CXSCREEN
);
3551 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3552 h
= GetSystemMetrics(SM_CYSCREEN
);
3553 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3555 ddraw2
= create_ddraw();
3556 hr
= set_display_mode(ddraw2
, 640, 480);
3557 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3558 w
= GetSystemMetrics(SM_CXSCREEN
);
3559 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3560 h
= GetSystemMetrics(SM_CYSCREEN
);
3561 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3563 hr
= IDirectDraw4_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3564 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3566 ref
= IDirectDraw4_Release(ddraw1
);
3567 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3568 w
= GetSystemMetrics(SM_CXSCREEN
);
3569 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
3570 h
= GetSystemMetrics(SM_CYSCREEN
);
3571 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
3573 ref
= IDirectDraw4_Release(ddraw2
);
3574 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3575 w
= GetSystemMetrics(SM_CXSCREEN
);
3576 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3577 h
= GetSystemMetrics(SM_CYSCREEN
);
3578 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3580 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
3581 ddraw1
= create_ddraw();
3582 hr
= set_display_mode(ddraw1
, 800, 600);
3583 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
3584 w
= GetSystemMetrics(SM_CXSCREEN
);
3585 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
3586 h
= GetSystemMetrics(SM_CYSCREEN
);
3587 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
3589 hr
= IDirectDraw4_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
3590 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
3592 ddraw2
= create_ddraw();
3593 hr
= set_display_mode(ddraw2
, 640, 480);
3594 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
3596 ref
= IDirectDraw4_Release(ddraw1
);
3597 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3598 w
= GetSystemMetrics(SM_CXSCREEN
);
3599 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3600 h
= GetSystemMetrics(SM_CYSCREEN
);
3601 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3603 ref
= IDirectDraw4_Release(ddraw2
);
3604 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
3605 w
= GetSystemMetrics(SM_CXSCREEN
);
3606 ok(w
== registry_mode
.dmPelsWidth
, "Got unexpected screen width %u.\n", w
);
3607 h
= GetSystemMetrics(SM_CYSCREEN
);
3608 ok(h
== registry_mode
.dmPelsHeight
, "Got unexpected screen height %u.\n", h
);
3610 DestroyWindow(window
);
3613 static void test_initialize(void)
3615 IDirectDraw4
*ddraw
;
3618 ddraw
= create_ddraw();
3619 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3621 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3622 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
3623 IDirectDraw4_Release(ddraw
);
3626 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw4
, (void **)&ddraw
);
3627 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw4 instance, hr %#x.\n", hr
);
3628 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3629 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
3630 hr
= IDirectDraw4_Initialize(ddraw
, NULL
);
3631 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
3632 IDirectDraw4_Release(ddraw
);
3636 static void test_coop_level_surf_create(void)
3638 IDirectDrawSurface4
*surface
;
3639 IDirectDraw4
*ddraw
;
3640 DDSURFACEDESC2 ddsd
;
3643 ddraw
= create_ddraw();
3644 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3646 memset(&ddsd
, 0, sizeof(ddsd
));
3647 ddsd
.dwSize
= sizeof(ddsd
);
3648 ddsd
.dwFlags
= DDSD_CAPS
;
3649 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
3650 surface
= (void *)0xdeadbeef;
3651 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
3652 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
3653 ok(surface
== (void *)0xdeadbeef, "Got unexpected surface %p.\n", surface
);
3655 IDirectDraw4_Release(ddraw
);
3658 static void test_vb_discard(void)
3660 static const struct vec4 quad
[] =
3662 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
3663 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
3664 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
3665 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
3668 IDirect3DDevice3
*device
;
3670 IDirect3DVertexBuffer
*buffer
;
3673 D3DVERTEXBUFFERDESC desc
;
3675 static const unsigned int vbsize
= 16;
3678 window
= create_window();
3679 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3681 skip("Failed to create a 3D device, skipping test.\n");
3682 DestroyWindow(window
);
3686 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
3687 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
3689 memset(&desc
, 0, sizeof(desc
));
3690 desc
.dwSize
= sizeof(desc
);
3691 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
3692 desc
.dwFVF
= D3DFVF_XYZRHW
;
3693 desc
.dwNumVertices
= vbsize
;
3694 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
3695 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
3697 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3698 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3699 memcpy(data
, quad
, sizeof(quad
));
3700 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3701 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3703 hr
= IDirect3DDevice3_BeginScene(device
);
3704 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3705 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
3706 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3707 hr
= IDirect3DDevice3_EndScene(device
);
3708 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3710 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3711 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3712 memset(data
, 0xaa, sizeof(struct vec4
) * vbsize
);
3713 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3714 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3716 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&data
, NULL
);
3717 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
3718 for (i
= 0; i
< sizeof(struct vec4
) * vbsize
; i
++)
3720 if (data
[i
] != 0xaa)
3722 ok(FALSE
, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i
, data
[i
]);
3726 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
3727 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
3729 IDirect3DVertexBuffer_Release(buffer
);
3730 IDirect3D3_Release(d3d
);
3731 IDirect3DDevice3_Release(device
);
3732 DestroyWindow(window
);
3735 static void test_coop_level_multi_window(void)
3737 HWND window1
, window2
;
3738 IDirectDraw4
*ddraw
;
3741 window1
= create_window();
3742 window2
= create_window();
3743 ddraw
= create_ddraw();
3744 ok(!!ddraw
, "Failed to create a ddraw object.\n");
3746 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
3747 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3748 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
3749 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
3750 ok(IsWindow(window1
), "Window 1 was destroyed.\n");
3751 ok(IsWindow(window2
), "Window 2 was destroyed.\n");
3753 IDirectDraw4_Release(ddraw
);
3754 DestroyWindow(window2
);
3755 DestroyWindow(window1
);
3758 static void test_draw_strided(void)
3760 static struct vec3 position
[] =
3767 static DWORD diffuse
[] =
3769 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3771 static WORD indices
[] =
3776 IDirectDrawSurface4
*rt
;
3777 IDirect3DDevice3
*device
;
3781 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
3782 IDirect3DViewport3
*viewport
;
3783 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3785 window
= create_window();
3786 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3788 skip("Failed to create a 3D device, skipping test.\n");
3789 DestroyWindow(window
);
3793 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
3794 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3795 viewport
= create_viewport(device
, 0, 0, 640, 480);
3796 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
3797 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
3798 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
3799 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
3801 hr
= IDirect3DDevice3_BeginScene(device
);
3802 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3804 memset(&strided
, 0x55, sizeof(strided
));
3805 strided
.position
.lpvData
= position
;
3806 strided
.position
.dwStride
= sizeof(*position
);
3807 strided
.diffuse
.lpvData
= diffuse
;
3808 strided
.diffuse
.dwStride
= sizeof(*diffuse
);
3809 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
, D3DPT_TRIANGLELIST
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
3810 &strided
, 4, indices
, 6, 0);
3811 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3813 hr
= IDirect3DDevice3_EndScene(device
);
3814 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
3816 color
= get_surface_color(rt
, 320, 240);
3817 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
3819 IDirect3DViewport3_Release(viewport
);
3820 IDirectDrawSurface4_Release(rt
);
3821 IDirect3DDevice3_Release(device
);
3822 DestroyWindow(window
);
3825 static void test_lighting(void)
3827 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
3828 static D3DMATRIX mat
=
3830 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3831 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3832 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3833 0.0f
, 0.0f
, 0.0f
, 1.0f
,
3837 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3838 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3839 1.0f
, 0.0f
, 1.0f
, 0.0f
,
3840 0.0f
, 0.0f
, 0.5f
, 1.0f
,
3844 0.0f
, 0.0f
, 1.0f
, 0.0f
,
3845 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3846 -1.0f
, 0.0f
, 0.0f
, 0.0f
,
3847 10.f
, 10.0f
, 10.0f
, 1.0f
,
3851 1.0f
, 0.0f
, 0.0f
, 0.0f
,
3852 0.0f
, 1.0f
, 0.0f
, 0.0f
,
3853 0.0f
, 0.0f
, 1.0f
, -1.0f
,
3854 10.f
, 10.0f
, 10.0f
, 0.0f
,
3858 struct vec3 position
;
3863 {{-1.0f
, -1.0f
, 0.1f
}, 0xffff0000},
3864 {{-1.0f
, 0.0f
, 0.1f
}, 0xffff0000},
3865 {{ 0.0f
, 0.0f
, 0.1f
}, 0xffff0000},
3866 {{ 0.0f
, -1.0f
, 0.1f
}, 0xffff0000},
3870 {{-1.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
3871 {{-1.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
3872 {{ 0.0f
, 1.0f
, 0.1f
}, 0xff00ff00},
3873 {{ 0.0f
, 0.0f
, 0.1f
}, 0xff00ff00},
3877 struct vec3 position
;
3883 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3884 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3885 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3886 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
3890 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3891 {{0.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3892 {{1.0f
, 1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3893 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xffffff00},
3897 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3898 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3899 {{ 1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3900 {{ 1.0f
, -1.0f
, 0.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3904 {{-10.0f
, -11.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3905 {{-10.0f
, -9.0f
, 11.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3906 {{-10.0f
, -9.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3907 {{-10.0f
, -11.0f
, 9.0f
}, {-1.0f
, 0.0f
, 0.0f
}, 0xff0000ff},
3911 {{-11.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3912 {{-11.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3913 {{ -9.0f
, -9.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3914 {{ -9.0f
, -11.0f
, -10.0f
}, {0.0f
, 0.0f
, -1.0f
}, 0xff0000ff},
3916 static WORD indices
[] = {0, 1, 2, 2, 3, 0};
3919 D3DMATRIX
*world_matrix
;
3922 const char *message
;
3926 {&mat
, nquad
, 0x000000ff, "Lit quad with light"},
3927 {&mat_singular
, nquad
, 0x000000b4, "Lit quad with singular world matrix"},
3928 {&mat_transf
, rotatedquad
, 0x000000ff, "Lit quad with transformation matrix"},
3929 {&mat_nonaffine
, translatedquad
, 0x000000ff, "Lit quad with non-affine matrix"},
3934 IDirect3DDevice3
*device
;
3935 IDirectDrawSurface4
*rt
;
3936 IDirect3DViewport3
*viewport
;
3937 IDirect3DMaterial3
*material
;
3938 IDirect3DLight
*light
;
3939 D3DMATERIALHANDLE mat_handle
;
3940 D3DLIGHT2 light_desc
;
3942 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
3943 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
3948 window
= create_window();
3949 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
3951 skip("Failed to create a 3D device, skipping test.\n");
3952 DestroyWindow(window
);
3956 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
3957 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
3959 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
3960 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
3962 viewport
= create_viewport(device
, 0, 0, 640, 480);
3963 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
3964 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
3966 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
3967 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
3969 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
3970 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
3971 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
3972 ok(SUCCEEDED(hr
), "Failed to set view transformation, hr %#x.\n", hr
);
3973 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
3974 ok(SUCCEEDED(hr
), "Failed to set projection transformation, hr %#x.\n", hr
);
3975 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
3976 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
3977 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
3978 ok(SUCCEEDED(hr
), "Failed to disable zbuffer, hr %#x.\n", hr
);
3979 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
3980 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
3981 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
3982 ok(SUCCEEDED(hr
), "Failed to disable stencil buffer, hr %#x.\n", hr
);
3983 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
3984 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
3986 hr
= IDirect3DDevice3_BeginScene(device
);
3987 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
3989 /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
3990 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
3991 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
3992 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, unlitquad
, 4,
3994 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
3996 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
3997 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
3998 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, litquad
, 4,
4000 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4002 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
4003 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
4004 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, unlitnquad
, 4,
4006 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4008 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, TRUE
);
4009 ok(SUCCEEDED(hr
), "Failed to enable lighting, hr %#x.\n", hr
);
4010 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, litnquad
, 4,
4012 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4014 hr
= IDirect3DDevice3_EndScene(device
);
4015 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4017 color
= get_surface_color(rt
, 160, 360);
4018 ok(color
== 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color
);
4019 color
= get_surface_color(rt
, 160, 120);
4020 ok(color
== 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color
);
4021 color
= get_surface_color(rt
, 480, 360);
4022 ok(color
== 0x000000ff, "Unlit quad with normals has color 0x%08x.\n", color
);
4023 color
= get_surface_color(rt
, 480, 120);
4024 ok(color
== 0x00ffff00, "Lit quad with normals has color 0x%08x.\n", color
);
4026 material
= create_diffuse_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4027 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4028 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4029 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4030 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4032 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4033 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
4034 memset(&light_desc
, 0, sizeof(light_desc
));
4035 light_desc
.dwSize
= sizeof(light_desc
);
4036 light_desc
.dltType
= D3DLIGHT_DIRECTIONAL
;
4037 U1(light_desc
.dcvColor
).r
= 1.0f
;
4038 U2(light_desc
.dcvColor
).g
= 1.0f
;
4039 U3(light_desc
.dcvColor
).b
= 1.0f
;
4040 U4(light_desc
.dcvColor
).a
= 1.0f
;
4041 U3(light_desc
.dvDirection
).z
= 1.0f
;
4042 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4043 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4044 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4045 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
4047 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4048 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4050 hr
= IDirect3DDevice3_BeginScene(device
);
4051 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4053 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, nquad
,
4055 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4057 hr
= IDirect3DDevice3_EndScene(device
);
4058 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4060 color
= get_surface_color(rt
, 320, 240);
4061 ok(color
== 0x00000000, "Lit quad with no light has color 0x%08x.\n", color
);
4063 light_desc
.dwFlags
= D3DLIGHT_ACTIVE
;
4064 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)&light_desc
);
4065 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4067 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4069 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, tests
[i
].world_matrix
);
4070 ok(SUCCEEDED(hr
), "Failed to set world transformation, hr %#x.\n", hr
);
4072 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4073 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4075 hr
= IDirect3DDevice3_BeginScene(device
);
4076 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4078 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, nfvf
, tests
[i
].quad
,
4080 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4082 hr
= IDirect3DDevice3_EndScene(device
);
4083 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4085 color
= get_surface_color(rt
, 320, 240);
4086 ok(color
== tests
[i
].expected
, "%s has color 0x%08x.\n", tests
[i
].message
, color
);
4089 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4090 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
4091 IDirect3DLight_Release(light
);
4092 destroy_material(material
);
4093 IDirect3DViewport3_Release(viewport
);
4094 IDirectDrawSurface4_Release(rt
);
4095 refcount
= IDirect3DDevice3_Release(device
);
4096 ok(!refcount
, "Device has %u references left.\n", refcount
);
4097 IDirect3D3_Release(d3d
);
4098 DestroyWindow(window
);
4101 static void test_specular_lighting(void)
4103 static const unsigned int vertices_side
= 5;
4104 const unsigned int indices_count
= (vertices_side
- 1) * (vertices_side
- 1) * 2 * 3;
4105 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_NORMAL
;
4106 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4107 static D3DMATRIX mat
=
4109 1.0f
, 0.0f
, 0.0f
, 0.0f
,
4110 0.0f
, 1.0f
, 0.0f
, 0.0f
,
4111 0.0f
, 0.0f
, 1.0f
, 0.0f
,
4112 0.0f
, 0.0f
, 0.0f
, 1.0f
,
4114 static D3DLIGHT2 directional
=
4117 D3DLIGHT_DIRECTIONAL
,
4118 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4119 {{0.0f
}, {0.0f
}, {0.0f
}},
4120 {{0.0f
}, {0.0f
}, {1.0f
}},
4126 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4127 {{0.0f
}, {0.0f
}, {0.0f
}},
4128 {{0.0f
}, {0.0f
}, {0.0f
}},
4137 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4138 {{0.0f
}, {0.0f
}, {0.0f
}},
4139 {{0.0f
}, {0.0f
}, {1.0f
}},
4143 M_PI
/ 12.0f
, M_PI
/ 3.0f
4148 D3DLIGHT_PARALLELPOINT
,
4149 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4150 {{0.5f
}, {0.0f
}, {-1.0f
}},
4151 {{0.0f
}, {0.0f
}, {0.0f
}},
4157 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4158 {{-1.1f
}, {0.0f
}, {1.1f
}},
4159 {{0.0f
}, {0.0f
}, {0.0f
}},
4168 {{1.0f
}, {1.0f
}, {1.0f
}, {0.0f
}},
4169 {{0.0f
}, {0.0f
}, {0.1f
}},
4170 {{0.0f
}, {0.0f
}, {0.0f
}},
4175 static const struct expected_color
4180 expected_directional
[] =
4182 {160, 120, 0x003c3c3c},
4183 {320, 120, 0x00717171},
4184 {480, 120, 0x003c3c3c},
4185 {160, 240, 0x00717171},
4186 {320, 240, 0x00ffffff},
4187 {480, 240, 0x00717171},
4188 {160, 360, 0x003c3c3c},
4189 {320, 360, 0x00717171},
4190 {480, 360, 0x003c3c3c},
4194 {160, 120, 0x00000000},
4195 {320, 120, 0x00090909},
4196 {480, 120, 0x00000000},
4197 {160, 240, 0x00090909},
4198 {320, 240, 0x00fafafa},
4199 {480, 240, 0x00090909},
4200 {160, 360, 0x00000000},
4201 {320, 360, 0x00090909},
4202 {480, 360, 0x00000000},
4206 {160, 120, 0x00000000},
4207 {320, 120, 0x00020202},
4208 {480, 120, 0x00000000},
4209 {160, 240, 0x00020202},
4210 {320, 240, 0x00fafafa},
4211 {480, 240, 0x00020202},
4212 {160, 360, 0x00000000},
4213 {320, 360, 0x00020202},
4214 {480, 360, 0x00000000},
4216 expected_parallelpoint
[] =
4218 {160, 120, 0x00050505},
4219 {320, 120, 0x002c2c2c},
4220 {480, 120, 0x006e6e6e},
4221 {160, 240, 0x00090909},
4222 {320, 240, 0x00717171},
4223 {480, 240, 0x00ffffff},
4224 {160, 360, 0x00050505},
4225 {320, 360, 0x002c2c2c},
4226 {480, 360, 0x006e6e6e},
4228 expected_point_side
[] =
4230 {160, 120, 0x00000000},
4231 {320, 120, 0x00000000},
4232 {480, 120, 0x00000000},
4233 {160, 240, 0x00000000},
4234 {320, 240, 0x00000000},
4235 {480, 240, 0x00000000},
4236 {160, 360, 0x00000000},
4237 {320, 360, 0x00000000},
4238 {480, 360, 0x00000000},
4240 expected_point_far
[] =
4242 {160, 120, 0x00000000},
4243 {320, 120, 0x00000000},
4244 {480, 120, 0x00000000},
4245 {160, 240, 0x00000000},
4246 {320, 240, 0x00ffffff},
4247 {480, 240, 0x00000000},
4248 {160, 360, 0x00000000},
4249 {320, 360, 0x00000000},
4250 {480, 360, 0x00000000},
4256 float specular_power
;
4257 const struct expected_color
*expected
;
4258 unsigned int expected_count
;
4262 /* D3DRENDERSTATE_LOCALVIEWER does not exist in D3D < 7 (the behavior is
4263 * the one you get on newer D3D versions with it set as TRUE). */
4264 {&directional
, FALSE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4265 {&directional
, TRUE
, 30.0f
, expected_directional
, ARRAY_SIZE(expected_directional
)},
4266 {&point
, TRUE
, 30.0f
, expected_point
, ARRAY_SIZE(expected_point
)},
4267 {&spot
, TRUE
, 30.0f
, expected_spot
, ARRAY_SIZE(expected_spot
)},
4268 {¶llelpoint
, TRUE
, 30.0f
, expected_parallelpoint
, ARRAY_SIZE(expected_parallelpoint
)},
4269 {&point_side
, TRUE
, 0.0f
, expected_point_side
, ARRAY_SIZE(expected_point_side
)},
4270 {&point_far
, TRUE
, 1.0f
, expected_point_far
, ARRAY_SIZE(expected_point_far
)},
4273 IDirect3DDevice3
*device
;
4274 IDirectDrawSurface4
*rt
;
4275 IDirect3DViewport3
*viewport
;
4276 IDirect3DMaterial3
*material
;
4277 IDirect3DLight
*light
;
4278 D3DMATERIALHANDLE mat_handle
;
4283 unsigned int i
, j
, x
, y
;
4286 struct vec3 position
;
4291 window
= create_window();
4292 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4294 skip("Failed to create a 3D device, skipping test.\n");
4295 DestroyWindow(window
);
4299 quad
= HeapAlloc(GetProcessHeap(), 0, vertices_side
* vertices_side
* sizeof(*quad
));
4300 indices
= HeapAlloc(GetProcessHeap(), 0, indices_count
* sizeof(*indices
));
4301 for (i
= 0, y
= 0; y
< vertices_side
; ++y
)
4303 for (x
= 0; x
< vertices_side
; ++x
)
4305 quad
[i
].position
.x
= x
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4306 quad
[i
].position
.y
= y
* 2.0f
/ (vertices_side
- 1) - 1.0f
;
4307 quad
[i
].position
.z
= 1.0f
;
4308 quad
[i
].normal
.x
= 0.0f
;
4309 quad
[i
].normal
.y
= 0.0f
;
4310 quad
[i
++].normal
.z
= -1.0f
;
4313 for (i
= 0, y
= 0; y
< (vertices_side
- 1); ++y
)
4315 for (x
= 0; x
< (vertices_side
- 1); ++x
)
4317 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4318 indices
[i
++] = y
* vertices_side
+ x
;
4319 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4320 indices
[i
++] = y
* vertices_side
+ x
+ 1;
4321 indices
[i
++] = (y
+ 1) * vertices_side
+ x
;
4322 indices
[i
++] = (y
+ 1) * vertices_side
+ x
+ 1;
4326 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
4327 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
4329 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4330 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4332 viewport
= create_viewport(device
, 0, 0, 640, 480);
4333 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4334 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4336 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
4337 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
4338 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
4339 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
4340 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
4341 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
4342 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
4343 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
4344 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
4345 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
4346 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
4347 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
4349 hr
= IDirect3D3_CreateLight(d3d
, &light
, NULL
);
4350 ok(SUCCEEDED(hr
), "Failed to create a light object, hr %#x.\n", hr
);
4351 hr
= IDirect3DViewport3_AddLight(viewport
, light
);
4352 ok(SUCCEEDED(hr
), "Failed to add a light to the viewport, hr %#x.\n", hr
);
4354 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, TRUE
);
4355 ok(SUCCEEDED(hr
), "Failed to enable specular lighting, hr %#x.\n", hr
);
4357 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
4359 tests
[i
].light
->dwFlags
= D3DLIGHT_ACTIVE
;
4360 hr
= IDirect3DLight_SetLight(light
, (D3DLIGHT
*)tests
[i
].light
);
4361 ok(SUCCEEDED(hr
), "Failed to set light, hr %#x.\n", hr
);
4363 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LOCALVIEWER
, tests
[i
].local_viewer
);
4364 ok(SUCCEEDED(hr
), "Failed to set local viewer state, hr %#x.\n", hr
);
4366 material
= create_specular_material(device
, 1.0f
, 1.0f
, 1.0f
, 1.0f
, tests
[i
].specular_power
);
4367 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
4368 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
4369 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4370 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4372 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
4373 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4375 hr
= IDirect3DDevice3_BeginScene(device
);
4376 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4378 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, fvf
, quad
,
4379 vertices_side
* vertices_side
, indices
, indices_count
, 0);
4380 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4382 hr
= IDirect3DDevice3_EndScene(device
);
4383 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4385 for (j
= 0; j
< tests
[i
].expected_count
; ++j
)
4387 color
= get_surface_color(rt
, tests
[i
].expected
[j
].x
, tests
[i
].expected
[j
].y
);
4388 ok(compare_color(color
, tests
[i
].expected
[j
].color
, 1),
4389 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
4390 tests
[i
].expected
[j
].color
, tests
[i
].expected
[j
].x
,
4391 tests
[i
].expected
[j
].y
, color
, i
);
4394 destroy_material(material
);
4397 hr
= IDirect3DViewport3_DeleteLight(viewport
, light
);
4398 ok(SUCCEEDED(hr
), "Failed to remove a light from the viewport, hr %#x.\n", hr
);
4399 IDirect3DLight_Release(light
);
4400 IDirect3DViewport3_Release(viewport
);
4401 IDirectDrawSurface4_Release(rt
);
4402 refcount
= IDirect3DDevice3_Release(device
);
4403 ok(!refcount
, "Device has %u references left.\n", refcount
);
4404 IDirect3D3_Release(d3d
);
4405 DestroyWindow(window
);
4406 HeapFree(GetProcessHeap(), 0, indices
);
4407 HeapFree(GetProcessHeap(), 0, quad
);
4410 static void test_clear_rect_count(void)
4412 IDirectDrawSurface4
*rt
;
4413 IDirect3DDevice3
*device
;
4417 IDirect3DViewport3
*viewport
;
4418 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4420 window
= create_window();
4421 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4423 skip("Failed to create a 3D device, skipping test.\n");
4424 DestroyWindow(window
);
4428 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4429 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4431 viewport
= create_viewport(device
, 0, 0, 640, 480);
4432 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4433 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
4434 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00ffffff, 0.0f
, 0);
4435 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4436 hr
= IDirect3DViewport3_Clear2(viewport
, 0, &clear_rect
, D3DCLEAR_TARGET
, 0x00ff0000, 0.0f
, 0);
4437 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4438 hr
= IDirect3DViewport3_Clear2(viewport
, 0, NULL
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
4439 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4440 hr
= IDirect3DViewport3_Clear2(viewport
, 1, NULL
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
4441 ok(SUCCEEDED(hr
), "Failed to clear the viewport, hr %#x.\n", hr
);
4443 color
= get_surface_color(rt
, 320, 240);
4444 ok(compare_color(color
, 0x00ffffff, 1) || broken(compare_color(color
, 0x000000ff, 1)),
4445 "Got unexpected color 0x%08x.\n", color
);
4447 IDirect3DViewport3_Release(viewport
);
4448 IDirectDrawSurface4_Release(rt
);
4449 IDirect3DDevice3_Release(device
);
4450 DestroyWindow(window
);
4453 static BOOL
test_mode_restored(IDirectDraw4
*ddraw
, HWND window
)
4455 DDSURFACEDESC2 ddsd1
, ddsd2
;
4458 memset(&ddsd1
, 0, sizeof(ddsd1
));
4459 ddsd1
.dwSize
= sizeof(ddsd1
);
4460 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd1
);
4461 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4463 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4464 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4465 hr
= set_display_mode(ddraw
, 640, 480);
4466 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
4467 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4468 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4470 memset(&ddsd2
, 0, sizeof(ddsd2
));
4471 ddsd2
.dwSize
= sizeof(ddsd2
);
4472 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &ddsd2
);
4473 ok(SUCCEEDED(hr
), "GetDisplayMode failed, hr %#x.\n", hr
);
4474 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
4475 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
4477 return ddsd1
.dwWidth
== ddsd2
.dwWidth
&& ddsd1
.dwHeight
== ddsd2
.dwHeight
;
4480 static void test_coop_level_versions(void)
4486 IDirectDrawSurface
*surface
;
4487 IDirectDraw4
*ddraw4
;
4490 window
= create_window();
4491 ddraw4
= create_ddraw();
4492 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4493 /* Newly created ddraw objects restore the mode on ddraw2+::SetCooperativeLevel(NORMAL) */
4494 restored
= test_mode_restored(ddraw4
, window
);
4495 ok(restored
, "Display mode not restored in new ddraw object\n");
4497 /* A failing ddraw1::SetCooperativeLevel call does not have an effect */
4498 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4499 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4501 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4502 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4503 restored
= test_mode_restored(ddraw4
, window
);
4504 ok(restored
, "Display mode not restored after bad ddraw1::SetCooperativeLevel call\n");
4506 /* A successful one does */
4507 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4508 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4509 restored
= test_mode_restored(ddraw4
, window
);
4510 ok(!restored
, "Display mode restored after good ddraw1::SetCooperativeLevel call\n");
4512 IDirectDraw_Release(ddraw
);
4513 IDirectDraw4_Release(ddraw4
);
4515 ddraw4
= create_ddraw();
4516 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4517 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4518 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4520 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_SETFOCUSWINDOW
);
4521 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4522 restored
= test_mode_restored(ddraw4
, window
);
4523 ok(!restored
, "Display mode restored after ddraw1::SetCooperativeLevel(SETFOCUSWINDOW) call\n");
4525 IDirectDraw_Release(ddraw
);
4526 IDirectDraw4_Release(ddraw4
);
4528 /* A failing call does not restore the ddraw2+ behavior */
4529 ddraw4
= create_ddraw();
4530 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4531 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4532 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4534 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4535 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4536 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4537 ok(FAILED(hr
), "SetCooperativeLevel returned %#x, expected failure.\n", hr
);
4538 restored
= test_mode_restored(ddraw4
, window
);
4539 ok(!restored
, "Display mode restored after good-bad ddraw1::SetCooperativeLevel() call sequence\n");
4541 IDirectDraw_Release(ddraw
);
4542 IDirectDraw4_Release(ddraw4
);
4544 /* Neither does a sequence of successful calls with the new interface */
4545 ddraw4
= create_ddraw();
4546 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4547 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4548 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4550 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4551 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4552 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
4553 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4554 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4555 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4557 restored
= test_mode_restored(ddraw4
, window
);
4558 ok(!restored
, "Display mode restored after ddraw1-ddraw4 SetCooperativeLevel() call sequence\n");
4559 IDirectDraw_Release(ddraw
);
4560 IDirectDraw4_Release(ddraw4
);
4562 /* ddraw1::CreateSurface does not triger the ddraw1 behavior */
4563 ddraw4
= create_ddraw();
4564 ok(!!ddraw4
, "Failed to create a ddraw object.\n");
4565 hr
= IDirectDraw4_QueryInterface(ddraw4
, &IID_IDirectDraw
, (void **)&ddraw
);
4566 ok(SUCCEEDED(hr
), "QueryInterface failed, hr %#x.\n", hr
);
4568 hr
= IDirectDraw4_SetCooperativeLevel(ddraw4
, window
, DDSCL_NORMAL
);
4569 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
4571 memset(&ddsd
, 0, sizeof(ddsd
));
4572 ddsd
.dwSize
= sizeof(ddsd
);
4573 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4574 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
4575 ddsd
.dwWidth
= ddsd
.dwHeight
= 8;
4576 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4577 ok(SUCCEEDED(hr
), "CreateSurface failed, hr %#x.\n", hr
);
4578 IDirectDrawSurface_Release(surface
);
4579 restored
= test_mode_restored(ddraw4
, window
);
4580 ok(restored
, "Display mode not restored after ddraw1::CreateSurface() call\n");
4582 IDirectDraw_Release(ddraw
);
4583 IDirectDraw4_Release(ddraw4
);
4584 DestroyWindow(window
);
4587 static void test_lighting_interface_versions(void)
4589 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
4590 IDirect3DMaterial3
*emissive
;
4591 IDirect3DViewport3
*viewport
;
4592 IDirect3DDevice3
*device
;
4593 IDirectDrawSurface4
*rt
;
4597 D3DMATERIALHANDLE mat_handle
;
4601 static D3DVERTEX quad
[] =
4603 {{-1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4604 {{ 1.0f
}, { 1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4605 {{-1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4606 {{ 1.0f
}, {-1.0f
}, {0.0f
}, {1.0f
}, {0.0f
}, {0.0f
}},
4609 #define FVF_COLORVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR)
4612 struct vec3 position
;
4614 DWORD diffuse
, specular
;
4618 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4619 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4620 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4621 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4624 static D3DLVERTEX lquad
[] =
4626 {{-1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4627 {{ 1.0f
}, { 1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4628 {{-1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4629 {{ 1.0f
}, {-1.0f
}, {0.0f
}, 0, {0xffff0000}, {0xff808080}},
4632 #define FVF_LVERTEX2 (D3DFVF_LVERTEX & ~D3DFVF_RESERVED1)
4635 struct vec3 position
;
4636 DWORD diffuse
, specular
;
4637 struct vec2 texcoord
;
4641 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4642 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4643 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4644 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000, 0xff808080},
4647 static D3DTLVERTEX tlquad
[] =
4649 {{ 0.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4650 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4651 {{ 640.0f
}, { 480.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4652 {{ 640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xff0000ff}, {0xff808080}},
4659 DWORD d3drs_lighting
, d3drs_specular
;
4665 /* Lighting is enabled when all of these conditions are met:
4666 * 1) No pretransformed position(D3DFVF_XYZRHW)
4667 * 2) Normals are available (D3DFVF_NORMAL)
4668 * 3) D3DDP_DONOTLIGHT is not set.
4670 * D3DRENDERSTATE_LIGHTING is ignored, it is not defined
4671 * in this d3d version */
4674 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, 0, 0x0000ff00},
4675 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, 0, 0x0000ff00},
4676 { D3DFVF_VERTEX
, quad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4677 { D3DFVF_VERTEX
, quad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4678 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, 0, 0x0000ff00},
4679 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, 0, 0x0000ff00},
4680 { D3DFVF_VERTEX
, quad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4681 { D3DFVF_VERTEX
, quad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ffffff},
4684 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, 0, 0x0000ff00},
4685 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, 0, 0x0000ff00},
4686 { FVF_COLORVERTEX
, quad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4687 { FVF_COLORVERTEX
, quad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4688 /* The specular color in the vertex is ignored because
4689 * D3DRENDERSTATE_COLORVERTEX is not enabled */
4690 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, 0, 0x0000ff00},
4691 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, 0, 0x0000ff00},
4692 { FVF_COLORVERTEX
, quad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4693 { FVF_COLORVERTEX
, quad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4696 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, 0, 0x00ff0000},
4697 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, 0, 0x00ff0000},
4698 { D3DFVF_LVERTEX
, lquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4699 { D3DFVF_LVERTEX
, lquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4700 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, 0, 0x00ff8080},
4701 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, 0, 0x00ff8080},
4702 { D3DFVF_LVERTEX
, lquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4703 { D3DFVF_LVERTEX
, lquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4706 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, 0, 0x00ff0000},
4707 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, 0, 0x00ff0000},
4708 { FVF_LVERTEX2
, lquad2
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4709 { FVF_LVERTEX2
, lquad2
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x00ff0000},
4710 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, 0, 0x00ff8080},
4711 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, 0, 0x00ff8080},
4712 { FVF_LVERTEX2
, lquad2
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4713 { FVF_LVERTEX2
, lquad2
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x00ff8080},
4716 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, 0, 0x000000ff},
4717 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, 0, 0x000000ff},
4718 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4719 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, FALSE
, D3DDP_DONOTLIGHT
, 0x000000ff},
4720 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, 0, 0x008080ff},
4721 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, 0, 0x008080ff},
4722 { D3DFVF_TLVERTEX
, tlquad
, FALSE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4723 { D3DFVF_TLVERTEX
, tlquad
, TRUE
, TRUE
, D3DDP_DONOTLIGHT
, 0x008080ff},
4726 window
= create_window();
4727 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
4729 skip("Failed to create a 3D device, skipping test.\n");
4730 DestroyWindow(window
);
4734 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
4735 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
4737 viewport
= create_viewport(device
, 0, 0, 640, 480);
4738 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
4739 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
4741 emissive
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
4742 hr
= IDirect3DMaterial3_GetHandle(emissive
, device
, &mat_handle
);
4743 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
4744 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
4745 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
4746 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
4747 ok(SUCCEEDED(hr
), "Failed to disable z test, hr %#x.\n", hr
);
4749 hr
= IDirect3DDevice3_GetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
, &rs
);
4750 ok(SUCCEEDED(hr
), "Failed to get specularenable render state, hr %#x.\n", hr
);
4751 ok(rs
== FALSE
, "Initial D3DRENDERSTATE_SPECULARENABLE is %#x, expected FALSE.\n", rs
);
4753 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4755 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff202020, 0.0f
, 0);
4756 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
4758 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, tests
[i
].d3drs_lighting
);
4759 ok(SUCCEEDED(hr
), "Failed to set lighting render state, hr %#x.\n", hr
);
4760 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SPECULARENABLE
,
4761 tests
[i
].d3drs_specular
);
4762 ok(SUCCEEDED(hr
), "Failed to set specularenable render state, hr %#x.\n", hr
);
4764 hr
= IDirect3DDevice3_BeginScene(device
);
4765 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
4766 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
4767 tests
[i
].vertextype
, tests
[i
].data
, 4, tests
[i
].draw_flags
| D3DDP_WAIT
);
4768 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
4769 hr
= IDirect3DDevice3_EndScene(device
);
4770 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
4772 color
= get_surface_color(rt
, 320, 240);
4773 ok(compare_color(color
, tests
[i
].color
, 1),
4774 "Got unexpected color 0x%08x, expected 0x%08x, test %u.\n",
4775 color
, tests
[i
].color
, i
);
4778 destroy_material(emissive
);
4779 IDirectDrawSurface4_Release(rt
);
4780 ref
= IDirect3DDevice3_Release(device
);
4781 ok(ref
== 0, "Device not properly released, refcount %u.\n", ref
);
4782 DestroyWindow(window
);
4788 IDirectDraw4
*ddraw
;
4791 } activateapp_testdata
;
4793 static LRESULT CALLBACK
activateapp_test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
4795 if (message
== WM_ACTIVATEAPP
)
4797 if (activateapp_testdata
.ddraw
)
4800 activateapp_testdata
.received
= FALSE
;
4801 hr
= IDirectDraw4_SetCooperativeLevel(activateapp_testdata
.ddraw
,
4802 activateapp_testdata
.window
, activateapp_testdata
.coop_level
);
4803 ok(SUCCEEDED(hr
), "Recursive SetCooperativeLevel call failed, hr %#x.\n", hr
);
4804 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP during recursive SetCooperativeLevel call.\n");
4806 activateapp_testdata
.received
= TRUE
;
4809 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
4812 static void test_coop_level_activateapp(void)
4814 IDirectDraw4
*ddraw
;
4818 DDSURFACEDESC2 ddsd
;
4819 IDirectDrawSurface4
*surface
;
4821 ddraw
= create_ddraw();
4822 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4824 wc
.lpfnWndProc
= activateapp_test_proc
;
4825 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
4826 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4828 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
4829 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
4831 /* Exclusive with window already active. */
4832 SetForegroundWindow(window
);
4833 activateapp_testdata
.received
= FALSE
;
4834 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4835 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4836 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP although window was already active.\n");
4837 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4838 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4840 /* Exclusive with window not active. */
4841 SetForegroundWindow(GetDesktopWindow());
4842 activateapp_testdata
.received
= FALSE
;
4843 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4844 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4845 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4846 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4847 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4849 /* Normal with window not active, then exclusive with the same window. */
4850 SetForegroundWindow(GetDesktopWindow());
4851 activateapp_testdata
.received
= FALSE
;
4852 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
4853 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4854 ok(!activateapp_testdata
.received
, "Received WM_ACTIVATEAPP when setting DDSCL_NORMAL.\n");
4855 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4856 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4857 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4858 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4859 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4861 /* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */
4862 SetForegroundWindow(GetDesktopWindow());
4863 activateapp_testdata
.received
= FALSE
;
4864 activateapp_testdata
.ddraw
= ddraw
;
4865 activateapp_testdata
.window
= window
;
4866 activateapp_testdata
.coop_level
= DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
;
4867 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4868 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4869 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4870 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4871 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4873 /* The recursive call seems to have some bad effect on native ddraw, despite (apparently)
4874 * succeeding. Another switch to exclusive and back to normal is needed to release the
4875 * window properly. Without doing this, SetCooperativeLevel(EXCLUSIVE) will not send
4876 * WM_ACTIVATEAPP messages. */
4877 activateapp_testdata
.ddraw
= NULL
;
4878 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4879 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4880 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4881 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4883 /* Setting DDSCL_NORMAL with recursive invocation. */
4884 SetForegroundWindow(GetDesktopWindow());
4885 activateapp_testdata
.received
= FALSE
;
4886 activateapp_testdata
.ddraw
= ddraw
;
4887 activateapp_testdata
.window
= window
;
4888 activateapp_testdata
.coop_level
= DDSCL_NORMAL
;
4889 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4890 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4891 ok(activateapp_testdata
.received
, "Expected WM_ACTIVATEAPP, but did not receive it.\n");
4893 /* DDraw is in exclusive mode now. */
4894 memset(&ddsd
, 0, sizeof(ddsd
));
4895 ddsd
.dwSize
= sizeof(ddsd
);
4896 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
4897 U5(ddsd
).dwBackBufferCount
= 1;
4898 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
4899 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4900 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
4901 IDirectDrawSurface4_Release(surface
);
4903 /* Recover again, just to be sure. */
4904 activateapp_testdata
.ddraw
= NULL
;
4905 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
4906 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4907 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4908 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4910 DestroyWindow(window
);
4911 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
4912 IDirectDraw4_Release(ddraw
);
4915 static void test_texturemanage(void)
4917 IDirectDraw4
*ddraw
;
4919 DDSURFACEDESC2 ddsd
;
4920 IDirectDrawSurface4
*surface
;
4922 DDCAPS hal_caps
, hel_caps
;
4923 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
4926 DWORD caps_in
, caps2_in
;
4928 DWORD caps_out
, caps2_out
;
4932 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4934 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4936 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4938 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4940 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, DD_OK
,
4941 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
},
4942 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, DD_OK
,
4943 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
},
4944 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
4945 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_LOCALVIDMEM
, 0},
4946 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0, DD_OK
,
4947 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0},
4949 {0, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4951 {0, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4953 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4955 {DDSCAPS_SYSTEMMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4957 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_TEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4959 {DDSCAPS_VIDEOMEMORY
, DDSCAPS2_D3DTEXTUREMANAGE
, DDERR_INVALIDCAPS
,
4961 {DDSCAPS_VIDEOMEMORY
, 0, DD_OK
,
4962 DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
, 0},
4963 {DDSCAPS_SYSTEMMEMORY
, 0, DD_OK
,
4964 DDSCAPS_SYSTEMMEMORY
, 0},
4967 ddraw
= create_ddraw();
4968 ok(!!ddraw
, "Failed to create a ddraw object.\n");
4969 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
4970 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
4972 memset(&hal_caps
, 0, sizeof(hal_caps
));
4973 hal_caps
.dwSize
= sizeof(hal_caps
);
4974 memset(&hel_caps
, 0, sizeof(hel_caps
));
4975 hel_caps
.dwSize
= sizeof(hel_caps
);
4976 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, &hel_caps
);
4977 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
4978 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
)
4980 skip("Managed textures not supported, skipping managed texture test.\n");
4981 IDirectDraw4_Release(ddraw
);
4985 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
4987 memset(&ddsd
, 0, sizeof(ddsd
));
4988 ddsd
.dwSize
= sizeof(ddsd
);
4989 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
4990 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps_in
;
4991 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2_in
;
4995 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
4996 ok(hr
== tests
[i
].hr
, "Got unexpected, hr %#x, case %u.\n", hr
, i
);
5000 memset(&ddsd
, 0, sizeof(ddsd
));
5001 ddsd
.dwSize
= sizeof(ddsd
);
5002 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5003 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5005 ok(ddsd
.ddsCaps
.dwCaps
== tests
[i
].caps_out
,
5006 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5007 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps_out
, ddsd
.ddsCaps
.dwCaps
, i
);
5008 ok(ddsd
.ddsCaps
.dwCaps2
== tests
[i
].caps2_out
,
5009 "Input caps %#x, %#x, expected output caps %#x, got %#x, case %u.\n",
5010 tests
[i
].caps_in
, tests
[i
].caps2_in
, tests
[i
].caps2_out
, ddsd
.ddsCaps
.dwCaps2
, i
);
5012 IDirectDrawSurface4_Release(surface
);
5015 IDirectDraw4_Release(ddraw
);
5018 #define SUPPORT_DXT1 0x01
5019 #define SUPPORT_DXT2 0x02
5020 #define SUPPORT_DXT3 0x04
5021 #define SUPPORT_DXT4 0x08
5022 #define SUPPORT_DXT5 0x10
5023 #define SUPPORT_YUY2 0x20
5024 #define SUPPORT_UYVY 0x40
5026 static HRESULT WINAPI
test_block_formats_creation_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5028 DWORD
*supported_fmts
= ctx
;
5030 if (!(fmt
->dwFlags
& DDPF_FOURCC
))
5031 return DDENUMRET_OK
;
5033 switch (fmt
->dwFourCC
)
5035 case MAKEFOURCC('D','X','T','1'):
5036 *supported_fmts
|= SUPPORT_DXT1
;
5038 case MAKEFOURCC('D','X','T','2'):
5039 *supported_fmts
|= SUPPORT_DXT2
;
5041 case MAKEFOURCC('D','X','T','3'):
5042 *supported_fmts
|= SUPPORT_DXT3
;
5044 case MAKEFOURCC('D','X','T','4'):
5045 *supported_fmts
|= SUPPORT_DXT4
;
5047 case MAKEFOURCC('D','X','T','5'):
5048 *supported_fmts
|= SUPPORT_DXT5
;
5050 case MAKEFOURCC('Y','U','Y','2'):
5051 *supported_fmts
|= SUPPORT_YUY2
;
5053 case MAKEFOURCC('U','Y','V','Y'):
5054 *supported_fmts
|= SUPPORT_UYVY
;
5060 return DDENUMRET_OK
;
5063 static void test_block_formats_creation(void)
5065 HRESULT hr
, expect_hr
;
5066 unsigned int i
, j
, w
, h
;
5068 IDirectDraw4
*ddraw
;
5070 IDirect3DDevice3
*device
;
5071 IDirectDrawSurface4
*surface
;
5072 DWORD supported_fmts
= 0, supported_overlay_fmts
= 0;
5073 DWORD num_fourcc_codes
= 0, *fourcc_codes
;
5074 DDSURFACEDESC2 ddsd
;
5083 unsigned int block_width
;
5084 unsigned int block_height
;
5085 unsigned int block_size
;
5086 BOOL create_size_checked
, overlay
;
5090 {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1
, 4, 4, 8, TRUE
, FALSE
},
5091 {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2
, 4, 4, 16, TRUE
, FALSE
},
5092 {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3
, 4, 4, 16, TRUE
, FALSE
},
5093 {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4
, 4, 4, 16, TRUE
, FALSE
},
5094 {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5
, 4, 4, 16, TRUE
, FALSE
},
5095 {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2
, 2, 1, 4, FALSE
, TRUE
},
5096 {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY
, 2, 1, 4, FALSE
, TRUE
},
5106 /* DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY fails to create any fourcc
5107 * surface with DDERR_INVALIDPIXELFORMAT. Don't care about it for now.
5109 * Nvidia returns E_FAIL on DXTN DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY.
5110 * Other hw / drivers successfully create those surfaces. Ignore them, this
5111 * suggests that no game uses this, otherwise Nvidia would support it. */
5113 DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
, 0,
5114 "videomemory texture", FALSE
5117 DDSCAPS_VIDEOMEMORY
| DDSCAPS_OVERLAY
, 0,
5118 "videomemory overlay", TRUE
5121 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
, 0,
5122 "systemmemory texture", FALSE
5125 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
5126 "managed texture", FALSE
5138 enum size_type size_type
;
5144 {DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5145 {DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5146 {DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5147 {DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5148 {DDSD_LPSURFACE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5149 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_ZERO
, 0, DDERR_INVALIDPARAMS
},
5150 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_PITCH
, 0, DDERR_INVALIDPARAMS
},
5151 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5152 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 1, DD_OK
},
5153 {DDSD_LPSURFACE
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, -1, DDERR_INVALIDPARAMS
},
5154 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_ZERO
, 0, DD_OK
},
5155 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_PITCH
, 0, DD_OK
},
5156 {DDSD_LPSURFACE
| DDSD_PITCH
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5157 {DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, SIZE_TYPE_SIZE
, 0, DD_OK
},
5160 window
= create_window();
5161 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5163 skip("Failed to create a 3D device, skipping test.\n");
5164 DestroyWindow(window
);
5168 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5169 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5170 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5171 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5172 IDirect3D3_Release(d3d
);
5174 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
,
5176 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5178 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
5179 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5180 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
5181 num_fourcc_codes
* sizeof(*fourcc_codes
));
5184 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
5185 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
5186 for (i
= 0; i
< num_fourcc_codes
; i
++)
5188 for (j
= 0; j
< ARRAY_SIZE(formats
); j
++)
5190 if (fourcc_codes
[i
] == formats
[j
].fourcc
)
5191 supported_overlay_fmts
|= formats
[j
].support_flag
;
5194 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
5196 memset(&hal_caps
, 0, sizeof(hal_caps
));
5197 hal_caps
.dwSize
= sizeof(hal_caps
);
5198 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
5199 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
5201 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * 2 * 16 + 1);
5203 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5205 for (j
= 0; j
< ARRAY_SIZE(types
); j
++)
5209 if (formats
[i
].overlay
!= types
[j
].overlay
5210 || (types
[j
].overlay
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
)))
5213 if (formats
[i
].overlay
)
5214 support
= supported_overlay_fmts
& formats
[i
].support_flag
;
5216 support
= supported_fmts
& formats
[i
].support_flag
;
5218 for (w
= 1; w
<= 8; w
++)
5220 for (h
= 1; h
<= 8; h
++)
5222 BOOL block_aligned
= TRUE
;
5225 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
5226 block_aligned
= FALSE
;
5228 memset(&ddsd
, 0, sizeof(ddsd
));
5229 ddsd
.dwSize
= sizeof(ddsd
);
5230 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5231 ddsd
.ddsCaps
.dwCaps
= types
[j
].caps
;
5232 ddsd
.ddsCaps
.dwCaps2
= types
[j
].caps2
;
5233 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5234 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5235 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5239 /* TODO: Handle power of two limitations. I cannot test the pow2
5240 * behavior on windows because I have no hardware that doesn't at
5241 * least support np2_conditional. There's probably no HW that
5242 * supports DXTN textures but no conditional np2 textures. */
5243 if (!support
&& !(types
[j
].caps
& DDSCAPS_SYSTEMMEMORY
))
5244 expect_hr
= DDERR_INVALIDPARAMS
;
5245 else if (formats
[i
].create_size_checked
&& !block_aligned
)
5247 expect_hr
= DDERR_INVALIDPARAMS
;
5248 if (!(types
[j
].caps
& DDSCAPS_TEXTURE
))
5254 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5257 "Got unexpected hr %#x for format %s, resource type %s, size %ux%u, expected %#x.\n",
5258 hr
, formats
[i
].name
, types
[j
].name
, w
, h
, expect_hr
);
5261 IDirectDrawSurface4_Release(surface
);
5266 if (formats
[i
].overlay
)
5269 for (j
= 0; j
< ARRAY_SIZE(user_mem_tests
); ++j
)
5271 memset(&ddsd
, 0, sizeof(ddsd
));
5272 ddsd
.dwSize
= sizeof(ddsd
);
5273 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| user_mem_tests
[j
].flags
;
5274 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
;
5276 switch (user_mem_tests
[j
].size_type
)
5278 case SIZE_TYPE_ZERO
:
5279 U1(ddsd
).dwLinearSize
= 0;
5282 case SIZE_TYPE_PITCH
:
5283 U1(ddsd
).dwLinearSize
= 2 * formats
[i
].block_size
;
5286 case SIZE_TYPE_SIZE
:
5287 U1(ddsd
).dwLinearSize
= 2 * 2 * formats
[i
].block_size
;
5290 U1(ddsd
).dwLinearSize
+= user_mem_tests
[j
].rel_size
;
5292 ddsd
.lpSurface
= mem
;
5293 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
5294 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
;
5295 U4(ddsd
).ddpfPixelFormat
.dwFourCC
= formats
[i
].fourcc
;
5299 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5300 ok(hr
== user_mem_tests
[j
].hr
, "Test %u: Got unexpected hr %#x, format %s.\n", j
, hr
, formats
[i
].name
);
5305 memset(&ddsd
, 0, sizeof(ddsd
));
5306 ddsd
.dwSize
= sizeof(ddsd
);
5307 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5308 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", j
, hr
);
5309 ok(ddsd
.dwFlags
== (DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_LINEARSIZE
),
5310 "Test %u: Got unexpected flags %#x.\n", j
, ddsd
.dwFlags
);
5311 if (user_mem_tests
[j
].flags
& DDSD_LPSURFACE
)
5312 ok(U1(ddsd
).dwLinearSize
== ~0u, "Test %u: Got unexpected linear size %#x.\n",
5313 j
, U1(ddsd
).dwLinearSize
);
5315 ok(U1(ddsd
).dwLinearSize
== 2 * 2 * formats
[i
].block_size
,
5316 "Test %u: Got unexpected linear size %#x, expected %#x.\n",
5317 j
, U1(ddsd
).dwLinearSize
, 2 * 2 * formats
[i
].block_size
);
5318 IDirectDrawSurface4_Release(surface
);
5322 HeapFree(GetProcessHeap(), 0, mem
);
5324 IDirectDraw4_Release(ddraw
);
5325 IDirect3DDevice3_Release(device
);
5326 DestroyWindow(window
);
5329 struct format_support_check
5331 const DDPIXELFORMAT
*format
;
5335 static HRESULT WINAPI
test_unsupported_formats_cb(DDPIXELFORMAT
*fmt
, void *ctx
)
5337 struct format_support_check
*format
= ctx
;
5339 if (!memcmp(format
->format
, fmt
, sizeof(*fmt
)))
5341 format
->supported
= TRUE
;
5342 return DDENUMRET_CANCEL
;
5345 return DDENUMRET_OK
;
5348 static void test_unsupported_formats(void)
5351 BOOL expect_success
;
5353 IDirectDraw4
*ddraw
;
5355 IDirect3DDevice3
*device
;
5356 IDirectDrawSurface4
*surface
;
5357 DDSURFACEDESC2 ddsd
;
5359 DWORD expected_caps
;
5370 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
5371 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
5377 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5378 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
5382 static const DWORD caps
[] = {0, DDSCAPS_SYSTEMMEMORY
, DDSCAPS_VIDEOMEMORY
};
5384 window
= create_window();
5385 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
5387 skip("Failed to create a 3D device, skipping test.\n");
5388 DestroyWindow(window
);
5392 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
5393 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
5394 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **) &ddraw
);
5395 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
5396 IDirect3D3_Release(d3d
);
5398 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
5400 struct format_support_check check
= {&formats
[i
].fmt
, FALSE
};
5401 hr
= IDirect3DDevice3_EnumTextureFormats(device
, test_unsupported_formats_cb
, &check
);
5402 ok(SUCCEEDED(hr
), "Failed to enumerate texture formats %#x.\n", hr
);
5404 for (j
= 0; j
< ARRAY_SIZE(caps
); j
++)
5406 memset(&ddsd
, 0, sizeof(ddsd
));
5407 ddsd
.dwSize
= sizeof(ddsd
);
5408 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
5409 U4(ddsd
).ddpfPixelFormat
= formats
[i
].fmt
;
5412 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| caps
[j
];
5414 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
&& !check
.supported
)
5415 expect_success
= FALSE
;
5417 expect_success
= TRUE
;
5419 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
5420 ok(SUCCEEDED(hr
) == expect_success
,
5421 "Got unexpected hr %#x for format %s, caps %#x, expected %s.\n",
5422 hr
, formats
[i
].name
, caps
[j
], expect_success
? "success" : "failure");
5426 memset(&ddsd
, 0, sizeof(ddsd
));
5427 ddsd
.dwSize
= sizeof(ddsd
);
5428 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
5429 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
5431 if (caps
[j
] & DDSCAPS_VIDEOMEMORY
)
5432 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5433 else if (caps
[j
] & DDSCAPS_SYSTEMMEMORY
)
5434 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5435 else if (check
.supported
)
5436 expected_caps
= DDSCAPS_VIDEOMEMORY
;
5438 expected_caps
= DDSCAPS_SYSTEMMEMORY
;
5440 ok(ddsd
.ddsCaps
.dwCaps
& expected_caps
,
5441 "Expected capability %#x, format %s, input cap %#x.\n",
5442 expected_caps
, formats
[i
].name
, caps
[j
]);
5444 IDirectDrawSurface4_Release(surface
);
5448 IDirectDraw4_Release(ddraw
);
5449 IDirect3DDevice3_Release(device
);
5450 DestroyWindow(window
);
5453 static void test_rt_caps(void)
5455 PALETTEENTRY palette_entries
[256];
5456 IDirectDrawPalette
*palette
;
5457 IDirectDraw4
*ddraw
;
5458 DDPIXELFORMAT z_fmt
;
5465 static const DDPIXELFORMAT p8_fmt
=
5467 sizeof(DDPIXELFORMAT
), DDPF_PALETTEINDEXED8
| DDPF_RGB
, 0,
5468 {8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
5473 const DDPIXELFORMAT
*pf
;
5476 HRESULT create_device_hr
;
5477 HRESULT set_rt_hr
, alternative_set_rt_hr
;
5483 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5484 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5491 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5492 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5499 DDSCAPS_OFFSCREENPLAIN
,
5500 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5507 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5508 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5509 D3DERR_SURFACENOTINVIDMEM
,
5515 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5516 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5523 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
,
5524 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5532 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5540 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5547 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5548 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5549 D3DERR_SURFACENOTINVIDMEM
,
5555 DDSCAPS_SYSTEMMEMORY
,
5556 DDSCAPS_SYSTEMMEMORY
,
5564 DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5571 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
5573 DDERR_NOPALETTEATTACHED
,
5579 DDSCAPS_OFFSCREENPLAIN
,
5580 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
,
5587 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5588 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
,
5589 DDERR_NOPALETTEATTACHED
,
5595 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5596 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5603 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
,
5604 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5606 DDERR_INVALIDPIXELFORMAT
,
5611 DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5612 DDSCAPS_3DDEVICE
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5614 DDERR_INVALIDPIXELFORMAT
,
5620 DDSCAPS_VIDEOMEMORY
| DDSCAPS_ZBUFFER
| DDSCAPS_LOCALVIDMEM
,
5627 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5628 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_3DDEVICE
| DDSCAPS_ZBUFFER
,
5630 DDERR_INVALIDPIXELFORMAT
,
5635 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5636 DDSCAPS_SYSTEMMEMORY
| DDSCAPS_ZBUFFER
,
5643 window
= create_window();
5644 ddraw
= create_ddraw();
5645 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5646 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
5647 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5649 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
5651 skip("D3D interface is not available, skipping test.\n");
5655 memset(&z_fmt
, 0, sizeof(z_fmt
));
5656 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
5657 if (FAILED(hr
) || !z_fmt
.dwSize
)
5659 skip("No depth buffer formats available, skipping test.\n");
5660 IDirect3D3_Release(d3d
);
5664 memset(palette_entries
, 0, sizeof(palette_entries
));
5665 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
5666 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
5668 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5670 IDirectDrawSurface4
*surface
, *rt
, *expected_rt
, *tmp
;
5671 DDSURFACEDESC2 surface_desc
;
5672 IDirect3DDevice3
*device
;
5674 memset(&surface_desc
, 0, sizeof(surface_desc
));
5675 surface_desc
.dwSize
= sizeof(surface_desc
);
5676 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5677 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5678 if (test_data
[i
].pf
)
5680 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5681 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
5683 surface_desc
.dwWidth
= 640;
5684 surface_desc
.dwHeight
= 480;
5685 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5686 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
5687 i
, test_data
[i
].caps_in
, hr
);
5689 memset(&surface_desc
, 0, sizeof(surface_desc
));
5690 surface_desc
.dwSize
= sizeof(surface_desc
);
5691 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
5692 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5693 ok(test_data
[i
].caps_out
== ~0U || surface_desc
.ddsCaps
.dwCaps
== test_data
[i
].caps_out
,
5694 "Test %u: Got unexpected caps %#x, expected %#x.\n",
5695 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5697 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5698 ok(hr
== test_data
[i
].create_device_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n",
5699 i
, hr
, test_data
[i
].create_device_hr
);
5702 if (hr
== DDERR_NOPALETTEATTACHED
)
5704 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
5705 ok(SUCCEEDED(hr
), "Test %u: Failed to set palette, hr %#x.\n", i
, hr
);
5706 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5707 if (surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
5708 ok(hr
== DDERR_INVALIDPIXELFORMAT
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5710 ok(hr
== D3DERR_SURFACENOTINVIDMEM
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
5712 IDirectDrawSurface4_Release(surface
);
5714 memset(&surface_desc
, 0, sizeof(surface_desc
));
5715 surface_desc
.dwSize
= sizeof(surface_desc
);
5716 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5717 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
5718 surface_desc
.dwWidth
= 640;
5719 surface_desc
.dwHeight
= 480;
5720 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5721 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface, hr %#x.\n", i
, hr
);
5723 hr
= IDirect3D3_CreateDevice(d3d
, &IID_IDirect3DHALDevice
, surface
, &device
, NULL
);
5724 ok(SUCCEEDED(hr
), "Test %u: Failed to create device, hr %#x.\n", i
, hr
);
5727 memset(&surface_desc
, 0, sizeof(surface_desc
));
5728 surface_desc
.dwSize
= sizeof(surface_desc
);
5729 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
5730 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5731 if (test_data
[i
].pf
)
5733 surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
5734 U4(surface_desc
).ddpfPixelFormat
= *test_data
[i
].pf
;
5736 surface_desc
.dwWidth
= 640;
5737 surface_desc
.dwHeight
= 480;
5738 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &rt
, NULL
);
5739 ok(SUCCEEDED(hr
), "Test %u: Failed to create surface with caps %#x, hr %#x.\n",
5740 i
, test_data
[i
].caps_in
, hr
);
5742 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
5743 ok(hr
== test_data
[i
].set_rt_hr
|| broken(hr
== test_data
[i
].alternative_set_rt_hr
),
5744 "Test %u: Got unexpected hr %#x, expected %#x.\n",
5745 i
, hr
, test_data
[i
].set_rt_hr
);
5746 if (SUCCEEDED(hr
) || hr
== DDERR_INVALIDPIXELFORMAT
)
5749 expected_rt
= surface
;
5751 hr
= IDirect3DDevice3_GetRenderTarget(device
, &tmp
);
5752 ok(SUCCEEDED(hr
), "Test %u: Failed to get render target, hr %#x.\n", i
, hr
);
5753 ok(tmp
== expected_rt
, "Test %u: Got unexpected rt %p.\n", i
, tmp
);
5755 IDirectDrawSurface4_Release(tmp
);
5756 IDirectDrawSurface4_Release(rt
);
5757 refcount
= IDirect3DDevice3_Release(device
);
5758 ok(refcount
== 0, "Test %u: The device was not properly freed, refcount %u.\n", i
, refcount
);
5759 refcount
= IDirectDrawSurface4_Release(surface
);
5760 ok(refcount
== 0, "Test %u: The surface was not properly freed, refcount %u.\n", i
, refcount
);
5763 IDirectDrawPalette_Release(palette
);
5764 IDirect3D3_Release(d3d
);
5767 refcount
= IDirectDraw4_Release(ddraw
);
5768 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5769 DestroyWindow(window
);
5772 static void test_primary_caps(void)
5774 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
5775 IDirectDrawSurface4
*surface
;
5776 DDSURFACEDESC2 surface_desc
;
5777 IDirectDraw4
*ddraw
;
5787 DWORD back_buffer_count
;
5795 DDSCAPS_PRIMARYSURFACE
,
5798 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
,
5802 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_TEXTURE
,
5809 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
,
5816 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_BACKBUFFER
,
5823 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FLIP
,
5830 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
,
5837 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5844 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5851 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5853 DDERR_NOEXCLUSIVEMODE
,
5857 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5858 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5864 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5865 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
,
5868 DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
| DDSCAPS_FLIP
| DDSCAPS_COMPLEX
,
5871 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5872 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_FRONTBUFFER
,
5878 DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
,
5879 DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_BACKBUFFER
,
5886 window
= create_window();
5887 ddraw
= create_ddraw();
5888 ok(!!ddraw
, "Failed to create a ddraw object.\n");
5890 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5892 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, test_data
[i
].coop_level
);
5893 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
5895 memset(&surface_desc
, 0, sizeof(surface_desc
));
5896 surface_desc
.dwSize
= sizeof(surface_desc
);
5897 surface_desc
.dwFlags
= DDSD_CAPS
;
5898 if (test_data
[i
].back_buffer_count
!= ~0u)
5899 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
5900 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps_in
;
5901 U5(surface_desc
).dwBackBufferCount
= test_data
[i
].back_buffer_count
;
5902 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
5903 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
5907 memset(&surface_desc
, 0, sizeof(surface_desc
));
5908 surface_desc
.dwSize
= sizeof(surface_desc
);
5909 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
5910 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
5911 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == test_data
[i
].caps_out
,
5912 "Test %u: Got unexpected caps %#x, expected %#x.\n",
5913 i
, surface_desc
.ddsCaps
.dwCaps
, test_data
[i
].caps_out
);
5915 IDirectDrawSurface4_Release(surface
);
5918 refcount
= IDirectDraw4_Release(ddraw
);
5919 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
5920 DestroyWindow(window
);
5923 static void test_surface_lock(void)
5925 IDirectDraw4
*ddraw
;
5926 IDirect3D3
*d3d
= NULL
;
5927 IDirectDrawSurface4
*surface
;
5931 DDSURFACEDESC2 ddsd
;
5933 DDPIXELFORMAT z_fmt
;
5943 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
,
5945 "videomemory offscreenplain"
5948 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
,
5950 "systemmemory offscreenplain"
5953 DDSCAPS_PRIMARYSURFACE
,
5958 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5960 "videomemory texture"
5963 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
,
5965 "opaque videomemory texture"
5968 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
,
5970 "systemmemory texture"
5974 DDSCAPS2_TEXTUREMANAGE
,
5979 DDSCAPS2_D3DTEXTUREMANAGE
,
5984 DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
5985 "opaque managed texture"
5989 DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_OPAQUE
,
5990 "opaque managed texture"
5993 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
,
6004 window
= create_window();
6005 ddraw
= create_ddraw();
6006 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6007 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6008 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6010 if (FAILED(IDirectDraw4_QueryInterface(ddraw
, &IID_IDirect3D3
, (void **)&d3d
)))
6012 skip("D3D interface is not available, skipping test.\n");
6016 memset(&z_fmt
, 0, sizeof(z_fmt
));
6017 hr
= IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
6018 if (FAILED(hr
) || !z_fmt
.dwSize
)
6020 skip("No depth buffer formats available, skipping test.\n");
6024 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6026 memset(&ddsd
, 0, sizeof(ddsd
));
6027 ddsd
.dwSize
= sizeof(ddsd
);
6028 ddsd
.dwFlags
= DDSD_CAPS
;
6029 if (!(tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6031 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6035 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
6037 ddsd
.dwFlags
|= DDSD_PIXELFORMAT
;
6038 U4(ddsd
).ddpfPixelFormat
= z_fmt
;
6040 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6041 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6043 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6044 ok(SUCCEEDED(hr
), "Failed to create surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6046 memset(&ddsd
, 0, sizeof(ddsd
));
6047 ddsd
.dwSize
= sizeof(ddsd
);
6048 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6049 ok(SUCCEEDED(hr
), "Failed to lock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6052 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6053 ok(SUCCEEDED(hr
), "Failed to unlock surface, type %s, hr %#x.\n", tests
[i
].name
, hr
);
6056 memset(&ddsd
, 0, sizeof(ddsd
));
6057 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_WAIT
, NULL
);
6058 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, tests
[i
].name
);
6060 IDirectDrawSurface4_Release(surface
);
6065 IDirect3D3_Release(d3d
);
6066 refcount
= IDirectDraw4_Release(ddraw
);
6067 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6068 DestroyWindow(window
);
6071 static void test_surface_discard(void)
6073 IDirect3DDevice3
*device
;
6075 IDirectDraw4
*ddraw
;
6078 DDSURFACEDESC2 ddsd
;
6079 IDirectDrawSurface4
*surface
, *target
;
6088 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6089 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6090 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, TRUE
},
6091 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
},
6092 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
},
6093 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6094 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
},
6095 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
| DDSCAPS2_HINTDYNAMIC
, FALSE
},
6099 window
= create_window();
6100 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
6102 skip("Failed to create a 3D device, skipping test.\n");
6103 DestroyWindow(window
);
6106 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
6107 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
6108 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
6109 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
6110 hr
= IDirect3DDevice3_GetRenderTarget(device
, &target
);
6111 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
6113 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6117 memset(&ddsd
, 0, sizeof(ddsd
));
6118 ddsd
.dwSize
= sizeof(ddsd
);
6119 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6120 ddsd
.ddsCaps
.dwCaps
= tests
[i
].caps
;
6121 ddsd
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
6124 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6125 ok(SUCCEEDED(hr
), "Failed to create offscreen surface, hr %#x, case %u.\n", hr
, i
);
6127 memset(&ddsd
, 0, sizeof(ddsd
));
6128 ddsd
.dwSize
= sizeof(ddsd
);
6129 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6130 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6131 addr
= ddsd
.lpSurface
;
6132 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6133 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6135 memset(&ddsd
, 0, sizeof(ddsd
));
6136 ddsd
.dwSize
= sizeof(ddsd
);
6137 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6138 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6139 discarded
= ddsd
.lpSurface
!= addr
;
6140 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6141 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6143 hr
= IDirectDrawSurface4_Blt(target
, NULL
, surface
, NULL
, DDBLT_WAIT
, NULL
);
6144 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
6146 memset(&ddsd
, 0, sizeof(ddsd
));
6147 ddsd
.dwSize
= sizeof(ddsd
);
6148 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, DDLOCK_DISCARDCONTENTS
, NULL
);
6149 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6150 discarded
|= ddsd
.lpSurface
!= addr
;
6151 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6152 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6154 IDirectDrawSurface4_Release(surface
);
6156 /* Windows 7 reliably changes the address of surfaces that are discardable (Nvidia Kepler,
6157 * AMD r500, evergreen). Windows XP, at least on AMD r200, does not. */
6158 ok(!discarded
|| tests
[i
].discard
, "Expected surface not to be discarded, case %u\n", i
);
6161 IDirectDrawSurface4_Release(target
);
6162 IDirectDraw4_Release(ddraw
);
6163 IDirect3D3_Release(d3d
);
6164 IDirect3DDevice3_Release(device
);
6165 DestroyWindow(window
);
6168 static void fill_surface(IDirectDrawSurface4
*surface
, D3DCOLOR color
)
6170 DDSURFACEDESC2 surface_desc
= {sizeof(surface_desc
)};
6175 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
6176 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6178 for (y
= 0; y
< surface_desc
.dwHeight
; ++y
)
6180 ptr
= (DWORD
*)((BYTE
*)surface_desc
.lpSurface
+ y
* surface_desc
.lPitch
);
6181 for (x
= 0; x
< surface_desc
.dwWidth
; ++x
)
6187 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6188 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6191 static void test_flip(void)
6193 const DWORD placement
= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
;
6194 IDirectDrawSurface4
*frontbuffer
, *backbuffer1
, *backbuffer2
, *backbuffer3
, *surface
;
6195 DDSCAPS2 caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
6196 DDSURFACEDESC2 surface_desc
;
6197 BOOL sysmem_primary
;
6198 IDirectDraw4
*ddraw
;
6199 DWORD expected_caps
;
6213 {"PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE
},
6214 {"OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN
},
6215 {"TEXTURE", DDSCAPS_TEXTURE
},
6218 window
= create_window();
6219 ddraw
= create_ddraw();
6220 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6222 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6223 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6225 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
6227 /* Creating a flippable texture induces a BSoD on some versions of the
6228 * Intel graphics driver. At least Intel GMA 950 with driver version
6229 * 6.14.10.4926 on Windows XP SP3 is affected. */
6230 if ((test_data
[i
].caps
& DDSCAPS_TEXTURE
) && ddraw_is_intel(ddraw
))
6232 win_skip("Skipping flippable texture test.\n");
6236 memset(&surface_desc
, 0, sizeof(surface_desc
));
6237 surface_desc
.dwSize
= sizeof(surface_desc
);
6238 surface_desc
.dwFlags
= DDSD_CAPS
;
6239 if (!(test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6240 surface_desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6241 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6242 surface_desc
.dwWidth
= 512;
6243 surface_desc
.dwHeight
= 512;
6244 U5(surface_desc
).dwBackBufferCount
= 3;
6245 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6246 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6248 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_FLIP
;
6249 surface_desc
.dwFlags
|= DDSD_BACKBUFFERCOUNT
;
6250 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6251 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6253 surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_COMPLEX
;
6254 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FLIP
;
6255 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6256 ok(hr
== DDERR_INVALIDCAPS
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6258 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_COMPLEX
;
6259 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &frontbuffer
, NULL
);
6260 todo_wine_if(test_data
[i
].caps
& DDSCAPS_TEXTURE
)
6261 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6265 memset(&surface_desc
, 0, sizeof(surface_desc
));
6266 surface_desc
.dwSize
= sizeof(surface_desc
);
6267 hr
= IDirectDrawSurface4_GetSurfaceDesc(frontbuffer
, &surface_desc
);
6268 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6269 expected_caps
= DDSCAPS_FRONTBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| test_data
[i
].caps
;
6270 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6271 expected_caps
|= DDSCAPS_VISIBLE
;
6272 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6273 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6274 sysmem_primary
= surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
;
6276 hr
= IDirectDrawSurface4_GetAttachedSurface(frontbuffer
, &caps
, &backbuffer1
);
6277 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6278 memset(&surface_desc
, 0, sizeof(surface_desc
));
6279 surface_desc
.dwSize
= sizeof(surface_desc
);
6280 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer1
, &surface_desc
);
6281 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6282 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6283 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6284 expected_caps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
);
6285 expected_caps
|= DDSCAPS_BACKBUFFER
;
6286 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6287 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6289 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer1
, &caps
, &backbuffer2
);
6290 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6291 memset(&surface_desc
, 0, sizeof(surface_desc
));
6292 surface_desc
.dwSize
= sizeof(surface_desc
);
6293 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer2
, &surface_desc
);
6294 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6295 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6296 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6297 expected_caps
&= ~DDSCAPS_BACKBUFFER
;
6298 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6299 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6301 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer2
, &caps
, &backbuffer3
);
6302 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6303 memset(&surface_desc
, 0, sizeof(surface_desc
));
6304 surface_desc
.dwSize
= sizeof(surface_desc
);
6305 hr
= IDirectDrawSurface4_GetSurfaceDesc(backbuffer3
, &surface_desc
);
6306 ok(SUCCEEDED(hr
), "%s: Failed to get surface desc, hr %#x.\n", test_data
[i
].name
, hr
);
6307 ok(!U5(surface_desc
).dwBackBufferCount
, "%s: Got unexpected back buffer count %u.\n",
6308 test_data
[i
].name
, U5(surface_desc
).dwBackBufferCount
);
6309 ok((surface_desc
.ddsCaps
.dwCaps
& ~placement
) == expected_caps
,
6310 "%s: Got unexpected caps %#x.\n", test_data
[i
].name
, surface_desc
.ddsCaps
.dwCaps
);
6312 hr
= IDirectDrawSurface4_GetAttachedSurface(backbuffer3
, &caps
, &surface
);
6313 ok(SUCCEEDED(hr
), "%s: Failed to get attached surface, hr %#x.\n", test_data
[i
].name
, hr
);
6314 ok(surface
== frontbuffer
, "%s: Got unexpected surface %p, expected %p.\n",
6315 test_data
[i
].name
, surface
, frontbuffer
);
6316 IDirectDrawSurface4_Release(surface
);
6318 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
6319 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6320 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6321 ok(hr
== DD_OK
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6322 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6323 if (test_data
[i
].caps
& DDSCAPS_PRIMARYSURFACE
)
6324 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6326 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6327 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6328 ok(SUCCEEDED(hr
), "%s: Failed to set cooperative level, hr %#x.\n", test_data
[i
].name
, hr
);
6329 hr
= IDirectDrawSurface4_IsLost(frontbuffer
);
6330 todo_wine
ok(hr
== DDERR_SURFACELOST
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6331 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
6332 ok(SUCCEEDED(hr
), "%s: Failed to restore surfaces, hr %#x.\n", test_data
[i
].name
, hr
);
6334 memset(&surface_desc
, 0, sizeof(surface_desc
));
6335 surface_desc
.dwSize
= sizeof(surface_desc
);
6336 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
6337 surface_desc
.ddsCaps
.dwCaps
= 0;
6338 surface_desc
.dwWidth
= 640;
6339 surface_desc
.dwHeight
= 480;
6340 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
6341 ok(SUCCEEDED(hr
), "%s: Failed to create surface, hr %#x.\n", test_data
[i
].name
, hr
);
6342 hr
= IDirectDrawSurface4_Flip(frontbuffer
, surface
, DDFLIP_WAIT
);
6343 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6344 IDirectDrawSurface4_Release(surface
);
6346 hr
= IDirectDrawSurface4_Flip(frontbuffer
, frontbuffer
, DDFLIP_WAIT
);
6347 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6348 hr
= IDirectDrawSurface4_Flip(backbuffer1
, NULL
, DDFLIP_WAIT
);
6349 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6350 hr
= IDirectDrawSurface4_Flip(backbuffer2
, NULL
, DDFLIP_WAIT
);
6351 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6352 hr
= IDirectDrawSurface4_Flip(backbuffer3
, NULL
, DDFLIP_WAIT
);
6353 ok(hr
== DDERR_NOTFLIPPABLE
, "%s: Got unexpected hr %#x.\n", test_data
[i
].name
, hr
);
6355 /* The Nvidia Geforce 7 driver cannot do a color fill on a texture backbuffer after
6356 * the backbuffer has been locked. Do it ourselves as a workaround. Unlike ddraw1
6357 * and 2 GetSurfaceDesc does not cause issues in ddraw4 and ddraw7. */
6358 fill_surface(backbuffer1
, 0xffff0000);
6359 fill_surface(backbuffer2
, 0xff00ff00);
6360 fill_surface(backbuffer3
, 0xff0000ff);
6362 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6363 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6364 color
= get_surface_color(backbuffer1
, 320, 240);
6365 /* The testbot seems to just copy the contents of one surface to all the
6366 * others, instead of properly flipping. */
6367 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6368 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6369 color
= get_surface_color(backbuffer2
, 320, 240);
6370 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6371 fill_surface(backbuffer3
, 0xffff0000);
6373 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6374 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6375 color
= get_surface_color(backbuffer1
, 320, 240);
6376 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6377 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6378 color
= get_surface_color(backbuffer2
, 320, 240);
6379 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6380 fill_surface(backbuffer3
, 0xff00ff00);
6382 hr
= IDirectDrawSurface4_Flip(frontbuffer
, NULL
, DDFLIP_WAIT
);
6383 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6384 color
= get_surface_color(backbuffer1
, 320, 240);
6385 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6386 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6387 color
= get_surface_color(backbuffer2
, 320, 240);
6388 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6389 fill_surface(backbuffer3
, 0xff0000ff);
6391 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer1
, DDFLIP_WAIT
);
6392 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6393 color
= get_surface_color(backbuffer2
, 320, 240);
6394 ok(compare_color(color
, 0x0000ff00, 1) || broken(sysmem_primary
&& compare_color(color
, 0x000000ff, 1)),
6395 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6396 color
= get_surface_color(backbuffer3
, 320, 240);
6397 ok(compare_color(color
, 0x000000ff, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6398 fill_surface(backbuffer1
, 0xffff0000);
6400 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer2
, DDFLIP_WAIT
);
6401 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6402 color
= get_surface_color(backbuffer1
, 320, 240);
6403 ok(compare_color(color
, 0x00ff0000, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6404 color
= get_surface_color(backbuffer3
, 320, 240);
6405 ok(compare_color(color
, 0x000000ff, 1) || broken(sysmem_primary
&& compare_color(color
, 0x00ff0000, 1)),
6406 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6407 fill_surface(backbuffer2
, 0xff00ff00);
6409 hr
= IDirectDrawSurface4_Flip(frontbuffer
, backbuffer3
, DDFLIP_WAIT
);
6410 ok(SUCCEEDED(hr
), "%s: Failed to flip, hr %#x.\n", test_data
[i
].name
, hr
);
6411 color
= get_surface_color(backbuffer1
, 320, 240);
6412 ok(compare_color(color
, 0x00ff0000, 1) || broken(sysmem_primary
&& compare_color(color
, 0x0000ff00, 1)),
6413 "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6414 color
= get_surface_color(backbuffer2
, 320, 240);
6415 ok(compare_color(color
, 0x0000ff00, 1), "%s: Got unexpected color 0x%08x.\n", test_data
[i
].name
, color
);
6417 IDirectDrawSurface4_Release(backbuffer3
);
6418 IDirectDrawSurface4_Release(backbuffer2
);
6419 IDirectDrawSurface4_Release(backbuffer1
);
6420 IDirectDrawSurface4_Release(frontbuffer
);
6423 refcount
= IDirectDraw4_Release(ddraw
);
6424 ok(refcount
== 0, "The ddraw object was not properly freed, refcount %u.\n", refcount
);
6425 DestroyWindow(window
);
6428 static void reset_ddsd(DDSURFACEDESC2
*ddsd
)
6430 memset(ddsd
, 0, sizeof(*ddsd
));
6431 ddsd
->dwSize
= sizeof(*ddsd
);
6434 static void test_set_surface_desc(void)
6436 IDirectDraw4
*ddraw
;
6439 DDSURFACEDESC2 ddsd
;
6440 IDirectDrawSurface4
*surface
;
6450 invalid_caps_tests
[] =
6452 {DDSCAPS_VIDEOMEMORY
, 0, FALSE
, "videomemory plain"},
6453 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, TRUE
, "systemmemory texture"},
6454 {DDSCAPS_TEXTURE
, DDSCAPS2_D3DTEXTUREMANAGE
, FALSE
, "managed texture"},
6455 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, FALSE
, "managed texture"},
6456 {DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
, 0, FALSE
, "systemmemory primary"},
6459 window
= create_window();
6460 ddraw
= create_ddraw();
6461 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6462 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6463 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6466 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6469 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6470 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6471 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6472 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6473 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6474 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6475 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6477 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6478 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6481 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6482 ddsd
.lpSurface
= data
;
6483 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6484 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6486 /* Redundantly setting the same lpSurface is not an error. */
6487 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6488 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6489 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6490 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6491 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6492 ok(ddsd
.lpSurface
== NULL
, "lpSurface is %p, expected NULL.\n", ddsd
.lpSurface
);
6494 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &ddsd
, 0, NULL
);
6495 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
6496 ok(!(ddsd
.dwFlags
& DDSD_LPSURFACE
), "DDSD_LPSURFACE is set.\n");
6497 ok(ddsd
.lpSurface
== data
, "lpSurface is %p, expected %p.\n", data
, data
);
6498 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
6499 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
6502 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6503 ddsd
.lpSurface
= data
;
6504 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 1);
6505 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with flags=1 returned %#x.\n", hr
);
6507 ddsd
.lpSurface
= NULL
;
6508 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6509 ok(hr
== DDERR_INVALIDPARAMS
, "Setting lpSurface=NULL returned %#x.\n", hr
);
6511 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, NULL
, 0);
6512 ok(hr
== DDERR_INVALIDPARAMS
, "SetSurfaceDesc with NULL desc returned %#x.\n", hr
);
6514 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6515 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6516 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6517 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6518 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6520 /* Setting the caps is an error. This also means the original description cannot be reapplied. */
6521 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6522 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the original desc returned %#x.\n", hr
);
6524 ddsd
.dwFlags
= DDSD_CAPS
;
6525 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6526 ok(hr
== DDERR_INVALIDPARAMS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6528 /* dwCaps = 0 is allowed, but ignored. Caps2 can be anything and is ignored too. */
6529 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_LPSURFACE
;
6530 ddsd
.lpSurface
= data
;
6531 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6532 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6533 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6534 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6535 ok(hr
== DDERR_INVALIDCAPS
, "Setting DDSD_CAPS returned %#x.\n", hr
);
6536 ddsd
.ddsCaps
.dwCaps
= 0;
6537 ddsd
.ddsCaps
.dwCaps2
= 0xdeadbeef;
6538 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6539 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6541 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6542 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6543 ok(ddsd
.ddsCaps
.dwCaps
== (DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
),
6544 "Got unexpected caps %#x.\n", ddsd
.ddsCaps
.dwCaps
);
6545 ok(ddsd
.ddsCaps
.dwCaps2
== 0, "Got unexpected caps2 %#x.\n", 0);
6547 /* Setting the height is allowed, but it cannot be set to 0, and only if LPSURFACE is set too. */
6549 ddsd
.dwFlags
= DDSD_HEIGHT
;
6551 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6552 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height without lpSurface returned %#x.\n", hr
);
6554 ddsd
.lpSurface
= data
;
6555 ddsd
.dwFlags
= DDSD_HEIGHT
| DDSD_LPSURFACE
;
6556 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6557 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6560 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6561 ok(hr
== DDERR_INVALIDPARAMS
, "Setting height=0 returned %#x.\n", hr
);
6564 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6565 ok(SUCCEEDED(hr
), "GetSurfaceDesc failed, hr %#x.\n", hr
);
6566 ok(ddsd
.dwWidth
== 8, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6567 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6569 /* Pitch and width can be set, but only together, and only with LPSURFACE. They must not be 0 */
6571 ddsd
.dwFlags
= DDSD_PITCH
;
6572 U1(ddsd
).lPitch
= 8 * 4;
6573 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6574 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch without lpSurface or width returned %#x.\n", hr
);
6576 ddsd
.dwFlags
= DDSD_WIDTH
;
6578 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6579 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width without lpSurface or pitch returned %#x.\n", hr
);
6581 ddsd
.dwFlags
= DDSD_PITCH
| DDSD_LPSURFACE
;
6582 ddsd
.lpSurface
= data
;
6583 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6584 ok(hr
== DDERR_INVALIDPARAMS
, "Setting pitch and lpSurface without width returned %#x.\n", hr
);
6586 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_LPSURFACE
;
6587 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6588 ok(hr
== DDERR_INVALIDPARAMS
, "Setting width and lpSurface without pitch returned %#x.\n", hr
);
6590 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6591 U1(ddsd
).lPitch
= 16 * 4;
6593 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6594 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6597 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &ddsd
);
6598 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6599 ok(ddsd
.dwWidth
== 16, "SetSurfaceDesc: Expected width 8, got %u.\n", ddsd
.dwWidth
);
6600 ok(ddsd
.dwHeight
== 16, "SetSurfaceDesc: Expected height 16, got %u.\n", ddsd
.dwHeight
);
6601 ok(U1(ddsd
).lPitch
== 16 * 4, "SetSurfaceDesc: Expected pitch 64, got %u.\n", U1(ddsd
).lPitch
);
6603 /* The pitch must be 32 bit aligned and > 0, but is not verified for sanity otherwise.
6605 * VMware rejects those calls, but all real drivers accept it. Mark the VMware behavior broken. */
6606 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6607 U1(ddsd
).lPitch
= 4 * 4;
6608 ddsd
.lpSurface
= data
;
6609 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6610 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6612 U1(ddsd
).lPitch
= 4;
6613 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6614 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_INVALIDPARAMS
), "Failed to set surface desc, hr %#x.\n", hr
);
6616 U1(ddsd
).lPitch
= 16 * 4 + 1;
6617 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6618 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6620 U1(ddsd
).lPitch
= 16 * 4 + 3;
6621 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6622 ok(hr
== DDERR_INVALIDPARAMS
, "Setting misaligned pitch returned %#x.\n", hr
);
6624 U1(ddsd
).lPitch
= -4;
6625 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6626 ok(hr
== DDERR_INVALIDPARAMS
, "Setting negative pitch returned %#x.\n", hr
);
6628 U1(ddsd
).lPitch
= 16 * 4;
6629 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6630 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6633 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6634 U1(ddsd
).lPitch
= 0;
6636 ddsd
.lpSurface
= data
;
6637 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6638 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero pitch returned %#x.\n", hr
);
6640 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_PITCH
| DDSD_LPSURFACE
;
6641 U1(ddsd
).lPitch
= 16 * 4;
6643 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6644 ok(hr
== DDERR_INVALIDPARAMS
, "Setting zero width returned %#x.\n", hr
);
6646 /* Setting the pixelformat without LPSURFACE is an error, but with LPSURFACE it works. */
6647 ddsd
.dwFlags
= DDSD_PIXELFORMAT
;
6648 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6649 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6650 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6651 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6652 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6653 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6654 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6655 ok(hr
== DDERR_INVALIDPARAMS
, "Setting the pixel format returned %#x.\n", hr
);
6657 ddsd
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_LPSURFACE
;
6658 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6659 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6661 /* Can't set color keys. */
6663 ddsd
.dwFlags
= DDSD_CKSRCBLT
;
6664 ddsd
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff0000;
6665 ddsd
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff0000;
6666 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6667 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6669 ddsd
.dwFlags
= DDSD_CKSRCBLT
| DDSD_LPSURFACE
;
6670 ddsd
.lpSurface
= data
;
6671 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6672 ok(hr
== DDERR_INVALIDPARAMS
, "Setting ddckCKSrcBlt returned %#x.\n", hr
);
6674 IDirectDrawSurface4_Release(surface
);
6676 /* SetSurfaceDesc needs systemmemory surfaces.
6678 * As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing DDSD_LINEARSIZE is moot. */
6679 for (i
= 0; i
< ARRAY_SIZE(invalid_caps_tests
); i
++)
6682 ddsd
.dwFlags
= DDSD_CAPS
;
6683 ddsd
.ddsCaps
.dwCaps
= invalid_caps_tests
[i
].caps
;
6684 ddsd
.ddsCaps
.dwCaps2
= invalid_caps_tests
[i
].caps2
;
6685 if (!(invalid_caps_tests
[i
].caps
& DDSCAPS_PRIMARYSURFACE
))
6687 ddsd
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
6690 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6691 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6692 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6693 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6694 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6695 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6698 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6699 ok(SUCCEEDED(hr
) || hr
== DDERR_NODIRECTDRAWHW
, "Failed to create surface, hr %#x.\n", hr
);
6702 skip("Cannot create a %s surface, skipping vidmem SetSurfaceDesc test.\n",
6703 invalid_caps_tests
[i
].name
);
6708 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6709 ddsd
.lpSurface
= data
;
6710 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6711 if (invalid_caps_tests
[i
].supported
)
6713 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6717 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6718 invalid_caps_tests
[i
].name
, hr
);
6720 /* Check priority of error conditions. */
6721 ddsd
.dwFlags
= DDSD_WIDTH
;
6722 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6723 ok(hr
== DDERR_INVALIDSURFACETYPE
, "SetSurfaceDesc on a %s surface returned %#x.\n",
6724 invalid_caps_tests
[i
].name
, hr
);
6727 IDirectDrawSurface4_Release(surface
);
6731 ref
= IDirectDraw4_Release(ddraw
);
6732 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6733 DestroyWindow(window
);
6736 static void test_user_memory_getdc(void)
6738 IDirectDraw4
*ddraw
;
6741 DDSURFACEDESC2 ddsd
;
6742 IDirectDrawSurface4
*surface
;
6751 window
= create_window();
6752 ddraw
= create_ddraw();
6753 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6755 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6756 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6759 ddsd
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
6762 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6763 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6764 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6765 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6766 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6767 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6768 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
6769 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6770 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6772 memset(data
, 0xaa, sizeof(data
));
6774 ddsd
.dwFlags
= DDSD_LPSURFACE
;
6775 ddsd
.lpSurface
= data
;
6776 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6777 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6779 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
6780 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6781 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
6782 ok(!!bitmap
, "Failed to get bitmap.\n");
6783 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
6784 ok(size
== sizeof(dib
), "Got unexpected size %d.\n", size
);
6785 ok(dib
.dsBm
.bmBits
== data
, "Got unexpected bits %p, expected %p.\n", dib
.dsBm
.bmBits
, data
);
6786 BitBlt(dc
, 0, 0, 16, 8, NULL
, 0, 0, WHITENESS
);
6787 BitBlt(dc
, 0, 8, 16, 8, NULL
, 0, 0, BLACKNESS
);
6788 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
6789 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6791 ok(data
[0][0] == 0xffffffff, "Expected color 0xffffffff, got %#x.\n", data
[0][0]);
6792 ok(data
[15][15] == 0x00000000, "Expected color 0x00000000, got %#x.\n", data
[15][15]);
6794 ddsd
.dwFlags
= DDSD_LPSURFACE
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PITCH
;
6795 ddsd
.lpSurface
= data
;
6798 U1(ddsd
).lPitch
= sizeof(*data
);
6799 hr
= IDirectDrawSurface4_SetSurfaceDesc(surface
, &ddsd
, 0);
6800 ok(SUCCEEDED(hr
), "Failed to set surface desc, hr %#x.\n", hr
);
6802 memset(data
, 0xaa, sizeof(data
));
6803 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
6804 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
6805 BitBlt(dc
, 0, 0, 4, 8, NULL
, 0, 0, BLACKNESS
);
6806 BitBlt(dc
, 1, 1, 2, 2, NULL
, 0, 0, WHITENESS
);
6807 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
6808 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
6810 for (y
= 0; y
< 4; y
++)
6812 for (x
= 0; x
< 4; x
++)
6814 if ((x
== 1 || x
== 2) && (y
== 1 || y
== 2))
6815 ok(data
[y
][x
] == 0xffffffff, "Expected color 0xffffffff on position %ux%u, got %#x.\n",
6818 ok(data
[y
][x
] == 0x00000000, "Expected color 0x00000000 on position %ux%u, got %#x.\n",
6822 ok(data
[0][5] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 5x0, got %#x.\n",
6824 ok(data
[7][3] == 0x00000000, "Expected color 0x00000000 on position 3x7, got %#x.\n",
6826 ok(data
[7][4] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 4x7, got %#x.\n",
6828 ok(data
[8][0] == 0xaaaaaaaa, "Expected color 0xaaaaaaaa on position 0x8, got %#x.\n",
6831 IDirectDrawSurface4_Release(surface
);
6832 ref
= IDirectDraw4_Release(ddraw
);
6833 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6834 DestroyWindow(window
);
6837 static void test_sysmem_overlay(void)
6839 IDirectDraw4
*ddraw
;
6842 DDSURFACEDESC2 ddsd
;
6843 IDirectDrawSurface4
*surface
;
6846 window
= create_window();
6847 ddraw
= create_ddraw();
6848 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6850 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
6851 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6854 ddsd
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
6857 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OVERLAY
;
6858 U4(ddsd
).ddpfPixelFormat
.dwSize
= sizeof(U4(ddsd
).ddpfPixelFormat
);
6859 U4(ddsd
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
6860 U1(U4(ddsd
).ddpfPixelFormat
).dwRGBBitCount
= 32;
6861 U2(U4(ddsd
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
6862 U3(U4(ddsd
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
6863 U4(U4(ddsd
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
6864 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
6865 ok(hr
== DDERR_NOOVERLAYHW
, "Got unexpected hr %#x.\n", hr
);
6867 ref
= IDirectDraw4_Release(ddraw
);
6868 ok(ref
== 0, "Ddraw object not properly released, refcount %u.\n", ref
);
6869 DestroyWindow(window
);
6872 static void test_primary_palette(void)
6874 DDSCAPS2 surface_caps
= {DDSCAPS_FLIP
, 0, 0, {0}};
6875 IDirectDrawSurface4
*primary
, *backbuffer
;
6876 PALETTEENTRY palette_entries
[256];
6877 IDirectDrawPalette
*palette
, *tmp
;
6878 DDSURFACEDESC2 surface_desc
;
6879 IDirectDraw4
*ddraw
;
6885 window
= create_window();
6886 ddraw
= create_ddraw();
6887 ok(!!ddraw
, "Failed to create a ddraw object.\n");
6888 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
6890 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
6891 IDirectDraw4_Release(ddraw
);
6892 DestroyWindow(window
);
6895 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
6896 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
6898 memset(&surface_desc
, 0, sizeof(surface_desc
));
6899 surface_desc
.dwSize
= sizeof(surface_desc
);
6900 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
6901 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
6902 U5(surface_desc
).dwBackBufferCount
= 1;
6903 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
6904 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
6905 hr
= IDirectDrawSurface4_GetAttachedSurface(primary
, &surface_caps
, &backbuffer
);
6906 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
6908 memset(palette_entries
, 0, sizeof(palette_entries
));
6909 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
, palette_entries
, &palette
, NULL
);
6910 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
6911 refcount
= get_refcount((IUnknown
*)palette
);
6912 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6914 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6915 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6916 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6918 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
6919 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6921 /* The Windows 8 testbot attaches the palette to the backbuffer as well,
6922 * and is generally somewhat broken with respect to 8 bpp / palette
6924 if (SUCCEEDED(IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
)))
6926 win_skip("Broken palette handling detected, skipping tests.\n");
6927 IDirectDrawPalette_Release(tmp
);
6928 IDirectDrawPalette_Release(palette
);
6929 /* The Windows 8 testbot keeps extra references to the primary and
6930 * backbuffer while in 8 bpp mode. */
6931 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
6932 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
6936 refcount
= get_refcount((IUnknown
*)palette
);
6937 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6939 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6940 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6941 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_PRIMARYSURFACE
| DDPCAPS_ALLOW256
),
6942 "Got unexpected palette caps %#x.\n", palette_caps
);
6944 hr
= IDirectDrawSurface4_SetPalette(primary
, NULL
);
6945 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6946 refcount
= get_refcount((IUnknown
*)palette
);
6947 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6949 hr
= IDirectDrawPalette_GetCaps(palette
, &palette_caps
);
6950 ok(SUCCEEDED(hr
), "Failed to get palette caps, hr %#x.\n", hr
);
6951 ok(palette_caps
== (DDPCAPS_8BIT
| DDPCAPS_ALLOW256
), "Got unexpected palette caps %#x.\n", palette_caps
);
6953 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
6954 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
6955 refcount
= get_refcount((IUnknown
*)palette
);
6956 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
6958 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
6959 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
6960 ok(tmp
== palette
, "Got unexpected palette %p, expected %p.\n", tmp
, palette
);
6961 IDirectDrawPalette_Release(tmp
);
6962 hr
= IDirectDrawSurface4_GetPalette(backbuffer
, &tmp
);
6963 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6965 refcount
= IDirectDrawPalette_Release(palette
);
6966 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
6967 refcount
= IDirectDrawPalette_Release(palette
);
6968 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
6970 /* Note that this only seems to work when the palette is attached to the
6971 * primary surface. When attached to a regular surface, attempting to get
6972 * the palette here will cause an access violation. */
6973 hr
= IDirectDrawSurface4_GetPalette(primary
, &tmp
);
6974 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
6976 hr
= IDirectDrawSurface4_IsLost(primary
);
6977 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
6979 memset(&surface_desc
, 0, sizeof(surface_desc
));
6980 surface_desc
.dwSize
= sizeof(surface_desc
);
6981 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
6982 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6983 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6984 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6985 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 8, "Got unexpected bit count %u.\n",
6986 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
6988 hr
= set_display_mode(ddraw
, 640, 480);
6989 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
6991 memset(&surface_desc
, 0, sizeof(surface_desc
));
6992 surface_desc
.dwSize
= sizeof(surface_desc
);
6993 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
6994 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
6995 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
6996 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
6997 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
6998 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
6999 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7001 hr
= IDirectDrawSurface4_IsLost(primary
);
7002 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7003 hr
= IDirectDrawSurface4_Restore(primary
);
7004 ok(hr
== DDERR_WRONGMODE
, "Got unexpected hr %#x.\n", hr
);
7005 hr
= IDirectDrawSurface4_IsLost(primary
);
7006 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
7008 memset(&surface_desc
, 0, sizeof(surface_desc
));
7009 surface_desc
.dwSize
= sizeof(surface_desc
);
7010 hr
= IDirectDrawSurface4_GetSurfaceDesc(primary
, &surface_desc
);
7011 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
7012 ok(surface_desc
.dwWidth
== 640, "Got unexpected surface width %u.\n", surface_desc
.dwWidth
);
7013 ok(surface_desc
.dwHeight
== 480, "Got unexpected surface height %u.\n", surface_desc
.dwHeight
);
7014 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 32
7015 || U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== 24,
7016 "Got unexpected bit count %u.\n", U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
);
7019 refcount
= IDirectDrawSurface4_Release(backbuffer
);
7020 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7021 refcount
= IDirectDrawSurface4_Release(primary
);
7022 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7023 refcount
= IDirectDraw4_Release(ddraw
);
7024 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7025 DestroyWindow(window
);
7028 static HRESULT WINAPI
surface_counter(IDirectDrawSurface4
*surface
, DDSURFACEDESC2
*desc
, void *context
)
7030 UINT
*surface_count
= context
;
7033 IDirectDrawSurface_Release(surface
);
7035 return DDENUMRET_OK
;
7038 static void test_surface_attachment(void)
7040 IDirectDrawSurface4
*surface1
, *surface2
, *surface3
, *surface4
;
7041 IDirectDrawSurface
*surface1v1
, *surface2v1
;
7042 DDSCAPS2 caps
= {DDSCAPS_TEXTURE
, 0, 0, {0}};
7043 DDSURFACEDESC2 surface_desc
;
7044 IDirectDraw4
*ddraw
;
7050 window
= create_window();
7051 ddraw
= create_ddraw();
7052 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7053 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7054 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7056 memset(&surface_desc
, 0, sizeof(surface_desc
));
7057 surface_desc
.dwSize
= sizeof(surface_desc
);
7058 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_MIPMAPCOUNT
;
7059 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7060 U2(surface_desc
).dwMipMapCount
= 3;
7061 surface_desc
.dwWidth
= 128;
7062 surface_desc
.dwHeight
= 128;
7063 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7064 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7066 hr
= IDirectDrawSurface4_GetAttachedSurface(surface1
, &caps
, &surface2
);
7067 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7068 hr
= IDirectDrawSurface4_GetAttachedSurface(surface2
, &caps
, &surface3
);
7069 ok(SUCCEEDED(hr
), "Failed to get mip level, hr %#x.\n", hr
);
7070 hr
= IDirectDrawSurface4_GetAttachedSurface(surface3
, &caps
, &surface4
);
7071 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7074 IDirectDrawSurface4_EnumAttachedSurfaces(surface1
, &surface_count
, surface_counter
);
7075 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7077 IDirectDrawSurface4_EnumAttachedSurfaces(surface2
, &surface_count
, surface_counter
);
7078 ok(surface_count
== 1, "Got unexpected surface_count %u.\n", surface_count
);
7080 IDirectDrawSurface4_EnumAttachedSurfaces(surface3
, &surface_count
, surface_counter
);
7081 ok(!surface_count
, "Got unexpected surface_count %u.\n", surface_count
);
7083 memset(&surface_desc
, 0, sizeof(surface_desc
));
7084 surface_desc
.dwSize
= sizeof(surface_desc
);
7085 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7086 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
7087 surface_desc
.dwWidth
= 16;
7088 surface_desc
.dwHeight
= 16;
7089 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7090 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7092 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7093 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7094 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7095 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7096 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7097 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7098 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7099 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7100 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7101 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7102 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7103 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7105 IDirectDrawSurface4_Release(surface4
);
7107 memset(&surface_desc
, 0, sizeof(surface_desc
));
7108 surface_desc
.dwSize
= sizeof(surface_desc
);
7109 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7110 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7111 surface_desc
.dwWidth
= 16;
7112 surface_desc
.dwHeight
= 16;
7113 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7114 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7116 if (SUCCEEDED(hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
)))
7118 skip("Running on refrast, skipping some tests.\n");
7119 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface4
);
7120 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7124 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7125 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7126 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7127 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface4
);
7128 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7129 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface3
);
7130 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7131 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface4
);
7132 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7133 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface2
);
7134 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7137 IDirectDrawSurface4_Release(surface4
);
7138 IDirectDrawSurface4_Release(surface3
);
7139 IDirectDrawSurface4_Release(surface2
);
7140 IDirectDrawSurface4_Release(surface1
);
7142 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
7143 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7145 /* Try a single primary and two offscreen plain surfaces. */
7146 memset(&surface_desc
, 0, sizeof(surface_desc
));
7147 surface_desc
.dwSize
= sizeof(surface_desc
);
7148 surface_desc
.dwFlags
= DDSD_CAPS
;
7149 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7150 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7151 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7153 memset(&surface_desc
, 0, sizeof(surface_desc
));
7154 surface_desc
.dwSize
= sizeof(surface_desc
);
7155 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7156 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7157 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7158 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7159 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7160 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7162 memset(&surface_desc
, 0, sizeof(surface_desc
));
7163 surface_desc
.dwSize
= sizeof(surface_desc
);
7164 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7165 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7166 surface_desc
.dwWidth
= registry_mode
.dmPelsWidth
;
7167 surface_desc
.dwHeight
= registry_mode
.dmPelsHeight
;
7168 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7169 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7171 /* This one has a different size. */
7172 memset(&surface_desc
, 0, sizeof(surface_desc
));
7173 surface_desc
.dwSize
= sizeof(surface_desc
);
7174 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
7175 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
7176 surface_desc
.dwWidth
= 128;
7177 surface_desc
.dwHeight
= 128;
7178 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
);
7179 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7181 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7182 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7183 /* Try the reverse without detaching first. */
7184 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7185 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7186 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7187 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7189 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface1
);
7190 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7191 /* Try to detach reversed. */
7192 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7193 ok(hr
== DDERR_CANNOTDETACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7194 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface1
);
7195 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7197 hr
= IDirectDrawSurface4_AddAttachedSurface(surface2
, surface3
);
7198 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7199 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface2
, 0, surface3
);
7200 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7202 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface4
);
7203 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7204 hr
= IDirectDrawSurface4_AddAttachedSurface(surface4
, surface1
);
7205 ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7207 IDirectDrawSurface4_Release(surface4
);
7208 IDirectDrawSurface4_Release(surface3
);
7209 IDirectDrawSurface4_Release(surface2
);
7210 IDirectDrawSurface4_Release(surface1
);
7212 /* Test DeleteAttachedSurface() and automatic detachment of attached surfaces on release. */
7213 memset(&surface_desc
, 0, sizeof(surface_desc
));
7214 surface_desc
.dwSize
= sizeof(surface_desc
);
7215 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7216 surface_desc
.dwWidth
= 64;
7217 surface_desc
.dwHeight
= 64;
7218 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
7219 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7220 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
; /* D3DFMT_R5G6B5 */
7221 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
7222 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
7223 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
7224 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
7225 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
7226 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7227 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface3
, NULL
);
7228 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7230 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
7231 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
7232 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= 16;
7233 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= 0x0000ffff;
7234 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
7235 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7237 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirectDrawSurface
, (void **)&surface1v1
);
7238 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7239 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirectDrawSurface
, (void **)&surface2v1
);
7240 ok(SUCCEEDED(hr
), "Failed to get interface, hr %#x.\n", hr
);
7242 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7243 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7244 refcount
= get_refcount((IUnknown
*)surface2
);
7245 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7246 refcount
= get_refcount((IUnknown
*)surface2v1
);
7247 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7248 hr
= IDirectDrawSurface4_AddAttachedSurface(surface1
, surface2
);
7249 ok(hr
== DDERR_SURFACEALREADYATTACHED
, "Got unexpected hr %#x.\n", hr
);
7250 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7251 todo_wine
ok(hr
== DDERR_CANNOTATTACHSURFACE
, "Got unexpected hr %#x.\n", hr
);
7252 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7253 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7255 /* Attaching while already attached to other surface. */
7256 hr
= IDirectDrawSurface4_AddAttachedSurface(surface3
, surface2
);
7257 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7258 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface3
, 0, surface2
);
7259 todo_wine
ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7260 IDirectDrawSurface4_Release(surface3
);
7262 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7263 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7264 refcount
= get_refcount((IUnknown
*)surface2
);
7265 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7266 refcount
= get_refcount((IUnknown
*)surface2v1
);
7267 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
7269 /* DeleteAttachedSurface() when attaching via IDirectDrawSurface. */
7270 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7271 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7272 hr
= IDirectDrawSurface4_DeleteAttachedSurface(surface1
, 0, surface2
);
7273 ok(hr
== DDERR_SURFACENOTATTACHED
, "Got unexpected hr %#x.\n", hr
);
7274 hr
= IDirectDrawSurface_DeleteAttachedSurface(surface1v1
, 0, surface2v1
);
7275 ok(SUCCEEDED(hr
), "Failed to detach surface, hr %#x.\n", hr
);
7276 refcount
= IDirectDrawSurface4_Release(surface2
);
7277 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7278 refcount
= IDirectDrawSurface4_Release(surface1
);
7279 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7281 /* Automatic detachment on release. */
7282 hr
= IDirectDrawSurface_AddAttachedSurface(surface1v1
, surface2v1
);
7283 ok(SUCCEEDED(hr
), "Failed to attach surface, hr %#x.\n", hr
);
7284 refcount
= get_refcount((IUnknown
*)surface2v1
);
7285 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
7286 refcount
= IDirectDrawSurface_Release(surface1v1
);
7287 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7288 refcount
= IDirectDrawSurface_Release(surface2v1
);
7289 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7290 refcount
= IDirectDraw4_Release(ddraw
);
7291 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7292 DestroyWindow(window
);
7295 static void test_private_data(void)
7297 IDirectDraw4
*ddraw
;
7298 IDirectDrawSurface4
*surface
, *surface2
;
7299 DDSURFACEDESC2 surface_desc
;
7300 ULONG refcount
, refcount2
, refcount3
;
7302 DWORD size
= sizeof(ptr
);
7305 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7306 DWORD data
[] = {1, 2, 3, 4};
7308 static const GUID ddraw_private_data_test_guid
=
7313 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
7315 static const GUID ddraw_private_data_test_guid2
=
7320 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
7323 window
= create_window();
7324 ddraw
= create_ddraw();
7325 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7326 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7327 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7329 reset_ddsd(&surface_desc
);
7330 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
7331 surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_OFFSCREENPLAIN
;
7332 surface_desc
.dwHeight
= 4;
7333 surface_desc
.dwWidth
= 4;
7334 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7335 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7337 /* NULL pointers are not valid, but don't cause a crash. */
7338 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
,
7339 sizeof(IUnknown
*), DDSPD_IUNKNOWNPOINTER
);
7340 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7341 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 0, 0);
7342 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7343 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, 1, 0);
7344 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7346 /* DDSPD_IUNKNOWNPOINTER needs sizeof(IUnknown *) bytes of data. */
7347 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7348 0, DDSPD_IUNKNOWNPOINTER
);
7349 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7350 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7351 5, DDSPD_IUNKNOWNPOINTER
);
7352 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7353 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7354 sizeof(ddraw
) * 2, DDSPD_IUNKNOWNPOINTER
);
7355 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7357 /* Note that with a size != 0 and size != sizeof(IUnknown *) and
7358 * DDSPD_IUNKNOWNPOINTER set SetPrivateData in ddraw4 and ddraw7
7359 * erases the old content and returns an error. This behavior has
7360 * been fixed in d3d8 and d3d9. Unless an application is found
7361 * that depends on this we don't care about this behavior. */
7362 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7363 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7364 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7365 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7366 0, DDSPD_IUNKNOWNPOINTER
);
7367 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7369 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7370 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7371 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7372 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7374 refcount
= get_refcount((IUnknown
*)ddraw
);
7375 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7376 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7377 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7378 refcount2
= get_refcount((IUnknown
*)ddraw
);
7379 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7381 hr
= IDirectDrawSurface4_FreePrivateData(surface
, &ddraw_private_data_test_guid
);
7382 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#x.\n", hr
);
7383 refcount2
= get_refcount((IUnknown
*)ddraw
);
7384 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7386 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7387 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7388 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7389 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, surface
,
7390 sizeof(surface
), DDSPD_IUNKNOWNPOINTER
);
7391 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7392 refcount2
= get_refcount((IUnknown
*)ddraw
);
7393 ok(refcount2
== refcount
, "Got unexpected refcount %u.\n", refcount2
);
7395 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, ddraw
,
7396 sizeof(ddraw
), DDSPD_IUNKNOWNPOINTER
);
7397 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7398 size
= 2 * sizeof(ptr
);
7399 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7400 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#x.\n", hr
);
7401 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7402 refcount2
= get_refcount(ptr
);
7403 /* Object is NOT addref'ed by the getter. */
7404 ok(ptr
== (IUnknown
*)ddraw
, "Returned interface pointer is %p, expected %p.\n", ptr
, ddraw
);
7405 ok(refcount2
== refcount
+ 1, "Got unexpected refcount %u.\n", refcount2
);
7407 ptr
= (IUnknown
*)0xdeadbeef;
7409 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7410 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7411 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7412 size
= 2 * sizeof(ptr
);
7413 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, &size
);
7414 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7415 ok(size
== 2 * sizeof(ptr
), "Got unexpected size %u.\n", size
);
7417 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, &ptr
, &size
);
7418 ok(hr
== DDERR_MOREDATA
, "Got unexpected hr %#x.\n", hr
);
7419 ok(size
== sizeof(ddraw
), "Got unexpected size %u.\n", size
);
7420 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7421 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, NULL
, NULL
);
7422 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7424 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid2
, &ptr
, &size
);
7425 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7426 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
7427 ok(size
== 0xdeadbabe, "Got unexpected size %u.\n", size
);
7428 hr
= IDirectDrawSurface4_GetPrivateData(surface
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7429 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
7431 refcount3
= IDirectDrawSurface4_Release(surface
);
7432 ok(!refcount3
, "Got unexpected refcount %u.\n", refcount3
);
7434 /* Destroying the surface frees the reference held on the private data. It also frees
7435 * the reference the surface is holding on its creating object. */
7436 refcount2
= get_refcount((IUnknown
*)ddraw
);
7437 ok(refcount2
== refcount
- 1, "Got unexpected refcount %u.\n", refcount2
);
7439 memset(&hal_caps
, 0, sizeof(hal_caps
));
7440 hal_caps
.dwSize
= sizeof(hal_caps
);
7441 hr
= IDirectDraw7_GetCaps(ddraw
, &hal_caps
, NULL
);
7442 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7443 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) == (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7445 reset_ddsd(&surface_desc
);
7446 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_MIPMAPCOUNT
;
7447 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7448 surface_desc
.dwHeight
= 4;
7449 surface_desc
.dwWidth
= 4;
7450 U2(surface_desc
).dwMipMapCount
= 2;
7451 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7452 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7453 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7454 ok(SUCCEEDED(hr
), "Failed to get attached surface, hr %#x.\n", hr
);
7456 hr
= IDirectDrawSurface4_SetPrivateData(surface
, &ddraw_private_data_test_guid
, data
, sizeof(data
), 0);
7457 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#x.\n", hr
);
7458 hr
= IDirectDrawSurface4_GetPrivateData(surface2
, &ddraw_private_data_test_guid
, NULL
, NULL
);
7459 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7461 IDirectDrawSurface4_Release(surface2
);
7462 IDirectDrawSurface4_Release(surface
);
7465 skip("Mipmapped textures not supported, skipping mipmap private data test.\n");
7467 refcount
= IDirectDraw4_Release(ddraw
);
7468 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7469 DestroyWindow(window
);
7472 static void test_pixel_format(void)
7474 HWND window
, window2
= NULL
;
7475 HDC hdc
, hdc2
= NULL
;
7477 int format
, test_format
;
7478 PIXELFORMATDESCRIPTOR pfd
;
7479 IDirectDraw4
*ddraw
= NULL
;
7480 IDirectDrawClipper
*clipper
= NULL
;
7481 DDSURFACEDESC2 ddsd
;
7482 IDirectDrawSurface4
*primary
= NULL
;
7486 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7487 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7490 skip("Failed to create window\n");
7494 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7495 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
7497 hdc
= GetDC(window
);
7500 skip("Failed to get DC\n");
7505 hdc2
= GetDC(window2
);
7507 gl
= LoadLibraryA("opengl32.dll");
7508 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
7510 format
= GetPixelFormat(hdc
);
7511 ok(format
== 0, "new window has pixel format %d\n", format
);
7513 ZeroMemory(&pfd
, sizeof(pfd
));
7514 pfd
.nSize
= sizeof(pfd
);
7516 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
7517 pfd
.iPixelType
= PFD_TYPE_RGBA
;
7518 pfd
.iLayerType
= PFD_MAIN_PLANE
;
7519 format
= ChoosePixelFormat(hdc
, &pfd
);
7522 skip("no pixel format available\n");
7526 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7528 skip("failed to set pixel format\n");
7532 if (!hdc2
|| !SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7534 skip("failed to set pixel format on second window\n");
7537 ReleaseDC(window2
, hdc2
);
7542 ddraw
= create_ddraw();
7543 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7545 test_format
= GetPixelFormat(hdc
);
7546 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7548 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7551 skip("Failed to set cooperative level, hr %#x.\n", hr
);
7555 test_format
= GetPixelFormat(hdc
);
7556 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7560 hr
= IDirectDraw4_CreateClipper(ddraw
, 0, &clipper
, NULL
);
7561 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
7562 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window2
);
7563 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
7565 test_format
= GetPixelFormat(hdc
);
7566 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7568 test_format
= GetPixelFormat(hdc2
);
7569 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7572 memset(&ddsd
, 0, sizeof(ddsd
));
7573 ddsd
.dwSize
= sizeof(ddsd
);
7574 ddsd
.dwFlags
= DDSD_CAPS
;
7575 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7577 hr
= IDirectDraw4_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
7578 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
7580 test_format
= GetPixelFormat(hdc
);
7581 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7585 test_format
= GetPixelFormat(hdc2
);
7586 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7591 hr
= IDirectDrawSurface4_SetClipper(primary
, clipper
);
7592 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
7594 test_format
= GetPixelFormat(hdc
);
7595 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7597 test_format
= GetPixelFormat(hdc2
);
7598 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7601 memset(&fx
, 0, sizeof(fx
));
7602 fx
.dwSize
= sizeof(fx
);
7603 hr
= IDirectDrawSurface4_Blt(primary
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
7604 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
7606 test_format
= GetPixelFormat(hdc
);
7607 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7611 test_format
= GetPixelFormat(hdc2
);
7612 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7616 if (primary
) IDirectDrawSurface4_Release(primary
);
7617 if (clipper
) IDirectDrawClipper_Release(clipper
);
7618 if (ddraw
) IDirectDraw4_Release(ddraw
);
7619 if (gl
) FreeLibrary(gl
);
7620 if (hdc
) ReleaseDC(window
, hdc
);
7621 if (hdc2
) ReleaseDC(window2
, hdc2
);
7622 if (window
) DestroyWindow(window
);
7623 if (window2
) DestroyWindow(window2
);
7626 static void test_create_surface_pitch(void)
7628 IDirectDrawSurface4
*surface
;
7629 DDSURFACEDESC2 surface_desc
;
7630 IDirectDraw4
*ddraw
;
7650 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7652 DDSD_PITCH
, 0x100, 0x100},
7653 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7654 DDSD_PITCH
, 0x104, DD_OK
,
7655 DDSD_PITCH
, 0x100, 0x100},
7656 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7657 DDSD_PITCH
, 0x0f8, DD_OK
,
7658 DDSD_PITCH
, 0x100, 0x100},
7659 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7660 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7662 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7664 DDSD_PITCH
, 0x100, 0x0fc},
7666 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7667 DDSD_PITCH
, 0x104, DD_OK
,
7668 DDSD_PITCH
, 0x100, 0x0fc},
7669 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7670 DDSD_PITCH
, 0x0f8, DD_OK
,
7671 DDSD_PITCH
, 0x100, 0x0fc},
7672 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7673 DDSD_PITCH
| DDSD_LINEARSIZE
, 0, DD_OK
,
7674 DDSD_PITCH
, 0x100, 0x0fc},
7675 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7676 DDSD_LPSURFACE
, 0, DDERR_INVALIDPARAMS
,
7678 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7679 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
7680 DDSD_PITCH
, 0x100, 0x100},
7682 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7683 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fe, DDERR_INVALIDPARAMS
,
7685 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7686 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0fc, DD_OK
,
7687 DDSD_PITCH
, 0x0fc, 0x0fc},
7688 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7689 DDSD_LPSURFACE
| DDSD_PITCH
, 0x0f8, DDERR_INVALIDPARAMS
,
7691 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7692 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x100, DDERR_INVALIDPARAMS
,
7694 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7695 DDSD_LPSURFACE
| DDSD_LINEARSIZE
, 0x3f00, DDERR_INVALIDPARAMS
,
7698 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
,
7699 DDSD_LPSURFACE
| DDSD_PITCH
| DDSD_LINEARSIZE
, 0x100, DD_OK
,
7700 DDSD_PITCH
, 0x100, 0x100},
7701 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7702 0, 0, DDERR_INVALIDCAPS
,
7704 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7706 DDSD_PITCH
, 0x100, 0 },
7707 {DDSCAPS_VIDEOMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7708 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DDERR_INVALIDCAPS
,
7710 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_ALLOCONLOAD
,
7711 0, 0, DDERR_INVALIDCAPS
,
7714 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7716 DDSD_PITCH
, 0x100, 0 },
7717 {DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
| DDSCAPS_ALLOCONLOAD
,
7718 DDSD_LPSURFACE
| DDSD_PITCH
, 0x100, DD_OK
,
7719 DDSD_PITCH
, 0x100, 0 },
7721 DWORD flags_mask
= DDSD_PITCH
| DDSD_LPSURFACE
| DDSD_LINEARSIZE
;
7723 window
= create_window();
7724 ddraw
= create_ddraw();
7725 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7726 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7727 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7729 mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((63 * 4) + 8) * 63);
7731 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7733 memset(&surface_desc
, 0, sizeof(surface_desc
));
7734 surface_desc
.dwSize
= sizeof(surface_desc
);
7735 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| test_data
[i
].flags_in
;
7736 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
7737 surface_desc
.dwWidth
= 63;
7738 surface_desc
.dwHeight
= 63;
7739 U1(surface_desc
).lPitch
= test_data
[i
].pitch_in
;
7740 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7741 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
7742 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
7743 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
7744 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
7745 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
7746 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7747 if (test_data
[i
].flags_in
& DDSD_LPSURFACE
)
7749 HRESULT expected_hr
= SUCCEEDED(test_data
[i
].hr
) ? DDERR_INVALIDPARAMS
: test_data
[i
].hr
;
7750 ok(hr
== expected_hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, expected_hr
);
7751 surface_desc
.lpSurface
= mem
;
7752 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7754 if ((test_data
[i
].caps
& DDSCAPS_VIDEOMEMORY
) && hr
== DDERR_NODIRECTDRAWHW
)
7756 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
7760 memset(&surface_desc
, 0, sizeof(surface_desc
));
7761 surface_desc
.dwSize
= sizeof(surface_desc
);
7762 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
7763 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7764 ok((surface_desc
.dwFlags
& flags_mask
) == test_data
[i
].flags_out
,
7765 "Test %u: Got unexpected flags %#x, expected %#x.\n",
7766 i
, surface_desc
.dwFlags
& flags_mask
, test_data
[i
].flags_out
);
7767 /* The pitch for textures seems to be implementation specific. */
7768 if (!(test_data
[i
].caps
& DDSCAPS_TEXTURE
))
7770 if (is_ddraw64
&& test_data
[i
].pitch_out32
!= test_data
[i
].pitch_out64
)
7771 todo_wine
ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out64
,
7772 "Test %u: Got unexpected pitch %u, expected %u.\n",
7773 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out64
);
7775 ok(U1(surface_desc
).lPitch
== test_data
[i
].pitch_out32
,
7776 "Test %u: Got unexpected pitch %u, expected %u.\n",
7777 i
, U1(surface_desc
).lPitch
, test_data
[i
].pitch_out32
);
7779 ok(!surface_desc
.lpSurface
, "Test %u: Got unexpected lpSurface %p.\n", i
, surface_desc
.lpSurface
);
7781 IDirectDrawSurface4_Release(surface
);
7784 HeapFree(GetProcessHeap(), 0, mem
);
7785 refcount
= IDirectDraw4_Release(ddraw
);
7786 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7787 DestroyWindow(window
);
7790 static void test_mipmap(void)
7792 IDirectDrawSurface4
*surface
, *surface2
;
7793 DDSURFACEDESC2 surface_desc
;
7794 IDirectDraw4
*ddraw
;
7799 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7808 DWORD mipmap_count_in
;
7810 DWORD mipmap_count_out
;
7814 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 3, DD_OK
, 3},
7815 {DDSD_MIPMAPCOUNT
, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDPARAMS
, 0},
7816 {0, DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 1},
7817 {0, DDSCAPS_MIPMAP
, 128, 32, 0, DDERR_INVALIDCAPS
, 0},
7818 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 128, 32, 0, DD_OK
, 6},
7819 {0, DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
, 32, 64, 0, DD_OK
, 6},
7822 window
= create_window();
7823 ddraw
= create_ddraw();
7824 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7825 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7826 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7828 memset(&hal_caps
, 0, sizeof(hal_caps
));
7829 hal_caps
.dwSize
= sizeof(hal_caps
);
7830 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
7831 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7832 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7834 skip("Mipmapped textures not supported, skipping tests.\n");
7835 IDirectDraw4_Release(ddraw
);
7836 DestroyWindow(window
);
7840 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7842 memset(&surface_desc
, 0, sizeof(surface_desc
));
7843 surface_desc
.dwSize
= sizeof(surface_desc
);
7844 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| tests
[i
].flags
;
7845 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
7846 surface_desc
.dwWidth
= tests
[i
].width
;
7847 surface_desc
.dwHeight
= tests
[i
].height
;
7848 if (tests
[i
].flags
& DDSD_MIPMAPCOUNT
)
7849 U2(surface_desc
).dwMipMapCount
= tests
[i
].mipmap_count_in
;
7850 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7851 ok(hr
== tests
[i
].hr
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
7855 memset(&surface_desc
, 0, sizeof(surface_desc
));
7856 surface_desc
.dwSize
= sizeof(surface_desc
);
7857 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
7858 ok(SUCCEEDED(hr
), "Test %u: Failed to get surface desc, hr %#x.\n", i
, hr
);
7859 ok(surface_desc
.dwFlags
& DDSD_MIPMAPCOUNT
,
7860 "Test %u: Got unexpected flags %#x.\n", i
, surface_desc
.dwFlags
);
7861 ok(U2(surface_desc
).dwMipMapCount
== tests
[i
].mipmap_count_out
,
7862 "Test %u: Got unexpected mipmap count %u.\n", i
, U2(surface_desc
).dwMipMapCount
);
7864 if (U2(surface_desc
).dwMipMapCount
> 1)
7866 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &surface2
);
7867 ok(SUCCEEDED(hr
), "Test %u: Failed to get attached surface, hr %#x.\n", i
, hr
);
7869 memset(&surface_desc
, 0, sizeof(surface_desc
));
7870 surface_desc
.dwSize
= sizeof(surface_desc
);
7871 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
7872 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
7873 memset(&surface_desc
, 0, sizeof(surface_desc
));
7874 surface_desc
.dwSize
= sizeof(surface_desc
);
7875 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &surface_desc
, 0, NULL
);
7876 ok(SUCCEEDED(hr
), "Test %u: Failed to lock surface, hr %#x.\n", i
, hr
);
7877 IDirectDrawSurface4_Unlock(surface2
, NULL
);
7878 IDirectDrawSurface4_Unlock(surface
, NULL
);
7880 IDirectDrawSurface4_Release(surface2
);
7883 IDirectDrawSurface4_Release(surface
);
7886 refcount
= IDirectDraw4_Release(ddraw
);
7887 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7888 DestroyWindow(window
);
7891 static void test_palette_complex(void)
7893 IDirectDrawSurface4
*surface
, *mipmap
, *tmp
;
7894 DDSURFACEDESC2 surface_desc
;
7895 IDirectDraw4
*ddraw
;
7896 IDirectDrawPalette
*palette
, *palette2
, *palette_mipmap
;
7900 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
7902 PALETTEENTRY palette_entries
[256];
7908 window
= create_window();
7909 ddraw
= create_ddraw();
7910 ok(!!ddraw
, "Failed to create a ddraw object.\n");
7911 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
7912 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
7914 memset(&hal_caps
, 0, sizeof(hal_caps
));
7915 hal_caps
.dwSize
= sizeof(hal_caps
);
7916 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
7917 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
7918 if ((hal_caps
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
)) != (DDSCAPS_TEXTURE
| DDSCAPS_MIPMAP
))
7920 skip("Mipmapped textures not supported, skipping mipmap palette test.\n");
7921 IDirectDraw4_Release(ddraw
);
7922 DestroyWindow(window
);
7926 memset(&surface_desc
, 0, sizeof(surface_desc
));
7927 surface_desc
.dwSize
= sizeof(surface_desc
);
7928 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
7929 surface_desc
.dwWidth
= 128;
7930 surface_desc
.dwHeight
= 128;
7931 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
7932 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
7933 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
7934 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
7935 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
7936 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
7938 memset(palette_entries
, 0, sizeof(palette_entries
));
7939 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7940 palette_entries
, &palette
, NULL
);
7941 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7943 memset(palette_entries
, 0, sizeof(palette_entries
));
7944 palette_entries
[1].peRed
= 0xff;
7945 palette_entries
[1].peGreen
= 0x80;
7946 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
7947 palette_entries
, &palette_mipmap
, NULL
);
7948 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
7950 palette2
= (void *)0xdeadbeef;
7951 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
7952 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x.\n", hr
);
7953 ok(!palette2
, "Got unexpected palette %p.\n", palette2
);
7954 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
7955 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
7956 hr
= IDirectDrawSurface4_GetPalette(surface
, &palette2
);
7957 ok(SUCCEEDED(hr
), "Failed to get palette, hr %#x.\n", hr
);
7958 ok(palette
== palette2
, "Got unexpected palette %p.\n", palette2
);
7959 IDirectDrawPalette_Release(palette2
);
7962 IDirectDrawSurface4_AddRef(mipmap
);
7963 for (i
= 0; i
< 7; ++i
)
7965 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7966 ok(SUCCEEDED(hr
), "Failed to get attached surface, i %u, hr %#x.\n", i
, hr
);
7967 palette2
= (void *)0xdeadbeef;
7968 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
7969 ok(hr
== DDERR_NOPALETTEATTACHED
, "Got unexpected hr %#x, i %u.\n", hr
, i
);
7970 ok(!palette2
, "Got unexpected palette %p, i %u.\n", palette2
, i
);
7972 hr
= IDirectDrawSurface4_SetPalette(tmp
, palette_mipmap
);
7973 ok(SUCCEEDED(hr
), "Failed to set palette, i %u, hr %#x.\n", i
, hr
);
7975 hr
= IDirectDrawSurface4_GetPalette(tmp
, &palette2
);
7976 ok(SUCCEEDED(hr
), "Failed to get palette, i %u, hr %#x.\n", i
, hr
);
7977 ok(palette_mipmap
== palette2
, "Got unexpected palette %p.\n", palette2
);
7978 IDirectDrawPalette_Release(palette2
);
7980 hr
= IDirectDrawSurface4_GetDC(tmp
, &dc
);
7981 ok(SUCCEEDED(hr
), "Failed to get DC, i %u, hr %#x.\n", i
, hr
);
7982 count
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
7983 ok(count
== 1, "Expected count 1, got %u.\n", count
);
7984 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x.\n", rgbquad
.rgbRed
);
7985 ok(rgbquad
.rgbGreen
== 0x80, "Expected rgbGreen = 0x80, got %#x.\n", rgbquad
.rgbGreen
);
7986 ok(rgbquad
.rgbBlue
== 0x0, "Expected rgbBlue = 0x0, got %#x.\n", rgbquad
.rgbBlue
);
7987 hr
= IDirectDrawSurface4_ReleaseDC(tmp
, dc
);
7988 ok(SUCCEEDED(hr
), "Failed to release DC, i %u, hr %#x.\n", i
, hr
);
7990 IDirectDrawSurface4_Release(mipmap
);
7994 hr
= IDirectDrawSurface4_GetAttachedSurface(mipmap
, &caps
, &tmp
);
7995 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
7996 IDirectDrawSurface4_Release(mipmap
);
7997 refcount
= IDirectDrawSurface4_Release(surface
);
7998 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
7999 refcount
= IDirectDrawPalette_Release(palette_mipmap
);
8000 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8001 refcount
= IDirectDrawPalette_Release(palette
);
8002 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8004 refcount
= IDirectDraw4_Release(ddraw
);
8005 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8006 DestroyWindow(window
);
8009 static void test_p8_blit(void)
8011 IDirectDrawSurface4
*src
, *dst
, *dst_p8
;
8012 DDSURFACEDESC2 surface_desc
;
8013 IDirectDraw4
*ddraw
;
8014 IDirectDrawPalette
*palette
, *palette2
;
8018 PALETTEENTRY palette_entries
[256];
8022 static const BYTE src_data
[] = {0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0xff, 0x80};
8023 static const BYTE src_data2
[] = {0x10, 0x5, 0x4, 0x3, 0x2, 0x1, 0xff, 0x80};
8024 static const BYTE expected_p8
[] = {0x10, 0x1, 0x4, 0x3, 0x4, 0x5, 0xff, 0x80};
8025 static const D3DCOLOR expected
[] =
8027 0x00101010, 0x00010101, 0x00020202, 0x00030303,
8028 0x00040404, 0x00050505, 0x00ffffff, 0x00808080,
8032 window
= create_window();
8033 ddraw
= create_ddraw();
8034 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8035 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8036 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8037 is_warp
= ddraw_is_warp(ddraw
);
8039 memset(palette_entries
, 0, sizeof(palette_entries
));
8040 palette_entries
[1].peGreen
= 0xff;
8041 palette_entries
[2].peBlue
= 0xff;
8042 palette_entries
[3].peFlags
= 0xff;
8043 palette_entries
[4].peRed
= 0xff;
8044 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8045 palette_entries
, &palette
, NULL
);
8046 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8047 palette_entries
[1].peBlue
= 0xff;
8048 palette_entries
[2].peGreen
= 0xff;
8049 palette_entries
[3].peRed
= 0xff;
8050 palette_entries
[4].peFlags
= 0x0;
8051 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8052 palette_entries
, &palette2
, NULL
);
8053 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8055 memset(&surface_desc
, 0, sizeof(surface_desc
));
8056 surface_desc
.dwSize
= sizeof(surface_desc
);
8057 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8058 surface_desc
.dwWidth
= 8;
8059 surface_desc
.dwHeight
= 1;
8060 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8061 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8062 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8063 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8064 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
8065 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8066 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_p8
, NULL
);
8067 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8068 hr
= IDirectDrawSurface4_SetPalette(dst_p8
, palette2
);
8069 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8071 memset(&surface_desc
, 0, sizeof(surface_desc
));
8072 surface_desc
.dwSize
= sizeof(surface_desc
);
8073 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8074 surface_desc
.dwWidth
= 8;
8075 surface_desc
.dwHeight
= 1;
8076 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8077 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8078 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8079 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8080 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8081 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8082 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8083 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
8084 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
8085 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8087 memset(&surface_desc
, 0, sizeof(surface_desc
));
8088 surface_desc
.dwSize
= sizeof(surface_desc
);
8089 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8090 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
8091 memcpy(surface_desc
.lpSurface
, src_data
, sizeof(src_data
));
8092 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
8093 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
8095 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
8096 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8097 memcpy(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
));
8098 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8099 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8101 hr
= IDirectDrawSurface4_SetPalette(src
, palette
);
8102 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8103 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
8104 /* The r500 Windows 7 driver returns E_NOTIMPL. r200 on Windows XP works.
8105 * The Geforce 7 driver on Windows Vista returns E_FAIL. Newer Nvidia GPUs work. */
8106 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) || broken(hr
== E_FAIL
),
8107 "Failed to blit, hr %#x.\n", hr
);
8111 for (x
= 0; x
< ARRAY_SIZE(expected
); x
++)
8113 color
= get_surface_color(dst
, x
, 0);
8114 todo_wine
ok(compare_color(color
, expected
[x
], 0),
8115 "Pixel %u: Got color %#x, expected %#x.\n",
8116 x
, color
, expected
[x
]);
8120 memset(&fx
, 0, sizeof(fx
));
8121 fx
.dwSize
= sizeof(fx
);
8122 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x2;
8123 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x2;
8124 hr
= IDirectDrawSurface4_Blt(dst_p8
, NULL
, src
, NULL
, DDBLT_WAIT
| DDBLT_KEYSRCOVERRIDE
, &fx
);
8125 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
8127 hr
= IDirectDrawSurface4_Lock(dst_p8
, NULL
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
8128 ok(SUCCEEDED(hr
), "Failed to lock destination surface, hr %#x.\n", hr
);
8129 /* A color keyed P8 blit doesn't do anything on WARP - it just leaves the data in the destination
8130 * surface untouched. P8 blits without color keys work. Error checking (DDBLT_KEYSRC without a key
8131 * for example) also works as expected.
8133 * Using DDBLT_KEYSRC instead of DDBLT_KEYSRCOVERRIDE doesn't change this. Doing this blit with
8134 * the display mode set to P8 doesn't help either. */
8135 ok(!memcmp(surface_desc
.lpSurface
, expected_p8
, sizeof(expected_p8
))
8136 || broken(is_warp
&& !memcmp(surface_desc
.lpSurface
, src_data2
, sizeof(src_data2
))),
8137 "Got unexpected P8 color key blit result.\n");
8138 hr
= IDirectDrawSurface4_Unlock(dst_p8
, NULL
);
8139 ok(SUCCEEDED(hr
), "Failed to unlock destination surface, hr %#x.\n", hr
);
8141 IDirectDrawSurface4_Release(src
);
8142 IDirectDrawSurface4_Release(dst
);
8143 IDirectDrawSurface4_Release(dst_p8
);
8144 IDirectDrawPalette_Release(palette
);
8145 IDirectDrawPalette_Release(palette2
);
8147 refcount
= IDirectDraw4_Release(ddraw
);
8148 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8149 DestroyWindow(window
);
8152 static void test_material(void)
8154 D3DMATERIALHANDLE mat_handle
, tmp
;
8155 IDirect3DMaterial3
*material
;
8156 IDirect3DViewport3
*viewport
;
8157 IDirect3DDevice3
*device
;
8158 IDirectDrawSurface4
*rt
;
8168 struct vec3 position
;
8174 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8175 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8176 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8177 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffffffff},
8181 {{-1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8182 {{-1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8183 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8184 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
, 0.0f
}, 0xffff0000},
8190 D3DCOLOR expected_color
;
8194 {quad1
, TRUE
, 0x0000ff00},
8195 {quad2
, TRUE
, 0x0000ff00},
8196 {quad1
, FALSE
, 0x00ffffff},
8197 {quad2
, FALSE
, 0x00ff0000},
8199 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
8201 window
= create_window();
8202 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
8204 skip("Failed to create a 3D device, skipping test.\n");
8205 DestroyWindow(window
);
8209 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
8210 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
8212 viewport
= create_viewport(device
, 0, 0, 640, 480);
8213 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
8214 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
8216 material
= create_emissive_material(device
, 0.0f
, 1.0f
, 0.0f
, 0.0f
);
8217 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8218 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8220 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8221 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8222 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8223 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, mat_handle
);
8224 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8225 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8226 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8227 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8228 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, 0);
8229 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8230 hr
= IDirect3DDevice3_GetLightState(device
, D3DLIGHTSTATE_MATERIAL
, &tmp
);
8231 ok(SUCCEEDED(hr
), "Failed to get light state, hr %#x.\n", hr
);
8232 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8234 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
8236 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
8237 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
8238 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8240 hr
= IDirect3DDevice3_SetLightState(device
, D3DLIGHTSTATE_MATERIAL
, test_data
[i
].material
? mat_handle
: 0);
8241 ok(SUCCEEDED(hr
), "Failed to set material state, hr %#x.\n", hr
);
8243 hr
= IDirect3DDevice3_BeginScene(device
);
8244 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8245 hr
= IDirect3DDevice2_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
8246 D3DFVF_XYZ
| D3DFVF_NORMAL
| D3DFVF_DIFFUSE
, test_data
[i
].data
, 4, 0);
8247 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8248 hr
= IDirect3DDevice3_EndScene(device
);
8249 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8250 color
= get_surface_color(rt
, 320, 240);
8251 ok(compare_color(color
, test_data
[i
].expected_color
, 1),
8252 "Got unexpected color 0x%08x, test %u.\n", color
, i
);
8255 destroy_material(material
);
8256 material
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
8257 hr
= IDirect3DMaterial3_GetHandle(material
, device
, &mat_handle
);
8258 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
8260 hr
= IDirect3DViewport3_SetBackground(viewport
, mat_handle
);
8261 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
8262 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8263 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8264 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8265 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8266 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8267 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8268 color
= get_surface_color(rt
, 320, 240);
8269 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8271 hr
= IDirect3DViewport3_SetBackground(viewport
, 0);
8272 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
8273 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8274 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8275 ok(tmp
== mat_handle
, "Got unexpected material handle %#x, expected %#x.\n", tmp
, mat_handle
);
8276 ok(valid
, "Got unexpected valid %#x.\n", valid
);
8277 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8278 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8279 color
= get_surface_color(rt
, 320, 240);
8280 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
8282 destroy_viewport(device
, viewport
);
8283 viewport
= create_viewport(device
, 0, 0, 640, 480);
8285 hr
= IDirect3DViewport3_GetBackground(viewport
, &tmp
, &valid
);
8286 ok(SUCCEEDED(hr
), "Failed to get viewport background, hr %#x.\n", hr
);
8287 ok(!tmp
, "Got unexpected material handle %#x.\n", tmp
);
8288 ok(!valid
, "Got unexpected valid %#x.\n", valid
);
8289 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
8290 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
8291 color
= get_surface_color(rt
, 320, 240);
8292 ok(compare_color(color
, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color
);
8294 destroy_viewport(device
, viewport
);
8295 destroy_material(material
);
8296 IDirectDrawSurface4_Release(rt
);
8297 refcount
= IDirect3DDevice3_Release(device
);
8298 ok(!refcount
, "Device has %u references left.\n", refcount
);
8299 DestroyWindow(window
);
8302 static void test_palette_gdi(void)
8304 IDirectDrawSurface4
*surface
, *primary
;
8305 DDSURFACEDESC2 surface_desc
;
8306 IDirectDraw4
*ddraw
;
8307 IDirectDrawPalette
*palette
, *palette2
;
8311 PALETTEENTRY palette_entries
[256];
8317 /* On the Windows 8 testbot palette index 0 of the onscreen palette is forced to
8318 * r = 0, g = 0, b = 0. Do not attempt to set it to something else as this is
8319 * not the point of this test. */
8320 static const RGBQUAD expected1
[] =
8322 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8323 {0x03, 0x00, 0x00, 0x00}, {0x15, 0x14, 0x13, 0x00},
8325 static const RGBQUAD expected2
[] =
8327 {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x01, 0x00}, {0x00, 0x02, 0x00, 0x00},
8328 {0x03, 0x00, 0x00, 0x00}, {0x25, 0x24, 0x23, 0x00},
8330 static const RGBQUAD expected3
[] =
8332 {0x00, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x40, 0x00},
8333 {0x00, 0x40, 0x00, 0x00}, {0x56, 0x34, 0x12, 0x00},
8335 HPALETTE ddraw_palette_handle
;
8336 /* Similar to index 0, index 255 is r = 0xff, g = 0xff, b = 0xff on the Win8 VMs. */
8337 RGBQUAD rgbquad
[255];
8338 static const RGBQUAD rgb_zero
= {0, 0, 0, 0};
8340 window
= create_window();
8341 ddraw
= create_ddraw();
8342 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8343 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
8344 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8346 memset(&surface_desc
, 0, sizeof(surface_desc
));
8347 surface_desc
.dwSize
= sizeof(surface_desc
);
8348 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8349 surface_desc
.dwWidth
= 16;
8350 surface_desc
.dwHeight
= 16;
8351 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8352 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8353 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
| DDPF_RGB
;
8354 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 8;
8355 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8356 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8358 /* Avoid colors from the Windows default palette. */
8359 memset(palette_entries
, 0, sizeof(palette_entries
));
8360 palette_entries
[1].peRed
= 0x01;
8361 palette_entries
[2].peGreen
= 0x02;
8362 palette_entries
[3].peBlue
= 0x03;
8363 palette_entries
[4].peRed
= 0x13;
8364 palette_entries
[4].peGreen
= 0x14;
8365 palette_entries
[4].peBlue
= 0x15;
8366 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8367 palette_entries
, &palette
, NULL
);
8368 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8370 /* If there is no palette assigned and the display mode is not 8 bpp, some
8371 * drivers refuse to create a DC while others allow it. If a DC is created,
8372 * the DIB color table is uninitialized and contains random colors. No error
8373 * is generated when trying to read pixels and random garbage is returned.
8375 * The most likely explanation is that if the driver creates a DC, it (or
8376 * the higher-level runtime) uses GetSystemPaletteEntries to find the
8377 * palette, but GetSystemPaletteEntries fails when bpp > 8 and the palette
8378 * contains uninitialized garbage. See comments below for the P8 case. */
8380 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8381 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8382 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8383 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8384 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8385 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8386 "Got unexpected palette %p, expected %p.\n",
8387 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8389 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8390 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8391 for (i
= 0; i
< ARRAY_SIZE(expected1
); i
++)
8393 ok(!memcmp(&rgbquad
[i
], &expected1
[i
], sizeof(rgbquad
[i
])),
8394 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8395 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8396 expected1
[i
].rgbRed
, expected1
[i
].rgbGreen
, expected1
[i
].rgbBlue
);
8398 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8400 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8401 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8402 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8405 /* Update the palette while the DC is in use. This does not modify the DC. */
8406 palette_entries
[4].peRed
= 0x23;
8407 palette_entries
[4].peGreen
= 0x24;
8408 palette_entries
[4].peBlue
= 0x25;
8409 hr
= IDirectDrawPalette_SetEntries(palette
, 0, 4, 1, &palette_entries
[4]);
8410 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#x.\n", hr
);
8412 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8413 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8414 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8415 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8416 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8417 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8419 /* Neither does re-setting the palette. */
8420 hr
= IDirectDrawSurface4_SetPalette(surface
, NULL
);
8421 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8422 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8423 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8425 i
= GetDIBColorTable(dc
, 4, 1, &rgbquad
[4]);
8426 ok(i
== 1, "Expected count 1, got %u.\n", i
);
8427 ok(!memcmp(&rgbquad
[4], &expected1
[4], sizeof(rgbquad
[4])),
8428 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8429 i
, rgbquad
[4].rgbRed
, rgbquad
[4].rgbGreen
, rgbquad
[4].rgbBlue
,
8430 expected1
[4].rgbRed
, expected1
[4].rgbGreen
, expected1
[4].rgbBlue
);
8432 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8433 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8435 /* Refresh the DC. This updates the palette. */
8436 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8437 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8438 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8439 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8440 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8442 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8443 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8444 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8445 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8447 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8449 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8450 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8451 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8453 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8454 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8456 refcount
= IDirectDrawSurface4_Release(surface
);
8457 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8459 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_FULLSCREEN
| DDSCL_EXCLUSIVE
);
8460 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8461 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8463 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8464 IDirectDrawPalette_Release(palette
);
8465 IDirectDraw4_Release(ddraw
);
8466 DestroyWindow(window
);
8469 ok(SUCCEEDED(hr
), "Failed to set display mode, hr %#x.\n", hr
);
8471 memset(&surface_desc
, 0, sizeof(surface_desc
));
8472 surface_desc
.dwSize
= sizeof(surface_desc
);
8473 surface_desc
.dwFlags
= DDSD_CAPS
;
8474 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8475 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
8476 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8478 memset(&fx
, 0, sizeof(fx
));
8479 fx
.dwSize
= sizeof(fx
);
8480 U5(fx
).dwFillColor
= 3;
8481 SetRect(&r
, 0, 0, 319, 479);
8482 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8483 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8484 SetRect(&r
, 320, 0, 639, 479);
8485 U5(fx
).dwFillColor
= 4;
8486 hr
= IDirectDrawSurface4_Blt(primary
, &r
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
8487 ok(SUCCEEDED(hr
), "Failed to clear surface, hr %#x.\n", hr
);
8489 hr
= IDirectDrawSurface4_SetPalette(primary
, palette
);
8490 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8491 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
8492 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8494 color
= GetPixel(dc
, 160, 240);
8495 ok(color
== 0x00030000, "Clear index 3: Got unexpected color 0x%08x.\n", color
);
8496 color
= GetPixel(dc
, 480, 240);
8497 ok(color
== 0x00252423, "Clear index 4: Got unexpected color 0x%08x.\n", color
);
8499 ddraw_palette_handle
= SelectPalette(dc
, GetStockObject(DEFAULT_PALETTE
), FALSE
);
8500 ok(ddraw_palette_handle
== GetStockObject(DEFAULT_PALETTE
),
8501 "Got unexpected palette %p, expected %p.\n",
8502 ddraw_palette_handle
, GetStockObject(DEFAULT_PALETTE
));
8503 SelectPalette(dc
, ddraw_palette_handle
, FALSE
);
8505 /* The primary uses the system palette. In exclusive mode, the system palette matches
8506 * the ddraw palette attached to the primary, so the result is what you would expect
8507 * from a regular surface. Tests for the interaction between the ddraw palette and
8508 * the system palette are not included pending an application that depends on this.
8509 * The relation between those causes problems on Windows Vista and newer for games
8510 * like Age of Empires or StarCraft. Don't emulate it without a real need. */
8511 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8512 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8513 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8515 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8516 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8517 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8518 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8520 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8522 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8523 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8524 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8526 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
8527 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8529 memset(&surface_desc
, 0, sizeof(surface_desc
));
8530 surface_desc
.dwSize
= sizeof(surface_desc
);
8531 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
8532 surface_desc
.dwWidth
= 16;
8533 surface_desc
.dwHeight
= 16;
8534 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8535 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8536 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8538 /* Here the offscreen surface appears to use the primary's palette,
8539 * but in all likelihood it is actually the system palette. */
8540 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8541 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8542 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8543 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8544 for (i
= 0; i
< ARRAY_SIZE(expected2
); i
++)
8546 ok(!memcmp(&rgbquad
[i
], &expected2
[i
], sizeof(rgbquad
[i
])),
8547 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8548 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8549 expected2
[i
].rgbRed
, expected2
[i
].rgbGreen
, expected2
[i
].rgbBlue
);
8551 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8553 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8554 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8555 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8557 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8558 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8560 /* On real hardware a change to the primary surface's palette applies immediately,
8561 * even on device contexts from offscreen surfaces that do not have their own
8562 * palette. On the testbot VMs this is not the case. Don't test this until we
8563 * know of an application that depends on this. */
8565 memset(palette_entries
, 0, sizeof(palette_entries
));
8566 palette_entries
[1].peBlue
= 0x40;
8567 palette_entries
[2].peRed
= 0x40;
8568 palette_entries
[3].peGreen
= 0x40;
8569 palette_entries
[4].peRed
= 0x12;
8570 palette_entries
[4].peGreen
= 0x34;
8571 palette_entries
[4].peBlue
= 0x56;
8572 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_8BIT
| DDPCAPS_ALLOW256
,
8573 palette_entries
, &palette2
, NULL
);
8574 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8575 hr
= IDirectDrawSurface4_SetPalette(surface
, palette2
);
8576 ok(SUCCEEDED(hr
), "Failed to set palette, hr %#x.\n", hr
);
8578 /* A palette assigned to the offscreen surface overrides the primary / system
8580 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8581 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
8582 i
= GetDIBColorTable(dc
, 0, ARRAY_SIZE(rgbquad
), rgbquad
);
8583 ok(i
== ARRAY_SIZE(rgbquad
), "Expected count 255, got %u.\n", i
);
8584 for (i
= 0; i
< ARRAY_SIZE(expected3
); i
++)
8586 ok(!memcmp(&rgbquad
[i
], &expected3
[i
], sizeof(rgbquad
[i
])),
8587 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=%#x g=%#x b=%#x.\n",
8588 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
,
8589 expected3
[i
].rgbRed
, expected3
[i
].rgbGreen
, expected3
[i
].rgbBlue
);
8591 for (; i
< ARRAY_SIZE(rgbquad
); i
++)
8593 ok(!memcmp(&rgbquad
[i
], &rgb_zero
, sizeof(rgbquad
[i
])),
8594 "Got color table entry %u r=%#x g=%#x b=%#x, expected r=0 g=0 b=0.\n",
8595 i
, rgbquad
[i
].rgbRed
, rgbquad
[i
].rgbGreen
, rgbquad
[i
].rgbBlue
);
8597 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8598 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8600 refcount
= IDirectDrawSurface4_Release(surface
);
8601 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8603 /* The Windows 8 testbot keeps extra references to the primary and
8604 * backbuffer while in 8 bpp mode. */
8605 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
8606 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8608 refcount
= IDirectDrawSurface4_Release(primary
);
8609 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8610 refcount
= IDirectDrawPalette_Release(palette2
);
8611 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8612 refcount
= IDirectDrawPalette_Release(palette
);
8613 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8614 refcount
= IDirectDraw4_Release(ddraw
);
8615 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8616 DestroyWindow(window
);
8619 static void test_palette_alpha(void)
8621 IDirectDrawSurface4
*surface
;
8622 DDSURFACEDESC2 surface_desc
;
8623 IDirectDraw4
*ddraw
;
8624 IDirectDrawPalette
*palette
;
8628 PALETTEENTRY palette_entries
[256];
8633 BOOL attach_allowed
;
8638 {DDSCAPS_OFFSCREENPLAIN
, DDSD_WIDTH
| DDSD_HEIGHT
, FALSE
, "offscreenplain"},
8639 {DDSCAPS_TEXTURE
, DDSD_WIDTH
| DDSD_HEIGHT
, TRUE
, "texture"},
8640 {DDSCAPS_PRIMARYSURFACE
, 0, FALSE
, "primary"}
8643 window
= create_window();
8644 ddraw
= create_ddraw();
8645 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8646 if (FAILED(IDirectDraw4_SetDisplayMode(ddraw
, 640, 480, 8, 0, 0)))
8648 win_skip("Failed to set 8 bpp display mode, skipping test.\n");
8649 IDirectDraw4_Release(ddraw
);
8650 DestroyWindow(window
);
8653 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8654 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8656 memset(palette_entries
, 0, sizeof(palette_entries
));
8657 palette_entries
[1].peFlags
= 0x42;
8658 palette_entries
[2].peFlags
= 0xff;
8659 palette_entries
[3].peFlags
= 0x80;
8660 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
, palette_entries
, &palette
, NULL
);
8661 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8663 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8664 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8665 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8666 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8667 palette_entries
[0].peFlags
);
8668 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8669 palette_entries
[1].peFlags
);
8670 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8671 palette_entries
[2].peFlags
);
8672 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8673 palette_entries
[3].peFlags
);
8675 IDirectDrawPalette_Release(palette
);
8677 memset(palette_entries
, 0, sizeof(palette_entries
));
8678 palette_entries
[1].peFlags
= 0x42;
8679 palette_entries
[1].peRed
= 0xff;
8680 palette_entries
[2].peFlags
= 0xff;
8681 palette_entries
[3].peFlags
= 0x80;
8682 hr
= IDirectDraw4_CreatePalette(ddraw
, DDPCAPS_ALLOW256
| DDPCAPS_8BIT
| DDPCAPS_ALPHA
,
8683 palette_entries
, &palette
, NULL
);
8684 ok(SUCCEEDED(hr
), "Failed to create palette, hr %#x.\n", hr
);
8686 memset(palette_entries
, 0x66, sizeof(palette_entries
));
8687 hr
= IDirectDrawPalette_GetEntries(palette
, 0, 1, 4, palette_entries
);
8688 ok(SUCCEEDED(hr
), "Failed to get palette entries, hr %#x.\n", hr
);
8689 ok(palette_entries
[0].peFlags
== 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8690 palette_entries
[0].peFlags
);
8691 ok(palette_entries
[1].peFlags
== 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n",
8692 palette_entries
[1].peFlags
);
8693 ok(palette_entries
[2].peFlags
== 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n",
8694 palette_entries
[2].peFlags
);
8695 ok(palette_entries
[3].peFlags
== 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n",
8696 palette_entries
[3].peFlags
);
8698 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
8700 memset(&surface_desc
, 0, sizeof(surface_desc
));
8701 surface_desc
.dwSize
= sizeof(surface_desc
);
8702 surface_desc
.dwFlags
= DDSD_CAPS
| test_data
[i
].flags
;
8703 surface_desc
.dwWidth
= 128;
8704 surface_desc
.dwHeight
= 128;
8705 surface_desc
.ddsCaps
.dwCaps
= test_data
[i
].caps
;
8706 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8707 ok(SUCCEEDED(hr
), "Failed to create %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8709 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8710 if (test_data
[i
].attach_allowed
)
8711 ok(SUCCEEDED(hr
), "Failed to attach palette to %s surface, hr %#x.\n", test_data
[i
].name
, hr
);
8713 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8721 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
8722 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x, %s surface.\n", hr
, test_data
[i
].name
);
8723 retval
= GetDIBColorTable(dc
, 1, 1, &rgbquad
);
8724 ok(retval
== 1, "GetDIBColorTable returned unexpected result %u.\n", retval
);
8725 ok(rgbquad
.rgbRed
== 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n",
8726 rgbquad
.rgbRed
, test_data
[i
].name
);
8727 ok(rgbquad
.rgbGreen
== 0, "Expected rgbGreen = 0, got %#x, %s surface.\n",
8728 rgbquad
.rgbGreen
, test_data
[i
].name
);
8729 ok(rgbquad
.rgbBlue
== 0, "Expected rgbBlue = 0, got %#x, %s surface.\n",
8730 rgbquad
.rgbBlue
, test_data
[i
].name
);
8731 ok(rgbquad
.rgbReserved
== 0, "Expected rgbReserved = 0, got %u, %s surface.\n",
8732 rgbquad
.rgbReserved
, test_data
[i
].name
);
8733 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
8734 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
8736 IDirectDrawSurface4_Release(surface
);
8739 /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */
8740 memset(&surface_desc
, 0, sizeof(surface_desc
));
8741 surface_desc
.dwSize
= sizeof(surface_desc
);
8742 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
8743 surface_desc
.dwWidth
= 128;
8744 surface_desc
.dwHeight
= 128;
8745 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
8746 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
8747 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
8748 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
8749 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
8750 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
8751 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
8752 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8753 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8754 hr
= IDirectDrawSurface4_SetPalette(surface
, palette
);
8755 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got unexpected hr %#x.\n", hr
);
8756 IDirectDrawSurface4_Release(surface
);
8758 /* The Windows 8 testbot keeps extra references to the primary
8759 * while in 8 bpp mode. */
8760 hr
= IDirectDraw4_RestoreDisplayMode(ddraw
);
8761 ok(SUCCEEDED(hr
), "Failed to restore display mode, hr %#x.\n", hr
);
8763 refcount
= IDirectDrawPalette_Release(palette
);
8764 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8765 refcount
= IDirectDraw4_Release(ddraw
);
8766 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
8767 DestroyWindow(window
);
8770 static void test_vb_writeonly(void)
8772 IDirect3DDevice3
*device
;
8774 IDirect3DVertexBuffer
*buffer
;
8777 D3DVERTEXBUFFERDESC desc
;
8779 static const struct vec4 quad
[] =
8781 { 0.0f
, 480.0f
, 0.0f
, 1.0f
},
8782 { 0.0f
, 0.0f
, 0.0f
, 1.0f
},
8783 {640.0f
, 480.0f
, 0.0f
, 1.0f
},
8784 {640.0f
, 0.0f
, 0.0f
, 1.0f
},
8787 window
= create_window();
8788 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
8790 skip("Failed to create a 3D device, skipping test.\n");
8791 DestroyWindow(window
);
8795 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
8796 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
8798 memset(&desc
, 0, sizeof(desc
));
8799 desc
.dwSize
= sizeof(desc
);
8800 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
8801 desc
.dwFVF
= D3DFVF_XYZRHW
;
8802 desc
.dwNumVertices
= ARRAY_SIZE(quad
);
8803 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &buffer
, 0, NULL
);
8804 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
8806 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, &ptr
, NULL
);
8807 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8808 memcpy(ptr
, quad
, sizeof(quad
));
8809 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8810 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8812 hr
= IDirect3DDevice3_BeginScene(device
);
8813 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
8814 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 4, 0);
8815 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
8816 hr
= IDirect3DDevice3_EndScene(device
);
8817 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
8819 hr
= IDirect3DVertexBuffer_Lock(buffer
, 0, &ptr
, NULL
);
8820 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8821 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8822 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8823 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8825 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_READONLY
, &ptr
, NULL
);
8826 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
8827 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8828 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
8829 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
8831 IDirect3DVertexBuffer_Release(buffer
);
8832 IDirect3D3_Release(d3d
);
8833 IDirect3DDevice3_Release(device
);
8834 DestroyWindow(window
);
8837 static void test_lost_device(void)
8839 IDirectDrawSurface4
*surface
;
8840 DDSURFACEDESC2 surface_desc
;
8841 HWND window1
, window2
;
8842 IDirectDraw4
*ddraw
;
8847 window1
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8848 0, 0, 640, 480, 0, 0, 0, 0);
8849 window2
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
8850 0, 0, 640, 480, 0, 0, 0, 0);
8851 ddraw
= create_ddraw();
8852 ok(!!ddraw
, "Failed to create a ddraw object.\n");
8853 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8854 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
8856 memset(&surface_desc
, 0, sizeof(surface_desc
));
8857 surface_desc
.dwSize
= sizeof(surface_desc
);
8858 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8859 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8860 U5(surface_desc
).dwBackBufferCount
= 1;
8861 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8862 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8864 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8865 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8866 hr
= IDirectDrawSurface4_IsLost(surface
);
8867 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8868 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8869 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8871 ret
= SetForegroundWindow(GetDesktopWindow());
8872 ok(ret
, "Failed to set foreground window.\n");
8873 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8874 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8875 hr
= IDirectDrawSurface4_IsLost(surface
);
8876 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8877 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8878 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8880 ret
= SetForegroundWindow(window1
);
8881 ok(ret
, "Failed to set foreground window.\n");
8882 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8883 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8884 hr
= IDirectDrawSurface4_IsLost(surface
);
8885 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8886 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8887 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8889 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
8890 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8891 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8892 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8893 hr
= IDirectDrawSurface4_IsLost(surface
);
8894 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8895 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8896 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8898 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8899 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8900 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8901 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8902 hr
= IDirectDrawSurface4_IsLost(surface
);
8903 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8904 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8905 todo_wine
ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8907 /* Trying to restore the primary will crash, probably because flippable
8908 * surfaces can't exist in DDSCL_NORMAL. */
8909 IDirectDrawSurface4_Release(surface
);
8910 memset(&surface_desc
, 0, sizeof(surface_desc
));
8911 surface_desc
.dwSize
= sizeof(surface_desc
);
8912 surface_desc
.dwFlags
= DDSD_CAPS
;
8913 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8914 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8915 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8917 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8918 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8919 hr
= IDirectDrawSurface4_IsLost(surface
);
8920 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8922 ret
= SetForegroundWindow(GetDesktopWindow());
8923 ok(ret
, "Failed to set foreground window.\n");
8924 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8925 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8926 hr
= IDirectDrawSurface4_IsLost(surface
);
8927 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8929 ret
= SetForegroundWindow(window1
);
8930 ok(ret
, "Failed to set foreground window.\n");
8931 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8932 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8933 hr
= IDirectDrawSurface4_IsLost(surface
);
8934 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8936 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8937 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8938 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8939 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8940 hr
= IDirectDrawSurface4_IsLost(surface
);
8941 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
8943 hr
= IDirectDraw4_RestoreAllSurfaces(ddraw
);
8944 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8945 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8946 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8947 hr
= IDirectDrawSurface4_IsLost(surface
);
8948 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8950 IDirectDrawSurface4_Release(surface
);
8951 memset(&surface_desc
, 0, sizeof(surface_desc
));
8952 surface_desc
.dwSize
= sizeof(surface_desc
);
8953 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
8954 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
;
8955 U5(surface_desc
).dwBackBufferCount
= 1;
8956 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
8957 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
8959 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
8960 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8961 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8962 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8963 hr
= IDirectDrawSurface4_IsLost(surface
);
8964 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8965 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8966 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8968 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8969 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8970 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8971 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8972 hr
= IDirectDrawSurface4_IsLost(surface
);
8973 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8974 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8975 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8977 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window1
, DDSCL_NORMAL
);
8978 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8979 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8980 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8981 hr
= IDirectDrawSurface4_IsLost(surface
);
8982 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8983 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8984 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8986 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
);
8987 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8988 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8989 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8990 hr
= IDirectDrawSurface4_IsLost(surface
);
8991 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8992 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
8993 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
8995 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
8996 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8997 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
8998 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
8999 hr
= IDirectDrawSurface4_IsLost(surface
);
9000 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9001 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9002 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
9004 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window2
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
9005 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9006 hr
= IDirectDraw4_TestCooperativeLevel(ddraw
);
9007 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
9008 hr
= IDirectDrawSurface4_IsLost(surface
);
9009 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9010 hr
= IDirectDrawSurface4_Flip(surface
, NULL
, DDFLIP_WAIT
);
9011 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
9013 IDirectDrawSurface4_Release(surface
);
9014 refcount
= IDirectDraw4_Release(ddraw
);
9015 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9016 DestroyWindow(window2
);
9017 DestroyWindow(window1
);
9020 static void test_surface_desc_lock(void)
9022 IDirectDrawSurface4
*surface
;
9023 DDSURFACEDESC2 surface_desc
;
9024 IDirectDraw4
*ddraw
;
9029 window
= create_window();
9030 ddraw
= create_ddraw();
9031 ok(!!ddraw
, "Failed to create a ddraw object.\n");
9032 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
9033 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
9035 memset(&surface_desc
, 0, sizeof(surface_desc
));
9036 surface_desc
.dwSize
= sizeof(surface_desc
);
9037 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
9038 surface_desc
.dwWidth
= 16;
9039 surface_desc
.dwHeight
= 16;
9040 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
9041 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9042 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9044 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9045 surface_desc
.dwSize
= sizeof(surface_desc
);
9046 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9047 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9048 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9050 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9051 surface_desc
.dwSize
= sizeof(surface_desc
);
9052 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9053 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
9054 ok(surface_desc
.lpSurface
!= NULL
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9055 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9056 surface_desc
.dwSize
= sizeof(surface_desc
);
9057 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9058 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9059 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9060 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9061 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
9063 memset(&surface_desc
, 0xaa, sizeof(surface_desc
));
9064 surface_desc
.dwSize
= sizeof(surface_desc
);
9065 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
9066 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9067 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
9069 IDirectDrawSurface4_Release(surface
);
9070 refcount
= IDirectDraw4_Release(ddraw
);
9071 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
9072 DestroyWindow(window
);
9075 static void test_texturemapblend(void)
9077 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
9078 static RECT rect
= {0, 0, 64, 128};
9079 IDirectDrawSurface4
*surface
, *rt
;
9080 IDirect3DViewport3
*viewport
;
9081 DDSURFACEDESC2 surface_desc
;
9082 IDirect3DTexture2
*texture
;
9083 IDirect3DDevice3
*device
;
9084 IDirectDraw4
*ddraw
;
9095 struct vec4 position
;
9097 struct vec2 texcoord
;
9101 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 0.0f
}},
9102 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {0.0f
, 1.0f
}},
9103 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 0.0f
}},
9104 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0xffffffff, {1.0f
, 1.0f
}},
9105 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 0.0f
}},
9106 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {0.0f
, 1.0f
}},
9107 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 0.0f
}},
9108 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x80ffffff, {1.0f
, 1.0f
}},
9112 {{ 0.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 0.0f
}},
9113 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {0.0f
, 1.0f
}},
9114 {{640.0f
, 0.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 0.0f
}},
9115 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x00ff0080, {1.0f
, 1.0f
}},
9116 {{ 0.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 0.0f
}},
9117 {{ 0.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {0.0f
, 1.0f
}},
9118 {{640.0f
, 240.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 0.0f
}},
9119 {{640.0f
, 480.0f
, 0.0f
, 1.0f
}, 0x008000ff, {1.0f
, 1.0f
}},
9122 window
= create_window();
9123 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9125 skip("Failed to create a 3D device, skipping test.\n");
9126 DestroyWindow(window
);
9130 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9131 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9132 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9133 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9134 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9135 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9137 viewport
= create_viewport(device
, 0, 0, 640, 480);
9138 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9139 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
9141 /* Test alpha with DDPF_ALPHAPIXELS texture - should be taken from texture
9144 * The vertex alpha is completely ignored in this case, so case 1 and 2
9145 * combined are not a D3DTOP_MODULATE with texture alpha = 0xff in case 2
9146 * (no alpha in texture). */
9147 memset(&surface_desc
, 0, sizeof(surface_desc
));
9148 surface_desc
.dwSize
= sizeof(surface_desc
);
9149 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9150 surface_desc
.dwHeight
= 128;
9151 surface_desc
.dwWidth
= 128;
9152 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9153 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9154 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9155 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9156 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9157 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9158 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9159 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9160 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9161 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9163 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9164 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9165 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9166 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9168 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9169 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9171 memset(&fx
, 0, sizeof(fx
));
9172 fx
.dwSize
= sizeof(fx
);
9173 U5(fx
).dwFillColor
= 0xff0000ff;
9174 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9175 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9176 U5(fx
).dwFillColor
= 0x800000ff;
9177 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9178 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9180 /* Note that the ddraw1 version of this test runs tests 1-3 with
9181 * D3DRENDERSTATE_COLORKEYENABLE enabled, whereas this version only runs
9182 * test 4 with color keying on. Because no color key is set on the texture
9183 * this should not result in different behavior. */
9184 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
9185 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9186 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9187 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9188 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
9189 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9190 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
9191 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9192 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9193 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9194 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREMAPBLEND
, D3DTBLEND_MODULATE
);
9195 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9197 hr
= IDirect3DDevice3_BeginScene(device
);
9198 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9199 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9200 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9201 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9202 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9203 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9204 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9205 hr
= IDirect3DDevice3_EndScene(device
);
9206 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9208 color
= get_surface_color(rt
, 5, 5);
9209 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9210 color
= get_surface_color(rt
, 400, 5);
9211 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9212 color
= get_surface_color(rt
, 5, 245);
9213 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9214 color
= get_surface_color(rt
, 400, 245);
9215 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9217 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9218 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9219 IDirect3DTexture2_Release(texture
);
9220 refcount
= IDirectDrawSurface4_Release(surface
);
9221 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9223 /* Test alpha with texture that has no alpha channel - alpha should be
9224 * taken from diffuse vertex color. */
9225 memset(&surface_desc
, 0, sizeof(surface_desc
));
9226 surface_desc
.dwSize
= sizeof(surface_desc
);
9227 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9228 surface_desc
.dwHeight
= 128;
9229 surface_desc
.dwWidth
= 128;
9230 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9231 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9232 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9233 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9234 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9235 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9236 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9238 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9239 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9241 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9242 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9243 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9244 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9246 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9247 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9249 U5(fx
).dwFillColor
= 0xff0000ff;
9250 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9251 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9252 U5(fx
).dwFillColor
= 0x800000ff;
9253 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9254 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9256 hr
= IDirect3DDevice3_BeginScene(device
);
9257 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9258 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9259 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9260 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9261 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9262 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9263 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9264 hr
= IDirect3DDevice3_EndScene(device
);
9265 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9267 color
= get_surface_color(rt
, 5, 5);
9268 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9269 color
= get_surface_color(rt
, 400, 5);
9270 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9271 color
= get_surface_color(rt
, 5, 245);
9272 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9273 color
= get_surface_color(rt
, 400, 245);
9274 ok(compare_color(color
, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color
);
9276 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9277 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9278 IDirect3DTexture2_Release(texture
);
9279 refcount
= IDirectDrawSurface4_Release(surface
);
9280 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9282 /* Test RGB - should multiply color components from diffuse vertex color
9284 memset(&surface_desc
, 0, sizeof(surface_desc
));
9285 surface_desc
.dwSize
= sizeof(surface_desc
);
9286 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9287 surface_desc
.dwHeight
= 128;
9288 surface_desc
.dwWidth
= 128;
9289 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9290 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9291 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
9292 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
9293 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
9294 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
9295 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
9296 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
9297 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9298 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9300 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9301 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9302 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9303 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9305 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9306 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9308 U5(fx
).dwFillColor
= 0x00ffffff;
9309 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9310 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9311 U5(fx
).dwFillColor
= 0x00ffff80;
9312 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9313 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9315 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
9316 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9318 hr
= IDirect3DDevice3_BeginScene(device
);
9319 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9320 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9321 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[0], 4, 0);
9322 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9323 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9324 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test2_quads
[4], 4, 0);
9325 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9326 hr
= IDirect3DDevice3_EndScene(device
);
9327 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9329 color
= get_surface_color(rt
, 5, 5);
9330 ok(compare_color(color
, 0x00ff0040, 2), "Got unexpected color 0x%08x.\n", color
);
9331 color
= get_surface_color(rt
, 400, 5);
9332 ok(compare_color(color
, 0x00ff0080, 2), "Got unexpected color 0x%08x.\n", color
);
9333 color
= get_surface_color(rt
, 5, 245);
9334 ok(compare_color(color
, 0x00800080, 2), "Got unexpected color 0x%08x.\n", color
);
9335 color
= get_surface_color(rt
, 400, 245);
9336 ok(compare_color(color
, 0x008000ff, 2), "Got unexpected color 0x%08x.\n", color
);
9338 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9339 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9340 IDirect3DTexture2_Release(texture
);
9341 refcount
= IDirectDrawSurface4_Release(surface
);
9342 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9344 /* Test alpha again, now with color keyed texture (colorkey emulation in
9345 * wine can interfere). */
9346 memset(&surface_desc
, 0, sizeof(surface_desc
));
9347 surface_desc
.dwSize
= sizeof(surface_desc
);
9348 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
9349 surface_desc
.dwHeight
= 128;
9350 surface_desc
.dwWidth
= 128;
9351 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
9352 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
9353 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
9354 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
9355 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
9356 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
9357 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
9359 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9360 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
9362 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9363 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
9364 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9365 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9367 hr
= IDirect3DViewport3_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
9368 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
9370 U5(fx
).dwFillColor
= 0xf800;
9371 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9372 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9373 U5(fx
).dwFillColor
= 0x001f;
9374 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9375 ok(SUCCEEDED(hr
), "Failed to clear texture, hr %#x.\n", hr
);
9377 ckey
.dwColorSpaceLowValue
= 0x001f;
9378 ckey
.dwColorSpaceHighValue
= 0x001f;
9379 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
9380 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
9382 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
9383 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9384 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
9385 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9387 hr
= IDirect3DDevice3_BeginScene(device
);
9388 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9389 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9390 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[0], 4, 0);
9391 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9392 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9393 D3DFVF_XYZRHW
| D3DFVF_DIFFUSE
| D3DFVF_TEX1
, &test1_quads
[4], 4, 0);
9394 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9395 hr
= IDirect3DDevice3_EndScene(device
);
9396 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9398 color
= get_surface_color(rt
, 5, 5);
9399 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9400 color
= get_surface_color(rt
, 400, 5);
9401 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
9402 color
= get_surface_color(rt
, 5, 245);
9403 ok(compare_color(color
, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color
);
9404 color
= get_surface_color(rt
, 400, 245);
9405 ok(compare_color(color
, 0x00800000, 2), "Got unexpected color 0x%08x.\n", color
);
9407 hr
= IDirect3DDevice3_SetTexture(device
, 0, NULL
);
9408 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
9409 IDirect3DTexture2_Release(texture
);
9410 refcount
= IDirectDrawSurface4_Release(surface
);
9411 ok(!refcount
, "Surface not properly released, refcount %u.\n", refcount
);
9413 destroy_viewport(device
, viewport
);
9414 IDirectDrawSurface4_Release(rt
);
9415 IDirect3DDevice3_Release(device
);
9416 IDirect3D3_Release(d3d
);
9417 refcount
= IDirectDraw4_Release(ddraw
);
9418 ok(!refcount
, "Ddraw object not properly released, refcount %u.\n", refcount
);
9419 DestroyWindow(window
);
9422 static void test_signed_formats(void)
9425 IDirect3DDevice3
*device
;
9427 IDirectDraw4
*ddraw
;
9428 IDirectDrawSurface4
*surface
, *rt
;
9429 IDirect3DTexture2
*texture
;
9430 IDirect3DViewport3
*viewport
;
9431 DDSURFACEDESC2 surface_desc
;
9434 D3DCOLOR color
, expected_color
;
9438 struct vec3 position
;
9439 struct vec2 texcoord
;
9443 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
9444 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
9445 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
9446 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
9448 /* See test_signed_formats() in dlls/d3d9/tests/visual.c for an explanation
9449 * of these values. */
9450 static const USHORT content_v8u8
[4][4] =
9452 {0x0000, 0x7f7f, 0x8880, 0x0000},
9453 {0x0080, 0x8000, 0x7f00, 0x007f},
9454 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
9455 {0x4444, 0xc0c0, 0xa066, 0x22e0},
9457 static const DWORD content_x8l8v8u8
[4][4] =
9459 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
9460 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
9461 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
9462 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
9464 static const USHORT content_l6v5u5
[4][4] =
9466 {0x0000, 0xfdef, 0x0230, 0xfc00},
9467 {0x0010, 0x0200, 0x01e0, 0x000f},
9468 {0x4067, 0x53b9, 0x0421, 0xffff},
9469 {0x8108, 0x0318, 0xc28c, 0x909c},
9474 const void *content
;
9477 unsigned int slop
, slop_broken
;
9478 DDPIXELFORMAT format
;
9483 "D3DFMT_V8U8", content_v8u8
, sizeof(WORD
), FALSE
, 1, 0,
9485 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
, 0,
9486 {16}, {0x000000ff}, {0x0000ff00}, {0x00000000}, {0x00000000}
9490 "D3DFMT_X8L8V8U8", content_x8l8v8u8
, sizeof(DWORD
), TRUE
, 1, 0,
9492 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
9493 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
9497 "D3DFMT_L6V5U5", content_l6v5u5
, sizeof(WORD
), TRUE
, 4, 7,
9499 sizeof(DDPIXELFORMAT
), DDPF_BUMPDUDV
| DDPF_BUMPLUMINANCE
, 0,
9500 {16}, {0x0000001f}, {0x000003e0}, {0x0000fc00}, {0x00000000}
9504 /* No V16U16 or Q8W8V8U8 support in ddraw. */
9506 static const D3DCOLOR expected_colors
[4][4] =
9508 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
9509 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
9510 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
9511 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
9513 unsigned int i
, width
, x
, y
;
9514 D3DDEVICEDESC device_desc
, hel_desc
;
9516 window
= create_window();
9517 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9519 skip("Failed to create a 3D device, skipping test.\n");
9520 DestroyWindow(window
);
9524 memset(&device_desc
, 0, sizeof(device_desc
));
9525 device_desc
.dwSize
= sizeof(device_desc
);
9526 memset(&hel_desc
, 0, sizeof(hel_desc
));
9527 hel_desc
.dwSize
= sizeof(hel_desc
);
9528 hr
= IDirect3DDevice3_GetCaps(device
, &device_desc
, &hel_desc
);
9529 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
9530 if (!(device_desc
.dwTextureOpCaps
& D3DTEXOPCAPS_BLENDFACTORALPHA
))
9532 skip("D3DTOP_BLENDFACTORALPHA not supported, skipping bumpmap format tests.\n");
9536 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9537 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9538 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9539 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9540 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
9541 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
9543 memset(&surface_desc
, 0, sizeof(surface_desc
));
9544 surface_desc
.dwSize
= sizeof(surface_desc
);
9545 hr
= IDirectDrawSurface4_GetSurfaceDesc(rt
, &surface_desc
);
9546 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
9547 viewport
= create_viewport(device
, 0, 0, surface_desc
.dwWidth
, surface_desc
.dwHeight
);
9548 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
9549 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
9550 U1(clear_rect
).x1
= 0;
9551 U2(clear_rect
).y1
= 0;
9552 U3(clear_rect
).x2
= surface_desc
.dwWidth
;
9553 U4(clear_rect
).y2
= surface_desc
.dwHeight
;
9555 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
9556 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9558 /* dst = tex * 0.5 + 1.0 * (1.0 - 0.5) = tex * 0.5 + 0.5 */
9559 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x80ffffff);
9560 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
9561 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_BLENDFACTORALPHA
);
9562 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9563 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
9564 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9565 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
9566 ok(SUCCEEDED(hr
), "Failed to set texture stage state, hr %#x.\n", hr
);
9568 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
9570 for (width
= 1; width
< 5; width
+= 3)
9572 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
9573 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
9575 memset(&surface_desc
, 0, sizeof(surface_desc
));
9576 surface_desc
.dwSize
= sizeof(surface_desc
);
9577 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
9578 surface_desc
.dwWidth
= width
;
9579 surface_desc
.dwHeight
= 4;
9580 U4(surface_desc
).ddpfPixelFormat
= formats
[i
].format
;
9581 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
9582 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9585 skip("%s textures not supported, skipping.\n", formats
[i
].name
);
9588 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9590 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirect3DTexture2
, (void **)&texture
);
9591 ok(SUCCEEDED(hr
), "Failed to get Direct3DTexture2 interface, hr %#x, format %s.\n",
9592 hr
, formats
[i
].name
);
9593 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture
);
9594 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9595 IDirect3DTexture2_Release(texture
);
9597 memset(&surface_desc
, 0, sizeof(surface_desc
));
9598 surface_desc
.dwSize
= sizeof(surface_desc
);
9599 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, 0, NULL
);
9600 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9601 for (y
= 0; y
< 4; y
++)
9603 memcpy((char *)surface_desc
.lpSurface
+ y
* U1(surface_desc
).lPitch
,
9604 (char *)formats
[i
].content
+ y
* 4 * formats
[i
].pixel_size
,
9605 width
* formats
[i
].pixel_size
);
9607 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9608 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, format %s.\n", hr
, formats
[i
].name
);
9610 hr
= IDirect3DDevice3_BeginScene(device
);
9611 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
9612 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
,
9613 D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
9614 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
9615 hr
= IDirect3DDevice3_EndScene(device
);
9616 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
9618 for (y
= 0; y
< 4; y
++)
9620 for (x
= 0; x
< width
; x
++)
9622 expected_color
= expected_colors
[y
][x
];
9623 if (!formats
[i
].blue
)
9624 expected_color
|= 0x000000ff;
9626 color
= get_surface_color(rt
, 80 + 160 * x
, 60 + 120 * y
);
9627 ok(compare_color(color
, expected_color
, formats
[i
].slop
)
9628 || broken(compare_color(color
, expected_color
, formats
[i
].slop_broken
)),
9629 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
9630 expected_color
, color
, formats
[i
].name
, x
, y
);
9634 IDirectDrawSurface4_Release(surface
);
9638 destroy_viewport(device
, viewport
);
9639 IDirectDrawSurface4_Release(rt
);
9640 IDirectDraw4_Release(ddraw
);
9641 IDirect3D3_Release(d3d
);
9644 refcount
= IDirect3DDevice3_Release(device
);
9645 ok(!refcount
, "Device has %u references left.\n", refcount
);
9646 DestroyWindow(window
);
9649 static void test_color_fill(void)
9652 IDirect3DDevice3
*device
;
9654 IDirectDraw4
*ddraw
;
9655 IDirectDrawSurface4
*surface
, *surface2
;
9656 DDSURFACEDESC2 surface_desc
;
9657 DDPIXELFORMAT z_fmt
;
9662 RECT rect
= {5, 5, 7, 7};
9664 DWORD supported_fmts
= 0, num_fourcc_codes
, *fourcc_codes
;
9669 HRESULT colorfill_hr
, depthfill_hr
;
9674 DDPIXELFORMAT format
;
9679 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9680 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9682 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9683 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9687 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
9688 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain RGB", 0xdeadbeef, TRUE
,
9690 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9691 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9695 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
9696 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem texture RGB", 0xdeadbeef, TRUE
,
9698 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9699 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9703 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
9704 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem texture RGB", 0xdeadbeef, TRUE
,
9706 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9707 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9711 DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
,
9712 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "managed texture RGB", 0xdeadbeef, TRUE
,
9714 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
9715 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
9719 DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
, 0,
9720 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "vidmem zbuffer", 0xdeadbeef, TRUE
,
9721 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9724 DDSCAPS_ZBUFFER
| DDSCAPS_SYSTEMMEMORY
, 0,
9725 DDERR_INVALIDPARAMS
, DD_OK
, TRUE
, "sysmem zbuffer", 0xdeadbeef, TRUE
,
9726 {0, 0, 0, {0}, {0}, {0}, {0}, {0}}
9729 /* Colorfill on YUV surfaces always returns DD_OK, but the content is
9730 * different afterwards. DX9+ GPUs set one of the two luminance values
9731 * in each block, but AMD and Nvidia GPUs disagree on which luminance
9732 * value they set. r200 (dx8) just sets the entire block to the clear
9734 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9735 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain YUY2", 0, FALSE
,
9737 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9738 {0}, {0}, {0}, {0}, {0}
9742 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9743 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem offscreenplain UYVY", 0, FALSE
,
9745 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9746 {0}, {0}, {0}, {0}, {0}
9750 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
9751 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay YUY2", 0, FALSE
,
9753 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('Y', 'U', 'Y', '2'),
9754 {0}, {0}, {0}, {0}, {0}
9758 DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
, 0,
9759 DD_OK
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem overlay UYVY", 0, FALSE
,
9761 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('U', 'Y', 'V', 'Y'),
9762 {0}, {0}, {0}, {0}, {0}
9766 DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0,
9767 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "vidmem texture DXT1", 0, FALSE
,
9769 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9770 {0}, {0}, {0}, {0}, {0}
9774 DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0,
9775 E_NOTIMPL
, DDERR_INVALIDPARAMS
, FALSE
, "sysmem texture DXT1", 0, FALSE
,
9777 sizeof(DDPIXELFORMAT
), DDPF_FOURCC
, MAKEFOURCC('D', 'X', 'T', '1'),
9778 {0}, {0}, {0}, {0}, {0}
9782 /* The testbot fills this with 0x00 instead of the blue channel. The sysmem
9783 * surface works, presumably because it is handled by the runtime instead of
9785 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0,
9786 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "vidmem offscreenplain P8", 0xefefefef, FALSE
,
9788 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9789 {8}, {0}, {0}, {0}, {0}
9793 DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0,
9794 DD_OK
, DDERR_INVALIDPARAMS
, TRUE
, "sysmem offscreenplain P8", 0xefefefef, TRUE
,
9796 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_PALETTEINDEXED8
, 0,
9797 {8}, {0}, {0}, {0}, {0}
9809 {SRCCOPY
, "SRCCOPY", DD_OK
},
9810 {SRCPAINT
, "SRCPAINT", DDERR_NORASTEROPHW
},
9811 {SRCAND
, "SRCAND", DDERR_NORASTEROPHW
},
9812 {SRCINVERT
, "SRCINVERT", DDERR_NORASTEROPHW
},
9813 {SRCERASE
, "SRCERASE", DDERR_NORASTEROPHW
},
9814 {NOTSRCCOPY
, "NOTSRCCOPY", DDERR_NORASTEROPHW
},
9815 {NOTSRCERASE
, "NOTSRCERASE", DDERR_NORASTEROPHW
},
9816 {MERGECOPY
, "MERGECOPY", DDERR_NORASTEROPHW
},
9817 {MERGEPAINT
, "MERGEPAINT", DDERR_NORASTEROPHW
},
9818 {PATCOPY
, "PATCOPY", DDERR_NORASTEROPHW
},
9819 {PATPAINT
, "PATPAINT", DDERR_NORASTEROPHW
},
9820 {PATINVERT
, "PATINVERT", DDERR_NORASTEROPHW
},
9821 {DSTINVERT
, "DSTINVERT", DDERR_NORASTEROPHW
},
9822 {BLACKNESS
, "BLACKNESS", DD_OK
},
9823 {WHITENESS
, "WHITENESS", DD_OK
},
9824 {0xaa0029, "0xaa0029", DDERR_NORASTEROPHW
} /* noop */
9827 window
= create_window();
9828 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
9830 skip("Failed to create a 3D device, skipping test.\n");
9831 DestroyWindow(window
);
9835 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
9836 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
9837 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
9838 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
9840 memset(&z_fmt
, 0, sizeof(z_fmt
));
9841 IDirect3D3_EnumZBufferFormats(d3d
, &IID_IDirect3DHALDevice
, enum_z_fmt
, &z_fmt
);
9843 skip("No Z buffer formats supported, skipping Z buffer colorfill test.\n");
9845 IDirect3DDevice3_EnumTextureFormats(device
, test_block_formats_creation_cb
, &supported_fmts
);
9846 if (!(supported_fmts
& SUPPORT_DXT1
))
9847 skip("DXT1 textures not supported, skipping DXT1 colorfill test.\n");
9849 IDirect3D3_Release(d3d
);
9851 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, NULL
);
9852 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9853 fourcc_codes
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
9854 num_fourcc_codes
* sizeof(*fourcc_codes
));
9857 hr
= IDirectDraw4_GetFourCCCodes(ddraw
, &num_fourcc_codes
, fourcc_codes
);
9858 ok(SUCCEEDED(hr
), "Failed to get fourcc codes %#x.\n", hr
);
9859 for (i
= 0; i
< num_fourcc_codes
; i
++)
9861 if (fourcc_codes
[i
] == MAKEFOURCC('Y', 'U', 'Y', '2'))
9862 supported_fmts
|= SUPPORT_YUY2
;
9863 else if (fourcc_codes
[i
] == MAKEFOURCC('U', 'Y', 'V', 'Y'))
9864 supported_fmts
|= SUPPORT_UYVY
;
9866 HeapFree(GetProcessHeap(), 0, fourcc_codes
);
9868 memset(&hal_caps
, 0, sizeof(hal_caps
));
9869 hal_caps
.dwSize
= sizeof(hal_caps
);
9870 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
9871 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
9873 if (!(supported_fmts
& (SUPPORT_YUY2
| SUPPORT_UYVY
)) || !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9874 skip("Overlays or some YUV formats not supported, skipping YUV colorfill tests.\n");
9876 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
9878 DWORD expected_broken
= tests
[i
].result
;
9880 /* Some Windows drivers modify dwFillColor when it is used on P8 or FourCC formats. */
9881 memset(&fx
, 0, sizeof(fx
));
9882 fx
.dwSize
= sizeof(fx
);
9883 U5(fx
).dwFillColor
= 0xdeadbeef;
9885 memset(&surface_desc
, 0, sizeof(surface_desc
));
9886 surface_desc
.dwSize
= sizeof(surface_desc
);
9887 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
9888 surface_desc
.dwWidth
= 64;
9889 surface_desc
.dwHeight
= 64;
9890 U4(surface_desc
).ddpfPixelFormat
= tests
[i
].format
;
9891 surface_desc
.ddsCaps
.dwCaps
= tests
[i
].caps
;
9892 surface_desc
.ddsCaps
.dwCaps2
= tests
[i
].caps2
;
9894 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('D','X','T','1') && !(supported_fmts
& SUPPORT_DXT1
))
9896 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('Y','U','Y','2') && !(supported_fmts
& SUPPORT_YUY2
))
9898 if (tests
[i
].format
.dwFourCC
== MAKEFOURCC('U','Y','V','Y') && !(supported_fmts
& SUPPORT_UYVY
))
9900 if (tests
[i
].caps
& DDSCAPS_OVERLAY
&& !(hal_caps
.dwCaps
& DDCAPS_OVERLAY
))
9903 if (tests
[i
].caps
& DDSCAPS_ZBUFFER
)
9908 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
9909 /* Some drivers seem to convert depth values incorrectly or not at
9910 * all. Affects at least AMD PALM, 8.17.10.1247. */
9911 if (tests
[i
].caps
& DDSCAPS_VIDEOMEMORY
)
9916 expected
= tests
[i
].result
& U3(z_fmt
).dwZBitMask
;
9917 f
= ceilf(log2f(expected
+ 1.0f
));
9918 g
= (f
+ 1.0f
) / 2.0f
;
9920 expected_broken
= (expected
/ exp2f(f
) - g
) * 256;
9921 expected_broken
*= 0x01010101;
9925 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
9926 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9928 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9929 todo_wine_if (tests
[i
].format
.dwFourCC
)
9930 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9931 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9933 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
9934 todo_wine_if (tests
[i
].format
.dwFourCC
)
9935 ok(hr
== tests
[i
].colorfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9936 hr
, tests
[i
].colorfill_hr
, tests
[i
].name
);
9938 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9940 memset(&surface_desc
, 0, sizeof(surface_desc
));
9941 surface_desc
.dwSize
= sizeof(surface_desc
);
9942 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9943 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9944 color
= surface_desc
.lpSurface
;
9945 ok(*color
== tests
[i
].result
, "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9946 *color
, tests
[i
].result
, tests
[i
].name
);
9947 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9948 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9951 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9952 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9953 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9954 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
9955 ok(hr
== tests
[i
].depthfill_hr
, "Blt returned %#x, expected %#x, surface %s.\n",
9956 hr
, tests
[i
].depthfill_hr
, tests
[i
].name
);
9958 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9960 memset(&surface_desc
, 0, sizeof(surface_desc
));
9961 surface_desc
.dwSize
= sizeof(surface_desc
);
9962 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9963 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9964 color
= surface_desc
.lpSurface
;
9965 ok((*color
& U3(z_fmt
).dwZBitMask
) == (tests
[i
].result
& U3(z_fmt
).dwZBitMask
)
9966 || broken((*color
& U3(z_fmt
).dwZBitMask
) == (expected_broken
& U3(z_fmt
).dwZBitMask
)),
9967 "Got clear result 0x%08x, expected 0x%08x, surface %s.\n",
9968 *color
& U3(z_fmt
).dwZBitMask
, tests
[i
].result
& U3(z_fmt
).dwZBitMask
, tests
[i
].name
);
9969 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9970 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9973 U5(fx
).dwFillColor
= 0xdeadbeef;
9974 fx
.dwROP
= BLACKNESS
;
9975 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9976 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
9977 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9978 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
9979 U5(fx
).dwFillColor
, tests
[i
].name
);
9981 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
9983 memset(&surface_desc
, 0, sizeof(surface_desc
));
9984 surface_desc
.dwSize
= sizeof(surface_desc
);
9985 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
9986 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9987 color
= surface_desc
.lpSurface
;
9988 ok(*color
== 0, "Got clear result 0x%08x, expected 0x00000000, surface %s.\n",
9989 *color
, tests
[i
].name
);
9990 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
9991 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
9994 fx
.dwROP
= WHITENESS
;
9995 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
9996 ok(FAILED(hr
) == !tests
[i
].rop_success
, "Blt returned %#x, expected %s, surface %s.\n",
9997 hr
, tests
[i
].rop_success
? "success" : "failure", tests
[i
].name
);
9998 ok(U5(fx
).dwFillColor
== 0xdeadbeef, "dwFillColor was set to 0x%08x, surface %s\n",
9999 U5(fx
).dwFillColor
, tests
[i
].name
);
10001 if (SUCCEEDED(hr
) && tests
[i
].check_result
)
10003 memset(&surface_desc
, 0, sizeof(surface_desc
));
10004 surface_desc
.dwSize
= sizeof(surface_desc
);
10005 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_READONLY
, 0);
10006 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10007 color
= surface_desc
.lpSurface
;
10008 /* WHITENESS sets the alpha channel to 0x00. Ignore this for now. */
10009 ok((*color
& 0x00ffffff) == 0x00ffffff, "Got clear result 0x%08x, expected 0xffffffff, surface %s.\n",
10010 *color
, tests
[i
].name
);
10011 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
10012 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, surface %s.\n", hr
, tests
[i
].name
);
10015 IDirectDrawSurface4_Release(surface
);
10018 memset(&fx
, 0, sizeof(fx
));
10019 fx
.dwSize
= sizeof(fx
);
10020 U5(fx
).dwFillColor
= 0xdeadbeef;
10021 fx
.dwROP
= WHITENESS
;
10023 memset(&surface_desc
, 0, sizeof(surface_desc
));
10024 surface_desc
.dwSize
= sizeof(surface_desc
);
10025 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10026 surface_desc
.dwWidth
= 64;
10027 surface_desc
.dwHeight
= 64;
10028 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10029 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10030 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10031 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10032 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10033 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10034 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
10035 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10036 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10037 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10038 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10041 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, NULL
);
10042 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10043 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, NULL
);
10044 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10046 /* Unused source rectangle. */
10047 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10048 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10049 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10050 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10052 /* Unused source surface. */
10053 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10054 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10055 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10056 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10057 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10058 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10059 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10060 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10062 /* Inverted destination or source rectangle. */
10063 SetRect(&rect
, 5, 7, 7, 5);
10064 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10065 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10066 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10067 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10068 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10069 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10070 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10071 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10072 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10073 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10075 /* Negative rectangle. */
10076 SetRect(&rect
, -1, -1, 5, 5);
10077 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10078 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10079 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10080 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10081 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10082 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10083 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10084 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10085 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10086 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10088 /* Out of bounds rectangle. */
10089 SetRect(&rect
, 0, 0, 65, 65);
10090 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10091 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10092 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10093 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10095 /* Combine multiple flags. */
10096 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10097 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10098 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10099 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10100 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10101 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10103 for (i
= 0; i
< ARRAY_SIZE(rops
); i
++)
10105 fx
.dwROP
= rops
[i
].rop
;
10106 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_ROP
| DDBLT_WAIT
, &fx
);
10107 ok(hr
== rops
[i
].hr
, "Got unexpected hr %#x for rop %s.\n", hr
, rops
[i
].name
);
10110 IDirectDrawSurface4_Release(surface2
);
10111 IDirectDrawSurface4_Release(surface
);
10116 memset(&surface_desc
, 0, sizeof(surface_desc
));
10117 surface_desc
.dwSize
= sizeof(surface_desc
);
10118 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10119 surface_desc
.dwWidth
= 64;
10120 surface_desc
.dwHeight
= 64;
10121 U4(surface_desc
).ddpfPixelFormat
= z_fmt
;
10122 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
10123 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10124 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10125 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10126 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10129 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, NULL
);
10130 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10132 /* Unused source rectangle. */
10133 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10134 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10136 /* Unused source surface. */
10137 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10138 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10139 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10140 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10142 /* Inverted destination or source rectangle. */
10143 SetRect(&rect
, 5, 7, 7, 5);
10144 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10145 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10146 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10147 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10148 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10149 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10150 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10151 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10153 /* Negative rectangle. */
10154 SetRect(&rect
, -1, -1, 5, 5);
10155 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10156 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10157 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10158 ok(SUCCEEDED(hr
), "Got unexpected hr %#x.\n", hr
);
10159 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10160 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10161 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, surface2
, &rect
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10162 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10164 /* Out of bounds rectangle. */
10165 SetRect(&rect
, 0, 0, 65, 65);
10166 hr
= IDirectDrawSurface4_Blt(surface
, &rect
, NULL
, NULL
, DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10167 ok(hr
== DDERR_INVALIDRECT
, "Got unexpected hr %#x.\n", hr
);
10169 /* Combine multiple flags. */
10170 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_DEPTHFILL
| DDBLT_WAIT
, &fx
);
10171 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
10173 IDirectDrawSurface4_Release(surface2
);
10174 IDirectDrawSurface4_Release(surface
);
10177 IDirectDraw4_Release(ddraw
);
10178 refcount
= IDirect3DDevice3_Release(device
);
10179 ok(!refcount
, "Device has %u references left.\n", refcount
);
10180 DestroyWindow(window
);
10183 static void test_texcoordindex(void)
10188 struct vec2 texcoord1
;
10189 struct vec2 texcoord2
;
10190 struct vec2 texcoord3
;
10194 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}, {0.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10195 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 0.0f
}},
10196 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10197 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 0.0f
}},
10199 static const DWORD fvf
= D3DFVF_XYZ
| D3DFVF_TEX3
;
10200 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10201 IDirect3DDevice3
*device
;
10203 IDirectDraw4
*ddraw
;
10204 IDirectDrawSurface4
*rt
;
10205 IDirect3DViewport3
*viewport
;
10208 IDirectDrawSurface4
*surface1
, *surface2
;
10209 IDirect3DTexture2
*texture1
, *texture2
;
10210 DDSURFACEDESC2 surface_desc
;
10215 window
= create_window();
10216 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10218 skip("Failed to create a 3D device, skipping test.\n");
10219 DestroyWindow(window
);
10223 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10224 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10225 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10226 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10227 IDirect3D3_Release(d3d
);
10229 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10230 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10232 memset(&surface_desc
, 0, sizeof(surface_desc
));
10233 surface_desc
.dwSize
= sizeof(surface_desc
);
10234 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10235 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10236 surface_desc
.dwWidth
= 2;
10237 surface_desc
.dwHeight
= 2;
10238 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
10239 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
10240 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10241 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10242 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10243 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10244 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
10245 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface1
, NULL
);
10246 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10247 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface2
, NULL
);
10248 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10250 memset(&surface_desc
, 0, sizeof(surface_desc
));
10251 surface_desc
.dwSize
= sizeof(surface_desc
);
10252 hr
= IDirectDrawSurface4_Lock(surface1
, 0, &surface_desc
, 0, NULL
);
10253 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10254 ptr
= surface_desc
.lpSurface
;
10255 ptr
[0] = 0xff000000;
10256 ptr
[1] = 0xff00ff00;
10257 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10258 ptr
[0] = 0xff0000ff;
10259 ptr
[1] = 0xff00ffff;
10260 hr
= IDirectDrawSurface4_Unlock(surface1
, NULL
);
10261 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10263 memset(&surface_desc
, 0, sizeof(surface_desc
));
10264 surface_desc
.dwSize
= sizeof(surface_desc
);
10265 hr
= IDirectDrawSurface4_Lock(surface2
, 0, &surface_desc
, 0, NULL
);
10266 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10267 ptr
= surface_desc
.lpSurface
;
10268 ptr
[0] = 0xff000000;
10269 ptr
[1] = 0xff0000ff;
10270 ptr
+= U1(surface_desc
).lPitch
/ sizeof(*ptr
);
10271 ptr
[0] = 0xffff0000;
10272 ptr
[1] = 0xffff00ff;
10273 hr
= IDirectDrawSurface4_Unlock(surface2
, 0);
10274 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10276 viewport
= create_viewport(device
, 0, 0, 640, 480);
10277 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10278 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
10280 hr
= IDirectDrawSurface4_QueryInterface(surface1
, &IID_IDirect3DTexture2
, (void **)&texture1
);
10281 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10282 hr
= IDirectDrawSurface4_QueryInterface(surface2
, &IID_IDirect3DTexture2
, (void **)&texture2
);
10283 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10284 hr
= IDirect3DDevice3_SetTexture(device
, 0, texture1
);
10285 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10286 hr
= IDirect3DDevice3_SetTexture(device
, 1, texture2
);
10287 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10288 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10289 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10290 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
10291 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10292 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10293 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10294 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_ADD
);
10295 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10296 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10297 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10298 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
10299 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10300 hr
= IDirect3DDevice3_SetTextureStageState(device
, 2, D3DTSS_COLOROP
, D3DTOP_DISABLE
);
10301 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10303 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_TEXCOORDINDEX
, 1);
10304 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10305 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 0);
10306 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10308 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
10309 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10311 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10312 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10314 hr
= IDirect3DDevice3_BeginScene(device
);
10315 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10316 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10317 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10318 hr
= IDirect3DDevice3_EndScene(device
);
10319 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10321 color
= get_surface_color(rt
, 160, 120);
10322 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10323 color
= get_surface_color(rt
, 480, 120);
10324 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10325 color
= get_surface_color(rt
, 160, 360);
10326 ok(compare_color(color
, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color
);
10327 color
= get_surface_color(rt
, 480, 360);
10328 ok(compare_color(color
, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color
);
10330 /* D3DTSS_TEXTURETRANSFORMFLAGS was introduced in D3D7, can't test it here. */
10332 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_TEXCOORDINDEX
, 2);
10333 ok(SUCCEEDED(hr
), "Failed to set texcoord index, hr %#x.\n", hr
);
10335 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffff00, 1.0f
, 0);
10336 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10338 hr
= IDirect3DDevice3_BeginScene(device
);
10339 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10340 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, fvf
, quad
, 4, 0);
10341 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10342 hr
= IDirect3DDevice3_EndScene(device
);
10343 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10345 color
= get_surface_color(rt
, 160, 120);
10346 ok(compare_color(color
, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color
);
10347 color
= get_surface_color(rt
, 480, 120);
10348 ok(compare_color(color
, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color
);
10349 color
= get_surface_color(rt
, 160, 360);
10350 ok(compare_color(color
, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color
);
10351 color
= get_surface_color(rt
, 480, 360);
10352 ok(compare_color(color
, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color
);
10354 IDirect3DTexture2_Release(texture2
);
10355 IDirect3DTexture2_Release(texture1
);
10356 IDirectDrawSurface4_Release(surface2
);
10357 IDirectDrawSurface4_Release(surface1
);
10359 destroy_viewport(device
, viewport
);
10361 IDirectDrawSurface4_Release(rt
);
10362 IDirectDraw_Release(ddraw
);
10363 refcount
= IDirect3DDevice3_Release(device
);
10364 ok(!refcount
, "Device has %u references left.\n", refcount
);
10365 DestroyWindow(window
);
10368 static void test_colorkey_precision(void)
10373 struct vec2 texcoord
;
10377 {{-1.0f
, -1.0f
, 0.0f
}, {0.0f
, 1.0f
}},
10378 {{-1.0f
, 1.0f
, 0.0f
}, {0.0f
, 0.0f
}},
10379 {{ 1.0f
, -1.0f
, 0.0f
}, {1.0f
, 1.0f
}},
10380 {{ 1.0f
, 1.0f
, 0.0f
}, {1.0f
, 0.0f
}},
10382 IDirect3DDevice3
*device
;
10384 IDirectDraw4
*ddraw
;
10385 IDirectDrawSurface4
*rt
;
10386 IDirect3DViewport3
*viewport
;
10389 IDirectDrawSurface4
*src
, *dst
, *texture
;
10390 IDirect3DTexture2
*d3d_texture
;
10391 DDSURFACEDESC2 surface_desc
, lock_desc
;
10397 DWORD data
[4] = {0}, color_mask
;
10398 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10399 BOOL is_nvidia
, is_warp
;
10400 static const struct
10402 unsigned int max
, shift
, bpp
, clear
;
10410 255, 0, 4, 0x00345678, "D3DFMT_X8R8G8B8", FALSE
,
10412 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10413 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
10418 63, 5, 2, 0x5678, "D3DFMT_R5G6B5, G channel", FALSE
,
10420 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10421 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10426 31, 0, 2, 0x5678, "D3DFMT_R5G6B5, B channel", FALSE
,
10428 sizeof(DDPIXELFORMAT
), DDPF_RGB
, 0,
10429 {16}, {0xf800}, {0x07e0}, {0x001f}, {0x0000}
10434 15, 0, 2, 0x0678, "D3DFMT_A4R4G4B4", TRUE
,
10436 sizeof(DDPIXELFORMAT
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0,
10437 {16}, {0x0f00}, {0x00f0}, {0x000f}, {0xf000}
10442 window
= create_window();
10443 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10445 skip("Failed to create a 3D device, skipping test.\n");
10446 DestroyWindow(window
);
10450 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10451 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
10452 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
10453 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
10454 IDirect3D3_Release(d3d
);
10455 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10456 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10458 is_nvidia
= ddraw_is_nvidia(ddraw
);
10459 /* The Windows 8 WARP driver has plenty of false negatives in X8R8G8B8
10460 * (color key doesn't match although the values are equal), and a false
10461 * positive when the color key is 0 and the texture contains the value 1.
10462 * I don't want to mark this broken unconditionally since this would
10463 * essentially disable the test on Windows. Also on random occasions
10464 * 254 == 255 and 255 != 255.*/
10465 is_warp
= ddraw_is_warp(ddraw
);
10467 viewport
= create_viewport(device
, 0, 0, 640, 480);
10468 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10469 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
10471 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
10472 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
10473 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
10474 ok(SUCCEEDED(hr
), "Failed to disable z-buffering, hr %#x.\n", hr
);
10475 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
10476 ok(SUCCEEDED(hr
), "Failed to enable color keying, hr %#x.\n", hr
);
10477 /* Multiply the texture read result with 0, that way the result color if the key doesn't
10478 * match is constant. In theory color keying works without reading the texture result
10479 * (meaning we could just op=arg1, arg1=tfactor), but the Geforce7 Windows driver begs
10481 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
10482 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
10483 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_TEXTURE
);
10484 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10485 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_TFACTOR
);
10486 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
10487 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0x00000000);
10488 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
10490 memset(&fx
, 0, sizeof(fx
));
10491 fx
.dwSize
= sizeof(fx
);
10492 memset(&lock_desc
, 0, sizeof(lock_desc
));
10493 lock_desc
.dwSize
= sizeof(lock_desc
);
10495 for (t
= 0; t
< ARRAY_SIZE(tests
); ++t
)
10497 if (is_nvidia
&& tests
[t
].skip_nv
)
10499 win_skip("Skipping test %s on Nvidia Windows drivers.\n", tests
[t
].name
);
10503 memset(&surface_desc
, 0, sizeof(surface_desc
));
10504 surface_desc
.dwSize
= sizeof(surface_desc
);
10505 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
10506 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10507 surface_desc
.dwWidth
= 4;
10508 surface_desc
.dwHeight
= 1;
10509 U4(surface_desc
).ddpfPixelFormat
= tests
[t
].fmt
;
10510 /* Windows XP (at least with the r200 driver, other drivers untested) produces
10511 * garbage when doing color keyed texture->texture blits. */
10512 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
10513 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10514 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
10515 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10517 U5(fx
).dwFillColor
= tests
[t
].clear
;
10518 /* On the w8 testbot (WARP driver) the blit result has different values in the
10520 color_mask
= U2(tests
[t
].fmt
).dwRBitMask
10521 | U3(tests
[t
].fmt
).dwGBitMask
10522 | U4(tests
[t
].fmt
).dwBBitMask
;
10524 for (c
= 0; c
<= tests
[t
].max
; ++c
)
10526 /* The idiotic Nvidia Windows driver can't change the color key on a d3d
10527 * texture after it has been set once... */
10528 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
10529 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10530 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10531 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10532 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &texture
, NULL
);
10533 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10534 hr
= IDirectDrawSurface4_QueryInterface(texture
, &IID_IDirect3DTexture2
, (void **)&d3d_texture
);
10535 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
10536 hr
= IDirect3DDevice3_SetTexture(device
, 0, d3d_texture
);
10537 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#x.\n", hr
);
10539 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
10540 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
10542 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10543 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10544 switch (tests
[t
].bpp
)
10547 ((DWORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10548 ((DWORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10549 ((DWORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10550 ((DWORD
*)lock_desc
.lpSurface
)[3] = 0xffffffff;
10554 ((WORD
*)lock_desc
.lpSurface
)[0] = (c
? c
- 1 : 0) << tests
[t
].shift
;
10555 ((WORD
*)lock_desc
.lpSurface
)[1] = c
<< tests
[t
].shift
;
10556 ((WORD
*)lock_desc
.lpSurface
)[2] = min(c
+ 1, tests
[t
].max
) << tests
[t
].shift
;
10557 ((WORD
*)lock_desc
.lpSurface
)[3] = 0xffff;
10560 hr
= IDirectDrawSurface4_Unlock(src
, 0);
10561 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10562 hr
= IDirectDrawSurface4_Blt(texture
, NULL
, src
, NULL
, DDBLT_WAIT
, NULL
);
10563 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10565 ckey
.dwColorSpaceLowValue
= c
<< tests
[t
].shift
;
10566 ckey
.dwColorSpaceHighValue
= c
<< tests
[t
].shift
;
10567 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
10568 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10570 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_WAIT
, NULL
);
10571 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
10573 /* Don't make this read only, it somehow breaks the detection of the Nvidia bug below. */
10574 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &lock_desc
, DDLOCK_WAIT
, NULL
);
10575 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
10576 switch (tests
[t
].bpp
)
10579 data
[0] = ((DWORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10580 data
[1] = ((DWORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10581 data
[2] = ((DWORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10582 data
[3] = ((DWORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10586 data
[0] = ((WORD
*)lock_desc
.lpSurface
)[0] & color_mask
;
10587 data
[1] = ((WORD
*)lock_desc
.lpSurface
)[1] & color_mask
;
10588 data
[2] = ((WORD
*)lock_desc
.lpSurface
)[2] & color_mask
;
10589 data
[3] = ((WORD
*)lock_desc
.lpSurface
)[3] & color_mask
;
10592 hr
= IDirectDrawSurface4_Unlock(dst
, 0);
10593 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
10597 ok(data
[0] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10598 tests
[t
].clear
, data
[0], tests
[t
].name
, c
);
10600 if (data
[3] == tests
[t
].clear
)
10602 /* My Geforce GTX 460 on Windows 7 misbehaves when A4R4G4B4 is blitted with color
10603 * keying: The blit takes ~0.5 seconds, and subsequent color keying draws are broken,
10604 * even when a different surface is used. The blit itself doesn't draw anything,
10605 * so we can detect the bug by looking at the otherwise unused 4th texel. It should
10606 * never be masked out by the key.
10608 * On Windows 10 the problem is worse, Blt just hangs. For this reason the ARGB4444
10609 * test is disabled entirely.
10611 * Also appears to affect the testbot in some way with R5G6B5. Color keying is
10612 * terrible on WARP. */
10613 skip("Nvidia A4R4G4B4 color keying blit bug detected, skipping.\n");
10614 IDirect3DTexture2_Release(d3d_texture
);
10615 IDirectDrawSurface4_Release(texture
);
10616 IDirectDrawSurface4_Release(src
);
10617 IDirectDrawSurface4_Release(dst
);
10622 ok(data
[0] == (c
- 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10623 (c
- 1) << tests
[t
].shift
, data
[0], tests
[t
].name
, c
);
10625 ok(data
[1] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10626 tests
[t
].clear
, data
[1], tests
[t
].name
, c
);
10628 if (c
== tests
[t
].max
)
10629 ok(data
[2] == tests
[t
].clear
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10630 tests
[t
].clear
, data
[2], tests
[t
].name
, c
);
10632 ok(data
[2] == (c
+ 1) << tests
[t
].shift
, "Expected surface content %#x, got %#x, format %s, c=%u.\n",
10633 (c
+ 1) << tests
[t
].shift
, data
[2], tests
[t
].name
, c
);
10635 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 1.0f
, 0);
10636 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
10638 hr
= IDirect3DDevice3_BeginScene(device
);
10639 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10640 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_TEX1
, quad
, 4, 0);
10641 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10642 hr
= IDirect3DDevice3_EndScene(device
);
10643 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10645 color
= get_surface_color(rt
, 80, 240);
10647 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10648 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10649 color
, tests
[t
].name
, c
);
10651 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10652 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10653 color
, tests
[t
].name
, c
);
10655 color
= get_surface_color(rt
, 240, 240);
10656 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10657 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10658 color
, tests
[t
].name
, c
);
10660 color
= get_surface_color(rt
, 400, 240);
10661 if (c
== tests
[t
].max
)
10662 ok(compare_color(color
, 0x0000ff00, 1) || broken(is_warp
&& compare_color(color
, 0x00000000, 1)),
10663 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10664 color
, tests
[t
].name
, c
);
10666 ok(compare_color(color
, 0x00000000, 1) || broken(is_warp
&& compare_color(color
, 0x0000ff00, 1)),
10667 "Got unexpected color 0x%08x, format %s, c=%u.\n",
10668 color
, tests
[t
].name
, c
);
10670 IDirect3DTexture2_Release(d3d_texture
);
10671 IDirectDrawSurface4_Release(texture
);
10673 IDirectDrawSurface4_Release(src
);
10674 IDirectDrawSurface4_Release(dst
);
10678 destroy_viewport(device
, viewport
);
10679 IDirectDrawSurface4_Release(rt
);
10680 IDirectDraw4_Release(ddraw
);
10681 refcount
= IDirect3DDevice3_Release(device
);
10682 ok(!refcount
, "Device has %u references left.\n", refcount
);
10683 DestroyWindow(window
);
10686 static void test_range_colorkey(void)
10688 IDirectDraw4
*ddraw
;
10691 IDirectDrawSurface4
*surface
;
10692 DDSURFACEDESC2 surface_desc
;
10696 window
= create_window();
10697 ddraw
= create_ddraw();
10698 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10699 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10700 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10702 memset(&surface_desc
, 0, sizeof(surface_desc
));
10703 surface_desc
.dwSize
= sizeof(surface_desc
);
10704 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
10705 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
10706 surface_desc
.dwWidth
= 1;
10707 surface_desc
.dwHeight
= 1;
10708 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
10709 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
10710 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
10711 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
10712 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
10713 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0x00000000;
10715 /* Creating a surface with a range color key fails with DDERR_NOCOLORKEY. */
10716 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10717 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10718 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10719 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10721 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10722 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10723 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10724 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10726 /* Same for DDSCAPS_OFFSCREENPLAIN. */
10727 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
10728 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10729 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000001;
10730 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10731 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10733 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000001;
10734 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10735 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10736 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10738 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00000000;
10739 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00000000;
10740 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
10741 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
10743 /* Setting a range color key without DDCKEY_COLORSPACE collapses the key. */
10744 ckey
.dwColorSpaceLowValue
= 0x00000000;
10745 ckey
.dwColorSpaceHighValue
= 0x00000001;
10746 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10747 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10749 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10750 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10751 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10752 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10754 ckey
.dwColorSpaceLowValue
= 0x00000001;
10755 ckey
.dwColorSpaceHighValue
= 0x00000000;
10756 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10757 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10759 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10760 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10761 ok(ckey
.dwColorSpaceLowValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10762 ok(ckey
.dwColorSpaceHighValue
== 0x00000001, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10764 /* DDCKEY_COLORSPACE is ignored if the key is a single value. */
10765 ckey
.dwColorSpaceLowValue
= 0x00000000;
10766 ckey
.dwColorSpaceHighValue
= 0x00000000;
10767 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10768 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
10770 /* Using it with a range key results in DDERR_NOCOLORKEYHW. */
10771 ckey
.dwColorSpaceLowValue
= 0x00000001;
10772 ckey
.dwColorSpaceHighValue
= 0x00000000;
10773 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10774 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10775 ckey
.dwColorSpaceLowValue
= 0x00000000;
10776 ckey
.dwColorSpaceHighValue
= 0x00000001;
10777 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10778 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10779 /* Range destination keys don't work either. */
10780 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_DESTBLT
| DDCKEY_COLORSPACE
, &ckey
);
10781 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10783 /* Just to show it's not because of A, R, and G having equal values. */
10784 ckey
.dwColorSpaceLowValue
= 0x00000000;
10785 ckey
.dwColorSpaceHighValue
= 0x01010101;
10786 hr
= IDirectDrawSurface4_SetColorKey(surface
, DDCKEY_SRCBLT
| DDCKEY_COLORSPACE
, &ckey
);
10787 ok(hr
== DDERR_NOCOLORKEYHW
, "Got unexpected hr %#x.\n", hr
);
10789 /* None of these operations modified the key. */
10790 hr
= IDirectDrawSurface4_GetColorKey(surface
, DDCKEY_SRCBLT
, &ckey
);
10791 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
10792 ok(!ckey
.dwColorSpaceLowValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceLowValue
);
10793 ok(!ckey
.dwColorSpaceHighValue
, "Got unexpected value 0x%08x.\n", ckey
.dwColorSpaceHighValue
);
10795 IDirectDrawSurface4_Release(surface
),
10796 refcount
= IDirectDraw4_Release(ddraw
);
10797 ok(!refcount
, "Got unexpected refcount %u.\n", refcount
);
10798 DestroyWindow(window
);
10801 static void test_shademode(void)
10803 IDirect3DVertexBuffer
*vb_strip
, *vb_list
, *buffer
;
10804 IDirect3DViewport3
*viewport
;
10805 IDirect3DDevice3
*device
;
10806 D3DVERTEXBUFFERDESC desc
;
10807 IDirectDrawSurface4
*rt
;
10808 DWORD color0
, color1
;
10815 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
10816 static const struct
10818 struct vec3 position
;
10823 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10824 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10825 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10826 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
10830 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10831 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10832 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10834 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
10835 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
10836 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
10838 static const struct
10842 DWORD color0
, color1
;
10846 {D3DPT_TRIANGLESTRIP
, D3DSHADE_FLAT
, 0x00ff0000, 0x0000ff00},
10847 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10848 {D3DPT_TRIANGLESTRIP
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10849 {D3DPT_TRIANGLESTRIP
, D3DSHADE_PHONG
, 0x000dca28, 0x000d45c7},
10850 {D3DPT_TRIANGLELIST
, D3DSHADE_FLAT
, 0x00ff0000, 0x000000ff},
10851 {D3DPT_TRIANGLELIST
, D3DSHADE_GOURAUD
, 0x000dca28, 0x000d45c7},
10854 window
= create_window();
10855 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
10857 skip("Failed to create a 3D device, skipping test.\n");
10858 DestroyWindow(window
);
10862 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
10863 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
10864 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
10865 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
10867 viewport
= create_viewport(device
, 0, 0, 640, 480);
10868 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
10869 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
10871 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
10872 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
10874 memset(&desc
, 0, sizeof(desc
));
10875 desc
.dwSize
= sizeof(desc
);
10876 desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
10877 desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
10878 desc
.dwNumVertices
= ARRAY_SIZE(quad_strip
);
10879 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_strip
, 0, NULL
);
10880 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
10881 hr
= IDirect3DVertexBuffer_Lock(vb_strip
, 0, &data
, NULL
);
10882 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
10883 memcpy(data
, quad_strip
, sizeof(quad_strip
));
10884 hr
= IDirect3DVertexBuffer_Unlock(vb_strip
);
10885 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10887 desc
.dwNumVertices
= ARRAY_SIZE(quad_list
);
10888 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &desc
, &vb_list
, 0, NULL
);
10889 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#x.\n", hr
);
10890 hr
= IDirect3DVertexBuffer_Lock(vb_list
, 0, &data
, NULL
);
10891 ok(hr
== D3D_OK
, "Failed to lock vertex buffer, hr %#x.\n", hr
);
10892 memcpy(data
, quad_list
, sizeof(quad_list
));
10893 hr
= IDirect3DVertexBuffer_Unlock(vb_list
);
10894 ok(hr
== D3D_OK
, "Failed to unlock vertex buffer, hr %#x.\n", hr
);
10896 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
10897 * the color fixups we have to do for FLAT shading will be dependent on that. */
10899 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10901 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
10902 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
10904 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SHADEMODE
, tests
[i
].shademode
);
10905 ok(hr
== D3D_OK
, "Failed to set shade mode, hr %#x.\n", hr
);
10907 hr
= IDirect3DDevice3_BeginScene(device
);
10908 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
10909 buffer
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? vb_strip
: vb_list
;
10910 count
= tests
[i
].primtype
== D3DPT_TRIANGLESTRIP
? 4 : 6;
10911 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, tests
[i
].primtype
, buffer
, 0, count
, 0);
10912 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
10913 hr
= IDirect3DDevice3_EndScene(device
);
10914 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
10916 color0
= get_surface_color(rt
, 100, 100); /* Inside first triangle */
10917 color1
= get_surface_color(rt
, 500, 350); /* Inside second triangle */
10919 /* For D3DSHADE_FLAT it should take the color of the first vertex of
10920 * each triangle. This requires EXT_provoking_vertex or similar
10921 * functionality being available. */
10922 /* PHONG should be the same as GOURAUD, since no hardware implements
10924 ok(compare_color(color0
, tests
[i
].color0
, 1), "Test %u shading has color0 %08x, expected %08x.\n",
10925 i
, color0
, tests
[i
].color0
);
10926 ok(compare_color(color1
, tests
[i
].color1
, 1), "Test %u shading has color1 %08x, expected %08x.\n",
10927 i
, color1
, tests
[i
].color1
);
10930 IDirect3DVertexBuffer_Release(vb_strip
);
10931 IDirect3DVertexBuffer_Release(vb_list
);
10932 destroy_viewport(device
, viewport
);
10933 IDirectDrawSurface4_Release(rt
);
10934 IDirect3D3_Release(d3d
);
10935 refcount
= IDirect3DDevice3_Release(device
);
10936 ok(!refcount
, "Device has %u references left.\n", refcount
);
10937 DestroyWindow(window
);
10940 static void test_lockrect_invalid(void)
10943 IDirectDraw4
*ddraw
;
10944 IDirectDrawSurface4
*surface
;
10947 DDSURFACEDESC2 surface_desc
;
10949 DWORD needed_caps
= DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
;
10950 static RECT valid
[] =
10955 {120, 60, 128, 68},
10956 {60, 120, 68, 128},
10958 static RECT invalid
[] =
10960 {68, 60, 60, 68}, /* left > right */
10961 {60, 68, 68, 60}, /* top > bottom */
10962 {-8, 60, 0, 68}, /* left < surface */
10963 {60, -8, 68, 0}, /* top < surface */
10964 {-16, 60, -8, 68}, /* right < surface */
10965 {60, -16, 68, -8}, /* bottom < surface */
10966 {60, 60, 136, 68}, /* right > surface */
10967 {60, 60, 68, 136}, /* bottom > surface */
10968 {136, 60, 144, 68}, /* left > surface */
10969 {60, 136, 68, 144}, /* top > surface */
10971 static const struct
10979 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem offscreenplain", DDERR_INVALIDPARAMS
},
10980 {DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem offscreenplain", DDERR_INVALIDPARAMS
},
10981 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, 0, "sysmem texture", DDERR_INVALIDPARAMS
},
10982 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, 0, "vidmem texture", DDERR_INVALIDPARAMS
},
10983 {DDSCAPS_TEXTURE
, DDSCAPS2_TEXTUREMANAGE
, "managed texture", DDERR_INVALIDPARAMS
},
10986 window
= create_window();
10987 ddraw
= create_ddraw();
10988 ok(!!ddraw
, "Failed to create a ddraw object.\n");
10989 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
10990 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
10992 memset(&hal_caps
, 0, sizeof(hal_caps
));
10993 hal_caps
.dwSize
= sizeof(hal_caps
);
10994 hr
= IDirectDraw4_GetCaps(ddraw
, &hal_caps
, NULL
);
10995 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#x.\n", hr
);
10996 if ((hal_caps
.ddsCaps
.dwCaps
& needed_caps
) != needed_caps
10997 || !(hal_caps
.ddsCaps
.dwCaps
& DDSCAPS2_TEXTUREMANAGE
))
10999 skip("Required surface types not supported, skipping test.\n");
11003 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
11005 memset(&surface_desc
, 0, sizeof(surface_desc
));
11006 surface_desc
.dwSize
= sizeof(surface_desc
);
11007 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11008 surface_desc
.ddsCaps
.dwCaps
= resources
[r
].caps
;
11009 surface_desc
.ddsCaps
.dwCaps2
= resources
[r
].caps2
;
11010 surface_desc
.dwWidth
= 128;
11011 surface_desc
.dwHeight
= 128;
11012 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11013 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11014 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
11015 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xff0000;
11016 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x00ff00;
11017 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x0000ff;
11019 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11020 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11022 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, NULL
, DDLOCK_WAIT
, NULL
);
11023 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x, type %s.\n", hr
, resources
[r
].name
);
11025 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
11027 RECT
*rect
= &valid
[i
];
11029 memset(&surface_desc
, 0, sizeof(surface_desc
));
11030 surface_desc
.dwSize
= sizeof(surface_desc
);
11032 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11033 ok(SUCCEEDED(hr
), "Lock failed (%#x) for rect %s, type %s.\n",
11034 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11036 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11037 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11040 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
11042 RECT
*rect
= &invalid
[i
];
11044 memset(&surface_desc
, 1, sizeof(surface_desc
));
11045 surface_desc
.dwSize
= sizeof(surface_desc
);
11047 hr
= IDirectDrawSurface4_Lock(surface
, rect
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11048 ok(hr
== resources
[r
].hr
, "Lock returned %#x for rect %s, type %s.\n",
11049 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
11052 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11053 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11056 ok(!surface_desc
.lpSurface
, "Got unexpected lpSurface %p.\n", surface_desc
.lpSurface
);
11059 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11060 ok(SUCCEEDED(hr
), "Lock(rect = NULL) failed, hr %#x, type %s.\n",
11061 hr
, resources
[r
].name
);
11062 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
11063 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = NULL) returned %#x, type %s.\n",
11064 hr
, resources
[r
].name
);
11065 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11066 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11068 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11069 ok(SUCCEEDED(hr
), "Lock(rect = %s) failed (%#x).\n", wine_dbgstr_rect(&valid
[0]), hr
);
11070 hr
= IDirectDrawSurface4_Lock(surface
, &valid
[0], &surface_desc
, DDLOCK_WAIT
, NULL
);
11071 ok(hr
== DDERR_SURFACEBUSY
, "Double lock(rect = %s) failed (%#x).\n",
11072 wine_dbgstr_rect(&valid
[0]), hr
);
11074 /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
11075 * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */
11077 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11078 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x, type %s.\n", hr
, resources
[r
].name
);
11080 IDirectDrawSurface4_Release(surface
);
11084 IDirectDraw4_Release(ddraw
);
11085 DestroyWindow(window
);
11088 static void test_yv12_overlay(void)
11090 IDirectDrawSurface4
*src_surface
, *dst_surface
;
11091 RECT rect
= {13, 17, 14, 18};
11092 unsigned int offset
, y
;
11093 DDSURFACEDESC2 desc
;
11094 unsigned char *base
;
11095 IDirectDraw4
*ddraw
;
11099 window
= create_window();
11100 ddraw
= create_ddraw();
11101 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11102 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11103 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11105 if (!(src_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11107 skip("Failed to create a YV12 overlay, skipping test.\n");
11111 memset(&desc
, 0, sizeof(desc
));
11112 desc
.dwSize
= sizeof(desc
);
11113 hr
= IDirectDrawSurface4_Lock(src_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11114 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11116 ok(desc
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
| DDSD_PITCH
),
11117 "Got unexpected flags %#x.\n", desc
.dwFlags
);
11118 ok(desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_HWCODEC
)
11119 || desc
.ddsCaps
.dwCaps
== (DDSCAPS_OVERLAY
| DDSCAPS_VIDEOMEMORY
| DDSCAPS_LOCALVIDMEM
),
11120 "Got unexpected caps %#x.\n", desc
.ddsCaps
.dwCaps
);
11121 ok(desc
.dwWidth
== 256, "Got unexpected width %u.\n", desc
.dwWidth
);
11122 ok(desc
.dwHeight
== 256, "Got unexpected height %u.\n", desc
.dwHeight
);
11123 /* The overlay pitch seems to have 256 byte alignment. */
11124 ok(!(U1(desc
).lPitch
& 0xff), "Got unexpected pitch %u.\n", U1(desc
).lPitch
);
11126 /* Fill the surface with some data for the blit test. */
11127 base
= desc
.lpSurface
;
11129 for (y
= 0; y
< desc
.dwHeight
; ++y
)
11131 memset(base
+ U1(desc
).lPitch
* y
, 0x10, desc
.dwWidth
);
11134 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 4; ++y
)
11136 memset(base
+ U1(desc
).lPitch
* y
, 0x20, desc
.dwWidth
);
11139 for (; y
< desc
.dwHeight
+ desc
.dwHeight
/ 2; ++y
)
11141 memset(base
+ U1(desc
).lPitch
* y
, 0x30, desc
.dwWidth
);
11144 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11145 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11147 /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
11148 * other block-based formats like DXT the entire Y channel is stored in
11149 * one big chunk of memory, followed by the chroma channels. So partial
11150 * locks do not really make sense. Show that they are allowed nevertheless
11151 * and the offset points into the luminance data. */
11152 hr
= IDirectDrawSurface4_Lock(src_surface
, &rect
, &desc
, DDLOCK_WAIT
, NULL
);
11153 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11154 offset
= ((const unsigned char *)desc
.lpSurface
- base
);
11155 ok(offset
== rect
.top
* U1(desc
).lPitch
+ rect
.left
, "Got unexpected offset %u, expected %u.\n",
11156 offset
, rect
.top
* U1(desc
).lPitch
+ rect
.left
);
11157 hr
= IDirectDrawSurface4_Unlock(src_surface
, NULL
);
11158 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11160 if (!(dst_surface
= create_overlay(ddraw
, 256, 256, MAKEFOURCC('Y','V','1','2'))))
11162 /* Windows XP with a Radeon X1600 GPU refuses to create a second
11163 * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
11164 skip("Failed to create a second YV12 surface, skipping blit test.\n");
11165 IDirectDrawSurface4_Release(src_surface
);
11169 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, DDBLT_WAIT
, NULL
);
11170 /* VMware rejects YV12 blits. This behavior has not been seen on real
11171 * hardware yet, so mark it broken. */
11172 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
), "Failed to blit, hr %#x.\n", hr
);
11176 memset(&desc
, 0, sizeof(desc
));
11177 desc
.dwSize
= sizeof(desc
);
11178 hr
= IDirectDrawSurface4_Lock(dst_surface
, NULL
, &desc
, DDLOCK_WAIT
, NULL
);
11179 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
11181 base
= desc
.lpSurface
;
11182 ok(base
[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base
[0]);
11183 base
+= desc
.dwHeight
* U1(desc
).lPitch
;
11184 todo_wine
ok(base
[0] == 0x20, "Got unexpected V data 0x%02x.\n", base
[0]);
11185 base
+= desc
.dwHeight
/ 4 * U1(desc
).lPitch
;
11186 todo_wine
ok(base
[0] == 0x30, "Got unexpected U data 0x%02x.\n", base
[0]);
11188 hr
= IDirectDrawSurface4_Unlock(dst_surface
, NULL
);
11189 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
11192 IDirectDrawSurface4_Release(dst_surface
);
11193 IDirectDrawSurface4_Release(src_surface
);
11195 IDirectDraw4_Release(ddraw
);
11196 DestroyWindow(window
);
11199 static BOOL
dwm_enabled(void)
11203 if (!strcmp(winetest_platform
, "wine"))
11205 if (!pDwmIsCompositionEnabled
)
11207 if (FAILED(pDwmIsCompositionEnabled(&ret
)))
11212 static void test_offscreen_overlay(void)
11214 IDirectDrawSurface4
*overlay
, *offscreen
, *primary
;
11215 DDSURFACEDESC2 surface_desc
;
11216 IDirectDraw4
*ddraw
;
11221 window
= create_window();
11222 ddraw
= create_ddraw();
11223 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11224 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11225 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11227 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11229 skip("Failed to create a UYVY overlay, skipping test.\n");
11233 memset(&surface_desc
, 0, sizeof(surface_desc
));
11234 surface_desc
.dwSize
= sizeof(surface_desc
);
11235 surface_desc
.dwFlags
= DDSD_CAPS
;
11236 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11237 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11238 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11240 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11241 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11242 * surface prevents this by disabling the dwm. */
11243 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11244 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11245 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11246 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11248 /* Try to overlay a NULL surface. */
11249 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_SHOW
, NULL
);
11250 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11251 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, NULL
, NULL
, DDOVER_HIDE
, NULL
);
11252 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11254 /* Try to overlay an offscreen surface. */
11255 memset(&surface_desc
, 0, sizeof(surface_desc
));
11256 surface_desc
.dwSize
= sizeof(surface_desc
);
11257 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
| DDSD_PIXELFORMAT
;
11258 surface_desc
.dwWidth
= 64;
11259 surface_desc
.dwHeight
= 64;
11260 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11261 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
11262 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
11263 U4(surface_desc
).ddpfPixelFormat
.dwFourCC
= 0;
11264 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 16;
11265 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0xf800;
11266 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x07e0;
11267 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x001f;
11268 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
11269 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11271 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, offscreen
, NULL
, DDOVER_SHOW
, NULL
);
11272 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_OUTOFCAPS
&& dwm_enabled())
11273 || broken(hr
== E_NOTIMPL
&& ddraw_is_vmware(ddraw
)),
11274 "Failed to update overlay, hr %#x.\n", hr
);
11276 /* Try to overlay the primary with a non-overlay surface. */
11277 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11278 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11279 hr
= IDirectDrawSurface4_UpdateOverlay(offscreen
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11280 ok(hr
== DDERR_NOTAOVERLAYSURFACE
, "Got unexpected hr %#x.\n", hr
);
11282 IDirectDrawSurface4_Release(offscreen
);
11283 IDirectDrawSurface4_Release(primary
);
11284 IDirectDrawSurface4_Release(overlay
);
11286 IDirectDraw4_Release(ddraw
);
11287 DestroyWindow(window
);
11290 static void test_overlay_rect(void)
11292 IDirectDrawSurface4
*overlay
, *primary
= NULL
;
11293 DDSURFACEDESC2 surface_desc
;
11294 RECT rect
= {0, 0, 64, 64};
11295 IDirectDraw4
*ddraw
;
11301 window
= create_window();
11302 ddraw
= create_ddraw();
11303 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11304 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11305 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11307 if (!(overlay
= create_overlay(ddraw
, 64, 64, MAKEFOURCC('U','Y','V','Y'))))
11309 skip("Failed to create a UYVY overlay, skipping test.\n");
11313 memset(&surface_desc
, 0, sizeof(surface_desc
));
11314 surface_desc
.dwSize
= sizeof(surface_desc
);
11315 surface_desc
.dwFlags
= DDSD_CAPS
;
11316 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
11317 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &primary
, NULL
);
11318 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
11320 /* On Windows 7, and probably Vista, UpdateOverlay() will return
11321 * DDERR_OUTOFCAPS if the dwm is active. Calling GetDC() on the primary
11322 * surface prevents this by disabling the dwm. */
11323 hr
= IDirectDrawSurface4_GetDC(primary
, &dc
);
11324 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
11325 hr
= IDirectDrawSurface4_ReleaseDC(primary
, dc
);
11326 ok(SUCCEEDED(hr
), "Failed to release DC, hr %#x.\n", hr
);
11328 /* On Windows 8 and newer DWM can't be turned off, making overlays unusable. */
11331 win_skip("Cannot disable DWM, skipping overlay test.\n");
11335 /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is
11336 * used. This is not true in Windows Vista and earlier, but changed in
11338 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11339 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11340 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_HIDE
, NULL
);
11341 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11342 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, DDOVER_SHOW
, NULL
);
11343 ok(hr
== DD_OK
|| hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
11345 /* Show that the overlay position is the (top, left) coordinate of the
11346 * destination rectangle. */
11347 OffsetRect(&rect
, 32, 16);
11348 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_SHOW
, NULL
);
11349 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11350 pos_x
= -1; pos_y
= -1;
11351 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11352 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11353 ok(pos_x
== rect
.left
, "Got unexpected pos_x %d, expected %d.\n", pos_x
, rect
.left
);
11354 ok(pos_y
== rect
.top
, "Got unexpected pos_y %d, expected %d.\n", pos_y
, rect
.top
);
11356 /* Passing a NULL dest rect sets the position to 0/0. Visually it can be
11357 * seen that the overlay overlays the whole primary(==screen). */
11358 hr2
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, NULL
, 0, NULL
);
11359 ok(hr2
== DD_OK
|| hr2
== DDERR_INVALIDPARAMS
|| hr2
== DDERR_OUTOFCAPS
, "Got unexpected hr %#x.\n", hr2
);
11360 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11361 ok(SUCCEEDED(hr
), "Failed to get overlay position, hr %#x.\n", hr
);
11362 if (SUCCEEDED(hr2
))
11364 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11365 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11369 ok(pos_x
== 32, "Got unexpected pos_x %d.\n", pos_x
);
11370 ok(pos_y
== 16, "Got unexpected pos_y %d.\n", pos_y
);
11373 /* The position cannot be retrieved when the overlay is not shown. */
11374 hr
= IDirectDrawSurface4_UpdateOverlay(overlay
, NULL
, primary
, &rect
, DDOVER_HIDE
, NULL
);
11375 ok(SUCCEEDED(hr
), "Failed to update overlay, hr %#x.\n", hr
);
11376 pos_x
= -1; pos_y
= -1;
11377 hr
= IDirectDrawSurface4_GetOverlayPosition(overlay
, &pos_x
, &pos_y
);
11378 ok(hr
== DDERR_OVERLAYNOTVISIBLE
, "Got unexpected hr %#x.\n", hr
);
11379 ok(!pos_x
, "Got unexpected pos_x %d.\n", pos_x
);
11380 ok(!pos_y
, "Got unexpected pos_y %d.\n", pos_y
);
11382 IDirectDrawSurface4_Release(overlay
);
11385 IDirectDrawSurface4_Release(primary
);
11386 IDirectDraw4_Release(ddraw
);
11387 DestroyWindow(window
);
11390 static void test_blt(void)
11392 IDirectDrawSurface4
*surface
, *rt
;
11393 DDSURFACEDESC2 surface_desc
;
11394 IDirect3DDevice3
*device
;
11395 IDirectDraw4
*ddraw
;
11410 {{160, 0, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit. */
11411 {{160, 480, 640, 0}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, flipped source. */
11412 {{640, 0, 160, 480}, { 0, 0, 480, 480}, DDERR_INVALIDRECT
}, /* Overlapped blit, mirrored source. */
11413 {{160, 0, 480, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched x. */
11414 {{160, 160, 640, 480}, { 0, 0, 480, 480}, DD_OK
}, /* Overlapped blit, stretched y. */
11415 {{ 0, 0, 640, 480}, { 0, 0, 640, 480}, DD_OK
}, /* Full surface blit. */
11416 {{ 0, 0, 640, 480}, { 0, 480, 640, 0}, DDERR_INVALIDRECT
}, /* Full surface, flipped destination. */
11417 {{ 0, 0, 640, 480}, {640, 0, 0, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored destination. */
11418 {{ 0, 480, 640, 0}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, flipped source. */
11419 {{640, 0, 0, 480}, { 0, 0, 640, 480}, DDERR_INVALIDRECT
}, /* Full surface, mirrored source. */
11422 window
= create_window();
11423 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11425 skip("Failed to create a 3D device, skipping test.\n");
11426 DestroyWindow(window
);
11430 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
11431 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
11432 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
11433 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
11434 IDirect3D3_Release(d3d
);
11435 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11436 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11438 memset(&surface_desc
, 0, sizeof(surface_desc
));
11439 surface_desc
.dwSize
= sizeof(surface_desc
);
11440 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
11441 surface_desc
.dwWidth
= 640;
11442 surface_desc
.dwHeight
= 480;
11443 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11444 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
11445 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
11447 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, surface
, NULL
, 0, NULL
);
11448 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11450 hr
= IDirectDrawSurface4_Blt(surface
, NULL
, rt
, NULL
, 0, NULL
);
11451 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
11453 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11455 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11456 surface
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11457 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11459 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11460 rt
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11461 ok(hr
== test_data
[i
].hr
, "Test %u: Got unexpected hr %#x, expected %#x.\n", i
, hr
, test_data
[i
].hr
);
11463 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
,
11464 NULL
, &test_data
[i
].src_rect
, DDBLT_WAIT
, NULL
);
11465 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11467 hr
= IDirectDrawSurface4_Blt(surface
, &test_data
[i
].dst_rect
, NULL
, NULL
, DDBLT_WAIT
, NULL
);
11468 ok(hr
== DDERR_INVALIDPARAMS
, "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11471 IDirectDrawSurface4_Release(surface
);
11472 IDirectDrawSurface4_Release(rt
);
11473 IDirectDraw4_Release(ddraw
);
11474 refcount
= IDirect3DDevice3_Release(device
);
11475 ok(!refcount
, "Device has %u references left.\n", refcount
);
11476 DestroyWindow(window
);
11479 static void test_blt_z_alpha(void)
11481 DWORD blt_flags
[] =
11485 DDBLT_ALPHADESTCONSTOVERRIDE
,
11486 DDBLT_ALPHADESTNEG
,
11487 DDBLT_ALPHADESTSURFACEOVERRIDE
,
11488 DDBLT_ALPHAEDGEBLEND
,
11491 DDBLT_ALPHASRCCONSTOVERRIDE
,
11493 DDBLT_ALPHASRCSURFACEOVERRIDE
,
11496 DDBLT_ZBUFFERDESTCONSTOVERRIDE
,
11497 DDBLT_ZBUFFERDESTOVERRIDE
,
11498 DDBLT_ZBUFFERSRCCONSTOVERRIDE
,
11499 DDBLT_ZBUFFERSRCOVERRIDE
,
11501 IDirectDrawSurface4
*src_surface
, *dst_surface
;
11502 DDSURFACEDESC2 surface_desc
;
11503 IDirectDraw4
*ddraw
;
11512 window
= create_window();
11513 ddraw
= create_ddraw();
11514 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11515 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11516 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11518 memset(&pf
, 0, sizeof(pf
));
11519 pf
.dwSize
= sizeof(pf
);
11520 pf
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
11521 U1(pf
).dwRGBBitCount
= 32;
11522 U2(pf
).dwRBitMask
= 0x00ff0000;
11523 U3(pf
).dwGBitMask
= 0x0000ff00;
11524 U4(pf
).dwBBitMask
= 0x000000ff;
11525 U5(pf
).dwRGBAlphaBitMask
= 0xff000000;
11527 memset(&surface_desc
, 0, sizeof(surface_desc
));
11528 surface_desc
.dwSize
= sizeof(surface_desc
);
11529 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
11530 surface_desc
.dwWidth
= 64;
11531 surface_desc
.dwHeight
= 64;
11532 U4(surface_desc
).ddpfPixelFormat
= pf
;
11533 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11535 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
11536 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
11537 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
11538 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
11540 memset(&fx
, 0, sizeof(fx
));
11541 fx
.dwSize
= sizeof(fx
);
11542 fx
.dwZBufferOpCode
= D3DCMP_NEVER
;
11543 fx
.dwZDestConstBitDepth
= 32;
11544 U1(fx
).dwZDestConst
= 0x11111111;
11545 fx
.dwZSrcConstBitDepth
= 32;
11546 U2(fx
).dwZSrcConst
= 0xeeeeeeee;
11547 fx
.dwAlphaEdgeBlendBitDepth
= 8;
11548 fx
.dwAlphaEdgeBlend
= 0x7f;
11549 fx
.dwAlphaDestConstBitDepth
= 8;
11550 U3(fx
).dwAlphaDestConst
= 0xdd;
11551 fx
.dwAlphaSrcConstBitDepth
= 8;
11552 U4(fx
).dwAlphaSrcConst
= 0x22;
11554 for (i
= 0; i
< ARRAY_SIZE(blt_flags
); ++i
)
11556 fx
.dwFillColor
= 0x3300ff00;
11557 hr
= IDirectDrawSurface4_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11558 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11560 fx
.dwFillColor
= 0xccff0000;
11561 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
11562 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11564 hr
= IDirectDrawSurface4_Blt(dst_surface
, NULL
, src_surface
, NULL
, blt_flags
[i
] | DDBLT_WAIT
, &fx
);
11565 ok(SUCCEEDED(hr
), "Test %u: Got unexpected hr %#x.\n", i
, hr
);
11567 color
= get_surface_color(dst_surface
, 32, 32);
11568 ok(compare_color(color
, 0x0000ff00, 0), "Test %u: Got unexpected color 0x%08x.\n", i
, color
);
11571 IDirectDrawSurface4_Release(dst_surface
);
11572 IDirectDrawSurface4_Release(src_surface
);
11573 refcount
= IDirectDraw4_Release(ddraw
);
11574 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
11575 DestroyWindow(window
);
11578 static void test_color_clamping(void)
11580 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
11581 static D3DMATRIX mat
=
11583 1.0f
, 0.0f
, 0.0f
, 0.0f
,
11584 0.0f
, 1.0f
, 0.0f
, 0.0f
,
11585 0.0f
, 0.0f
, 1.0f
, 0.0f
,
11586 0.0f
, 0.0f
, 0.0f
, 1.0f
,
11588 static struct vec3 quad
[] =
11590 {-1.0f
, -1.0f
, 0.1f
},
11591 {-1.0f
, 1.0f
, 0.1f
},
11592 { 1.0f
, -1.0f
, 0.1f
},
11593 { 1.0f
, 1.0f
, 0.1f
},
11595 IDirect3DViewport3
*viewport
;
11596 IDirect3DDevice3
*device
;
11597 IDirectDrawSurface4
*rt
;
11603 window
= create_window();
11604 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
11606 skip("Failed to create a 3D device, skipping test.\n");
11607 DestroyWindow(window
);
11611 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
11612 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
11614 viewport
= create_viewport(device
, 0, 0, 640, 480);
11615 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
11616 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
11618 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
11619 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
11620 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
11621 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
11622 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
11623 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
11624 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
11625 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
11626 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
11627 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
11628 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
11629 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
11630 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
11631 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
11632 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
11633 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
11634 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
11635 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
11637 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_TEXTUREFACTOR
, 0xff404040);
11638 ok(SUCCEEDED(hr
), "Failed to set texture factor, hr %#x.\n", hr
);
11639 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_ADD
);
11640 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11641 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
11642 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11643 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG2
, D3DTA_SPECULAR
);
11644 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11645 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLOROP
, D3DTOP_MODULATE
);
11646 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
11647 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG1
, D3DTA_TFACTOR
);
11648 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11649 hr
= IDirect3DDevice3_SetTextureStageState(device
, 1, D3DTSS_COLORARG2
, D3DTA_CURRENT
);
11650 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
11652 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
11653 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
11655 hr
= IDirect3DDevice3_BeginScene(device
);
11656 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
11658 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
11659 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
11661 hr
= IDirect3DDevice3_EndScene(device
);
11662 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
11664 color
= get_surface_color(rt
, 320, 240);
11665 ok(compare_color(color
, 0x00404040, 1), "Got unexpected color 0x%08x.\n", color
);
11667 destroy_viewport(device
, viewport
);
11668 IDirectDrawSurface4_Release(rt
);
11669 refcount
= IDirect3DDevice3_Release(device
);
11670 ok(!refcount
, "Device has %u references left.\n", refcount
);
11671 DestroyWindow(window
);
11674 static void test_getdc(void)
11676 DDSCAPS2 caps
= {DDSCAPS_COMPLEX
, 0, 0, {0}};
11677 IDirectDrawSurface4
*surface
, *surface2
, *tmp
;
11678 DDSURFACEDESC2 surface_desc
, map_desc
;
11679 IDirectDraw4
*ddraw
;
11685 static const struct
11688 DDPIXELFORMAT format
;
11689 BOOL getdc_supported
;
11690 HRESULT alt_result
;
11694 {"D3DFMT_A8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11695 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}}, TRUE
},
11696 {"D3DFMT_X8R8G8B8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11697 {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}}, TRUE
},
11698 {"D3DFMT_R5G6B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11699 {0x0000f800}, {0x000007e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11700 {"D3DFMT_X1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11701 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00000000}}, TRUE
},
11702 {"D3DFMT_A1R5G5B5", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11703 {0x00007c00}, {0x000003e0}, {0x0000001f}, {0x00008000}}, TRUE
},
11704 {"D3DFMT_A4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {16},
11705 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11706 {"D3DFMT_X4R4G4B4", {sizeof(test_data
->format
), DDPF_RGB
, 0, {16},
11707 {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11708 {"D3DFMT_A2R10G10B10", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11709 {0xc0000000}, {0x3ff00000}, {0x000ffc00}, {0x000003ff}}, TRUE
},
11710 {"D3DFMT_A8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
| DDPF_ALPHAPIXELS
, 0, {32},
11711 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11712 {"D3DFMT_X8B8G8R8", {sizeof(test_data
->format
), DDPF_RGB
, 0, {32},
11713 {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}}, TRUE
, DDERR_CANTCREATEDC
/* Vista+ */},
11714 {"D3DFMT_R3G3B2", {sizeof(test_data
->format
), DDPF_RGB
, 0, {8},
11715 {0x000000e0}, {0x0000001c}, {0x00000003}, {0x00000000}}, FALSE
},
11716 /* GetDC() on a P8 surface fails unless the display mode is 8 bpp.
11717 * This is not implemented in wine yet, so disable the test for now.
11718 * Succeeding P8 GetDC() calls are tested in the ddraw:visual test.
11719 {"D3DFMT_P8", {sizeof(test_data->format), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0, {8 },
11720 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE},
11722 {"D3DFMT_L8", {sizeof(test_data
->format
), DDPF_LUMINANCE
, 0, {8},
11723 {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11724 {"D3DFMT_A8L8", {sizeof(test_data
->format
), DDPF_ALPHAPIXELS
| DDPF_LUMINANCE
, 0, {16},
11725 {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}}, FALSE
},
11726 {"D3DFMT_DXT1", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','1'), {0},
11727 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11728 {"D3DFMT_DXT2", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','2'), {0},
11729 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11730 {"D3DFMT_DXT3", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','3'), {0},
11731 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11732 {"D3DFMT_DXT4", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','4'), {0},
11733 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11734 {"D3DFMT_DXT5", {sizeof(test_data
->format
), DDPF_FOURCC
, MAKEFOURCC('D','X','T','5'), {0},
11735 {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}}, FALSE
},
11738 window
= create_window();
11739 ddraw
= create_ddraw();
11740 ok(!!ddraw
, "Failed to create a ddraw object.\n");
11741 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
11742 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
11744 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
11746 memset(&surface_desc
, 0, sizeof(surface_desc
));
11747 surface_desc
.dwSize
= sizeof(surface_desc
);
11748 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
11749 surface_desc
.dwWidth
= 64;
11750 surface_desc
.dwHeight
= 64;
11751 U4(surface_desc
).ddpfPixelFormat
= test_data
[i
].format
;
11752 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
11754 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11756 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
11757 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
11758 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11760 skip("Failed to create surface for format %s (hr %#x), skipping tests.\n", test_data
[i
].name
, hr
);
11765 dc
= (void *)0x1234;
11766 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11767 if (test_data
[i
].getdc_supported
)
11768 ok(SUCCEEDED(hr
) || broken(hr
== test_data
[i
].alt_result
),
11769 "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11771 ok(FAILED(hr
), "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11775 unsigned int width_bytes
;
11781 type
= GetObjectType(dc
);
11782 ok(type
== OBJ_MEMDC
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11783 bitmap
= GetCurrentObject(dc
, OBJ_BITMAP
);
11784 type
= GetObjectType(bitmap
);
11785 ok(type
== OBJ_BITMAP
, "Got unexpected object type %#x for format %s.\n", type
, test_data
[i
].name
);
11787 size
= GetObjectA(bitmap
, sizeof(dib
), &dib
);
11788 ok(size
== sizeof(dib
), "Got unexpected size %d for format %s.\n", size
, test_data
[i
].name
);
11789 ok(!dib
.dsBm
.bmType
, "Got unexpected type %#x for format %s.\n",
11790 dib
.dsBm
.bmType
, test_data
[i
].name
);
11791 ok(dib
.dsBm
.bmWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11792 dib
.dsBm
.bmWidth
, test_data
[i
].name
);
11793 ok(dib
.dsBm
.bmHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11794 dib
.dsBm
.bmHeight
, test_data
[i
].name
);
11795 width_bytes
= ((dib
.dsBm
.bmWidth
* U1(test_data
[i
].format
).dwRGBBitCount
+ 31) >> 3) & ~3;
11796 ok(dib
.dsBm
.bmWidthBytes
== width_bytes
, "Got unexpected width bytes %d for format %s.\n",
11797 dib
.dsBm
.bmWidthBytes
, test_data
[i
].name
);
11798 ok(dib
.dsBm
.bmPlanes
== 1, "Got unexpected plane count %d for format %s.\n",
11799 dib
.dsBm
.bmPlanes
, test_data
[i
].name
);
11800 ok(dib
.dsBm
.bmBitsPixel
== U1(test_data
[i
].format
).dwRGBBitCount
,
11801 "Got unexpected bit count %d for format %s.\n",
11802 dib
.dsBm
.bmBitsPixel
, test_data
[i
].name
);
11803 ok(!!dib
.dsBm
.bmBits
, "Got unexpected bits %p for format %s.\n",
11804 dib
.dsBm
.bmBits
, test_data
[i
].name
);
11806 ok(dib
.dsBmih
.biSize
== sizeof(dib
.dsBmih
), "Got unexpected size %u for format %s.\n",
11807 dib
.dsBmih
.biSize
, test_data
[i
].name
);
11808 ok(dib
.dsBmih
.biWidth
== surface_desc
.dwWidth
, "Got unexpected width %d for format %s.\n",
11809 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11810 ok(dib
.dsBmih
.biHeight
== surface_desc
.dwHeight
, "Got unexpected height %d for format %s.\n",
11811 dib
.dsBmih
.biHeight
, test_data
[i
].name
);
11812 ok(dib
.dsBmih
.biPlanes
== 1, "Got unexpected plane count %u for format %s.\n",
11813 dib
.dsBmih
.biPlanes
, test_data
[i
].name
);
11814 ok(dib
.dsBmih
.biBitCount
== U1(test_data
[i
].format
).dwRGBBitCount
,
11815 "Got unexpected bit count %u for format %s.\n",
11816 dib
.dsBmih
.biBitCount
, test_data
[i
].name
);
11817 ok(dib
.dsBmih
.biCompression
== (U1(test_data
[i
].format
).dwRGBBitCount
== 16 ? BI_BITFIELDS
: BI_RGB
)
11818 || broken(U1(test_data
[i
].format
).dwRGBBitCount
== 32 && dib
.dsBmih
.biCompression
== BI_BITFIELDS
),
11819 "Got unexpected compression %#x for format %s.\n",
11820 dib
.dsBmih
.biCompression
, test_data
[i
].name
);
11821 ok(!dib
.dsBmih
.biSizeImage
, "Got unexpected image size %u for format %s.\n",
11822 dib
.dsBmih
.biSizeImage
, test_data
[i
].name
);
11823 ok(!dib
.dsBmih
.biXPelsPerMeter
, "Got unexpected horizontal resolution %d for format %s.\n",
11824 dib
.dsBmih
.biXPelsPerMeter
, test_data
[i
].name
);
11825 ok(!dib
.dsBmih
.biYPelsPerMeter
, "Got unexpected vertical resolution %d for format %s.\n",
11826 dib
.dsBmih
.biYPelsPerMeter
, test_data
[i
].name
);
11827 ok(!dib
.dsBmih
.biClrUsed
, "Got unexpected used colour count %u for format %s.\n",
11828 dib
.dsBmih
.biClrUsed
, test_data
[i
].name
);
11829 ok(!dib
.dsBmih
.biClrImportant
, "Got unexpected important colour count %u for format %s.\n",
11830 dib
.dsBmih
.biClrImportant
, test_data
[i
].name
);
11832 if (dib
.dsBmih
.biCompression
== BI_BITFIELDS
)
11834 ok((dib
.dsBitfields
[0] == U2(test_data
[i
].format
).dwRBitMask
11835 && dib
.dsBitfields
[1] == U3(test_data
[i
].format
).dwGBitMask
11836 && dib
.dsBitfields
[2] == U4(test_data
[i
].format
).dwBBitMask
)
11837 || broken(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2]),
11838 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11839 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11843 ok(!dib
.dsBitfields
[0] && !dib
.dsBitfields
[1] && !dib
.dsBitfields
[2],
11844 "Got unexpected colour masks 0x%08x 0x%08x 0x%08x for format %s.\n",
11845 dib
.dsBitfields
[0], dib
.dsBitfields
[1], dib
.dsBitfields
[2], test_data
[i
].name
);
11847 ok(!dib
.dshSection
, "Got unexpected section %p for format %s.\n", dib
.dshSection
, test_data
[i
].name
);
11848 ok(!dib
.dsOffset
, "Got unexpected offset %u for format %s.\n", dib
.dsOffset
, test_data
[i
].name
);
11850 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11851 ok(hr
== DD_OK
, "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11855 ok(!dc
, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11858 IDirectDrawSurface4_Release(surface
);
11863 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_COMPLEX
| DDSCAPS_MIPMAP
;
11864 surface_desc
.ddsCaps
.dwCaps2
= DDSCAPS2_TEXTUREMANAGE
;
11865 if (FAILED(hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
)))
11867 skip("Failed to create mip-mapped texture for format %s (hr %#x), skipping tests.\n",
11868 test_data
[i
].name
, hr
);
11872 hr
= IDirectDrawSurface4_GetAttachedSurface(surface
, &caps
, &tmp
);
11873 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11874 hr
= IDirectDrawSurface4_GetAttachedSurface(tmp
, &caps
, &surface2
);
11875 ok(SUCCEEDED(hr
), "Failed to get attached surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11876 IDirectDrawSurface4_Release(tmp
);
11878 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11879 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11880 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11881 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11882 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11883 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11884 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11885 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11887 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11888 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11889 dc2
= (void *)0x1234;
11890 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
11891 ok(hr
== DDERR_DCALREADYCREATED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11892 ok(dc2
== (void *)0x1234, "Got unexpected dc %p for format %s.\n", dc
, test_data
[i
].name
);
11893 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11894 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11895 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11896 ok(hr
== DDERR_NODC
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11898 map_desc
.dwSize
= sizeof(map_desc
);
11899 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11900 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11901 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11902 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11903 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11904 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11905 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11906 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11908 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11909 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11910 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11911 ok(hr
== DDERR_SURFACEBUSY
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11912 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11913 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11915 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11916 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11917 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11918 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11919 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11920 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11921 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11922 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11924 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11925 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11926 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc2
);
11927 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11928 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc2
);
11929 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11930 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11931 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11933 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11934 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11935 hr
= IDirectDrawSurface4_GetDC(surface
, &dc2
);
11936 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11937 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc2
);
11938 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11939 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11940 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11942 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11943 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11944 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11945 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11946 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11947 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11948 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11949 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11951 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11952 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11953 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11954 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11955 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11956 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11957 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11958 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11960 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11961 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11962 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11963 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11964 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11965 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11966 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11967 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11969 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
11970 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11971 hr
= IDirectDrawSurface4_Lock(surface2
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11972 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11973 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11974 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11975 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
11976 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11978 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11979 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11980 hr
= IDirectDrawSurface4_Lock(surface
, NULL
, &map_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
11981 ok(SUCCEEDED(hr
), "Failed to map surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11982 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11983 ok(SUCCEEDED(hr
), "Failed to unmap surface for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11984 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11985 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11987 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11988 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11989 hr
= IDirectDrawSurface4_GetDC(surface2
, &dc
);
11990 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11991 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11992 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11993 hr
= IDirectDrawSurface4_ReleaseDC(surface2
, dc
);
11994 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
11995 hr
= IDirectDrawSurface4_Unlock(surface
, NULL
);
11996 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
11998 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
11999 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12000 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
12001 ok(SUCCEEDED(hr
), "Failed to get DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12002 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12003 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12004 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
12005 ok(SUCCEEDED(hr
), "Failed to release DC for format %s, hr %#x.\n", test_data
[i
].name
, hr
);
12006 hr
= IDirectDrawSurface4_Unlock(surface2
, NULL
);
12007 ok(hr
== DDERR_NOTLOCKED
, "Got unexpected hr %#x for format %s.\n", hr
, test_data
[i
].name
);
12009 IDirectDrawSurface4_Release(surface2
);
12010 IDirectDrawSurface4_Release(surface
);
12013 IDirectDraw4_Release(ddraw
);
12014 DestroyWindow(window
);
12017 static void test_draw_primitive(void)
12019 static WORD indices
[] = {0, 1, 2, 3};
12020 static struct vec3 quad
[] =
12022 {-1.0f
, -1.0f
, 0.0f
},
12023 {-1.0f
, 1.0f
, 0.0f
},
12024 { 1.0f
, -1.0f
, 0.0f
},
12025 { 1.0f
, 1.0f
, 0.0f
},
12027 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
12028 IDirect3DViewport3
*viewport
;
12029 D3DVERTEXBUFFERDESC vb_desc
;
12030 IDirect3DVertexBuffer
*vb
;
12031 IDirect3DDevice3
*device
;
12038 window
= create_window();
12039 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12041 skip("Failed to create a 3D device, skipping test.\n");
12042 DestroyWindow(window
);
12046 viewport
= create_viewport(device
, 0, 0, 640, 480);
12047 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12048 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12050 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12051 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12053 memset(&vb_desc
, 0, sizeof(vb_desc
));
12054 vb_desc
.dwSize
= sizeof(vb_desc
);
12055 vb_desc
.dwFVF
= D3DFVF_XYZ
;
12056 vb_desc
.dwNumVertices
= 4;
12057 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
12058 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
12060 IDirect3D3_Release(d3d
);
12062 memset(&strided
, 0, sizeof(strided
));
12064 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, NULL
, 0, 0);
12065 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12066 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12067 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, NULL
, 0, 0);
12068 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12069 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12070 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12071 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, 0);
12072 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12073 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, 0);
12074 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12075 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 0, 0);
12076 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12078 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, NULL
, 0, indices
, 4, 0);
12079 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12080 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12081 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 0, indices
, 4, 0);
12082 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12083 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12084 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12086 strided
.position
.lpvData
= quad
;
12087 strided
.position
.dwStride
= sizeof(*quad
);
12088 hr
= IDirect3DVertexBuffer_Lock(vb
, 0, &data
, NULL
);
12089 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
12090 memcpy(data
, quad
, sizeof(quad
));
12091 hr
= IDirect3DVertexBuffer_Unlock(vb
);
12092 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
12094 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, NULL
, 0, 0);
12095 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12096 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12097 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, NULL
, 0, 0);
12098 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12099 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, NULL
, 0, 0);
12100 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12101 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, 0);
12102 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12103 hr
= IDirect3DDevice3_DrawPrimitiveStrided(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, 0);
12104 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12105 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, 0, 4, 0);
12106 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12107 hr
= IDirect3DDevice3_DrawIndexedPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, quad
, 4, indices
, 4, 0);
12108 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12109 hr
= IDirect3DDevice3_DrawIndexedPrimitiveStrided(device
,
12110 D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
, &strided
, 4, indices
, 4, 0);
12111 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12112 hr
= IDirect3DDevice3_DrawIndexedPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, vb
, indices
, 4, 0);
12113 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12115 IDirect3DVertexBuffer_Release(vb
);
12116 destroy_viewport(device
, viewport
);
12117 refcount
= IDirect3DDevice3_Release(device
);
12118 ok(!refcount
, "Device has %u references left.\n", refcount
);
12119 DestroyWindow(window
);
12122 static void test_edge_antialiasing_blending(void)
12124 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12125 IDirectDrawSurface4
*offscreen
, *ds
;
12126 D3DDEVICEDESC hal_desc
, hel_desc
;
12127 IDirect3DViewport3
*viewport
;
12128 DDSURFACEDESC2 surface_desc
;
12129 IDirect3DDevice3
*device
;
12130 IDirectDraw4
*ddraw
;
12137 static D3DMATRIX mat
=
12139 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12140 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12141 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12142 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12146 struct vec3 position
;
12151 {{-1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12152 {{-1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12153 {{ 1.0f
, -1.0f
, 0.1f
}, 0x7f00ff00},
12154 {{ 1.0f
, 1.0f
, 0.1f
}, 0x7f00ff00},
12158 struct vec3 position
;
12163 {{-1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12164 {{-1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12165 {{ 1.0f
, -1.0f
, 0.1f
}, 0xccff0000},
12166 {{ 1.0f
, 1.0f
, 0.1f
}, 0xccff0000},
12169 window
= create_window();
12170 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12172 skip("Failed to create a 3D device.\n");
12173 DestroyWindow(window
);
12177 memset(&hal_desc
, 0, sizeof(hal_desc
));
12178 hal_desc
.dwSize
= sizeof(hal_desc
);
12179 memset(&hel_desc
, 0, sizeof(hel_desc
));
12180 hel_desc
.dwSize
= sizeof(hel_desc
);
12181 hr
= IDirect3DDevice3_GetCaps(device
, &hal_desc
, &hel_desc
);
12182 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#x.\n", hr
);
12183 trace("HAL line edge antialiasing support: %#x.\n",
12184 hal_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12185 trace("HAL triangle edge antialiasing support: %#x.\n",
12186 hal_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12187 trace("HEL line edge antialiasing support: %#x.\n",
12188 hel_desc
.dpcLineCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12189 trace("HEL triangle edge antialiasing support: %#x.\n",
12190 hel_desc
.dpcTriCaps
.dwRasterCaps
& D3DPRASTERCAPS_ANTIALIASEDGES
);
12192 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
12193 ok(SUCCEEDED(hr
), "Failed to get D3D interface, hr %#x.\n", hr
);
12194 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
12195 ok(SUCCEEDED(hr
), "Failed to get DirectDraw4 interface, hr %#x.\n", hr
);
12196 IDirect3D3_Release(d3d
);
12198 memset(&surface_desc
, 0, sizeof(surface_desc
));
12199 surface_desc
.dwSize
= sizeof(surface_desc
);
12200 surface_desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
;
12201 surface_desc
.dwWidth
= 640;
12202 surface_desc
.dwHeight
= 480;
12203 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
| DDSCAPS_3DDEVICE
;
12204 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
12205 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
= 32;
12206 U2(U4(surface_desc
).ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
12207 U3(U4(surface_desc
).ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
12208 U4(U4(surface_desc
).ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
12209 U5(U4(surface_desc
).ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
12210 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &offscreen
, NULL
);
12211 ok(hr
== D3D_OK
, "Creating the offscreen render target failed, hr %#x.\n", hr
);
12213 ds
= get_depth_stencil(device
);
12214 hr
= IDirectDrawSurface_AddAttachedSurface(offscreen
, ds
);
12215 todo_wine
ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
12216 IDirectDrawSurface_Release(ds
);
12218 hr
= IDirect3DDevice3_SetRenderTarget(device
, offscreen
, 0);
12219 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
12221 viewport
= create_viewport(device
, 0, 0, 640, 480);
12222 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12223 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
12225 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat
);
12226 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12227 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat
);
12228 ok(SUCCEEDED(hr
), "Failed to set view transform, hr %#x.\n", hr
);
12229 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat
);
12230 ok(SUCCEEDED(hr
), "Failed to set projection transform, hr %#x.\n", hr
);
12231 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CLIPPING
, FALSE
);
12232 ok(SUCCEEDED(hr
), "Failed to disable clipping, hr %#x.\n", hr
);
12233 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ZENABLE
, FALSE
);
12234 ok(SUCCEEDED(hr
), "Failed to disable Z test, hr %#x.\n", hr
);
12235 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_FOGENABLE
, FALSE
);
12236 ok(SUCCEEDED(hr
), "Failed to disable fog, hr %#x.\n", hr
);
12237 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_STENCILENABLE
, FALSE
);
12238 ok(SUCCEEDED(hr
), "Failed to disable stencil test, hr %#x.\n", hr
);
12239 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_CULLMODE
, D3DCULL_NONE
);
12240 ok(SUCCEEDED(hr
), "Failed to disable culling, hr %#x.\n", hr
);
12241 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
12242 ok(SUCCEEDED(hr
), "Failed to disable lighting, hr %#x.\n", hr
);
12244 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, TRUE
);
12245 ok(SUCCEEDED(hr
), "Failed to enable blending, hr %#x.\n", hr
);
12246 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
12247 ok(SUCCEEDED(hr
), "Failed to set src blend, hr %#x.\n", hr
);
12248 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_DESTALPHA
);
12249 ok(SUCCEEDED(hr
), "Failed to set dest blend, hr %#x.\n", hr
);
12251 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLOROP
, D3DTOP_SELECTARG1
);
12252 ok(SUCCEEDED(hr
), "Failed to set color op, hr %#x.\n", hr
);
12253 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_COLORARG1
, D3DTA_DIFFUSE
);
12254 ok(SUCCEEDED(hr
), "Failed to set color arg, hr %#x.\n", hr
);
12255 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAOP
, D3DTOP_SELECTARG1
);
12256 ok(SUCCEEDED(hr
), "Failed to set alpha op, hr %#x.\n", hr
);
12257 hr
= IDirect3DDevice3_SetTextureStageState(device
, 0, D3DTSS_ALPHAARG1
, D3DTA_DIFFUSE
);
12258 ok(SUCCEEDED(hr
), "Failed to set alpha arg, hr %#x.\n", hr
);
12260 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12261 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12262 hr
= IDirect3DDevice3_BeginScene(device
);
12263 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12264 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12266 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12267 hr
= IDirect3DDevice3_EndScene(device
);
12268 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12269 color
= get_surface_color(offscreen
, 320, 240);
12270 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12272 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12273 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12274 hr
= IDirect3DDevice3_BeginScene(device
);
12275 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12276 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12278 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12279 hr
= IDirect3DDevice3_EndScene(device
);
12280 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12281 color
= get_surface_color(offscreen
, 320, 240);
12282 ok(compare_color(color
, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color
);
12284 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_ALPHABLENDENABLE
, FALSE
);
12285 ok(SUCCEEDED(hr
), "Failed to disable blending, hr %#x.\n", hr
);
12287 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12288 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12289 hr
= IDirect3DDevice3_BeginScene(device
);
12290 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12291 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12293 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12294 hr
= IDirect3DDevice3_EndScene(device
);
12295 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12296 color
= get_surface_color(offscreen
, 320, 240);
12297 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12299 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12300 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12301 hr
= IDirect3DDevice3_BeginScene(device
);
12302 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12303 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12305 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12306 hr
= IDirect3DDevice3_EndScene(device
);
12307 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12308 color
= get_surface_color(offscreen
, 320, 240);
12309 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12311 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_EDGEANTIALIAS
, TRUE
);
12312 ok(SUCCEEDED(hr
), "Failed to enable edge antialiasing, hr %#x.\n", hr
);
12314 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xccff0000, 0.0f
, 0);
12315 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12316 hr
= IDirect3DDevice3_BeginScene(device
);
12317 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12318 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12320 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12321 hr
= IDirect3DDevice3_EndScene(device
);
12322 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12323 color
= get_surface_color(offscreen
, 320, 240);
12324 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12326 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x7f00ff00, 0.0f
, 0);
12327 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12328 hr
= IDirect3DDevice3_BeginScene(device
);
12329 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12330 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12332 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12333 hr
= IDirect3DDevice3_EndScene(device
);
12334 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12335 color
= get_surface_color(offscreen
, 320, 240);
12336 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12338 IDirectDrawSurface4_Release(offscreen
);
12339 IDirectDraw3_Release(ddraw
);
12340 destroy_viewport(device
, viewport
);
12341 refcount
= IDirect3DDevice3_Release(device
);
12342 ok(!refcount
, "Device has %u references left.\n", refcount
);
12343 DestroyWindow(window
);
12346 /* TransformVertices always writes 32 bytes regardless of the input / output stride.
12347 * The stride is honored for navigating to the next vertex. 3 floats input position
12348 * are read, and 16 bytes extra vertex data are copied around. */
12349 struct transform_input
12351 float x
, y
, z
, unused1
; /* Position data, transformed. */
12352 DWORD v1
, v2
, v3
, v4
; /* Extra data, e.g. color and texture coords, copied. */
12356 struct transform_output
12359 DWORD v1
, v2
, v3
, v4
;
12360 DWORD unused3
, unused4
;
12363 static void test_transform_vertices(void)
12365 IDirect3DDevice3
*device
;
12366 IDirectDrawSurface4
*rt
;
12371 IDirect3DViewport3
*viewport
;
12372 static struct transform_input position_tests
[] =
12374 { 0.0f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12375 { 1.0f
, 1.0f
, 1.0f
, 8.0f
, 6, 7, 8, 9, 10},
12376 {-1.0f
, -1.0f
, -1.0f
, 4.0f
, 11, 12, 13, 14, 15},
12377 { 0.5f
, 0.5f
, 0.5f
, 2.0f
, 16, 17, 18, 19, 20},
12378 {-0.5f
, -0.5f
, -0.5f
, 1.0f
, ~1U, ~2U, ~3U, ~4U, ~5U},
12379 {-0.5f
, -0.5f
, 0.0f
, 0.0f
, ~6U, ~7U, ~8U, ~9U, ~0U},
12381 static struct transform_input cliptest
[] =
12383 { 25.59f
, 25.59f
, 1.0f
, 0.0f
, 1, 2, 3, 4, 5},
12384 { 25.61f
, 25.61f
, 1.01f
, 0.0f
, 1, 2, 3, 4, 5},
12385 {-25.59f
, -25.59f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12386 {-25.61f
, -25.61f
, -0.01f
, 0.0f
, 1, 2, 3, 4, 5},
12388 static struct transform_input offscreentest
[] =
12390 {128.1f
, 0.0f
, 0.0f
, 0.0f
, 1, 2, 3, 4, 5},
12392 struct transform_output out
[ARRAY_SIZE(position_tests
)];
12393 D3DHVERTEX out_h
[ARRAY_SIZE(position_tests
)];
12394 D3DTRANSFORMDATA transformdata
;
12395 static const D3DVIEWPORT vp_template
=
12397 sizeof(vp_template
), 0, 0, 256, 256, 5.0f
, 5.0f
, 256.0f
, 256.0f
, -25.0f
, 60.0f
12399 D3DVIEWPORT vp_data
=
12401 sizeof(vp_data
), 0, 0, 256, 256, 1.0f
, 1.0f
, 256.0f
, 256.0f
, 0.0f
, 1.0f
12403 D3DVIEWPORT2 vp2_data
;
12406 static D3DMATRIX mat_scale
=
12408 2.0f
, 0.0f
, 0.0f
, 0.0f
,
12409 0.0f
, 2.0f
, 0.0f
, 0.0f
,
12410 0.0f
, 0.0f
, 2.0f
, 0.0f
,
12411 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12415 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12416 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12417 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12418 1.0f
, 0.0f
, 0.0f
, 1.0f
,
12422 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12423 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12424 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12425 0.0f
, 1.0f
, 0.0f
, 1.0f
,
12429 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12430 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12431 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12432 0.0f
, 19.2f
, 0.0f
, 2.0f
,
12436 1.0f
, 0.0f
, 0.0f
, 0.0f
,
12437 0.0f
, 1.0f
, 0.0f
, 0.0f
,
12438 0.0f
, 0.0f
, 1.0f
, 0.0f
,
12439 0.0f
, 0.0f
, 0.0f
, 1.0f
,
12443 struct vec3 position
;
12448 {{-0.75f
, -0.5f
, 0.0f
}, 0xffff0000},
12449 {{-0.75f
, 0.25f
, 0.0f
}, 0xffff0000},
12450 {{ 0.5f
, -0.5f
, 0.0f
}, 0xffff0000},
12451 {{ 0.5f
, 0.25f
, 0.0f
}, 0xffff0000},
12453 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
12455 for (i
= 0; i
< ARRAY_SIZE(out
); ++i
)
12457 out
[i
].unused3
= 0xdeadbeef;
12458 out
[i
].unused4
= 0xcafecafe;
12461 window
= create_window();
12462 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
12464 skip("Failed to create a 3D device.\n");
12465 DestroyWindow(window
);
12468 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
12469 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
12471 viewport
= create_viewport(device
, 0, 0, 256, 256);
12472 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12473 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12475 memset(&transformdata
, 0, sizeof(transformdata
));
12476 transformdata
.dwSize
= sizeof(transformdata
);
12477 transformdata
.lpIn
= position_tests
;
12478 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12479 transformdata
.lpOut
= out
;
12480 transformdata
.dwOutSize
= sizeof(out
[0]);
12481 transformdata
.lpHOut
= NULL
;
12483 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12484 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12485 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12486 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12488 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12490 static const struct vec4 cmp
[] =
12492 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {129.0f
, 127.0f
, 1.0f
, 1.0f
}, {127.0f
, 129.0f
, -1.0f
, 1.0f
},
12493 {128.5f
, 127.5f
, 0.5f
, 1.0f
}, {127.5f
, 128.5f
, -0.5f
, 1.0f
}, {127.5f
, 128.5f
, 0.0f
, 1.0f
}
12496 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12497 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12498 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12499 ok(out
[i
].v1
== position_tests
[i
].v1
&& out
[i
].v2
== position_tests
[i
].v2
12500 && out
[i
].v3
== position_tests
[i
].v3
&& out
[i
].v4
== position_tests
[i
].v4
,
12501 "Vertex %u payload is %u %u %u %u.\n", i
, out
[i
].v1
, out
[i
].v2
, out
[i
].v3
, out
[i
].v4
);
12502 ok(out
[i
].unused3
== 0xdeadbeef && out
[i
].unused4
== 0xcafecafe,
12503 "Vertex %u unused data is %#x, %#x.\n", i
, out
[i
].unused3
, out
[i
].unused4
);
12506 vp_data
= vp_template
;
12507 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12508 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12509 offscreen
= 0xdeadbeef;
12510 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12511 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12512 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12513 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12515 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12517 static const struct vec4 cmp
[] =
12519 {128.0f
, 128.0f
, 0.0f
, 1.0f
}, {133.0f
, 123.0f
, 1.0f
, 1.0f
}, {123.0f
, 133.0f
, -1.0f
, 1.0f
},
12520 {130.5f
, 125.5f
, 0.5f
, 1.0f
}, {125.5f
, 130.5f
, -0.5f
, 1.0f
}, {125.5f
, 130.5f
, 0.0f
, 1.0f
}
12522 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12523 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12524 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12529 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12530 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12531 offscreen
= 0xdeadbeef;
12532 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12533 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12534 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12535 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12536 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12538 static const struct vec4 cmp
[] =
12540 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, {133.0f
, 153.0f
, -1.0f
, 1.0f
},
12541 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, {135.5f
, 150.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12543 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12544 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12545 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12548 transformdata
.lpHOut
= out_h
;
12549 offscreen
= 0xdeadbeef;
12550 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12551 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12552 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12553 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12554 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12556 static const D3DHVERTEX cmp_h
[] =
12558 {0, { 0.0f
}, { 0.0f
}, { 0.0f
}}, {0, { 1.0f
}, { 1.0f
}, {1.0f
}},
12559 {D3DCLIP_FRONT
, {-1.0f
}, {-1.0f
}, {-1.0f
}}, {0, { 0.5f
}, { 0.5f
}, {0.5f
}},
12560 {D3DCLIP_FRONT
, {-0.5f
}, {-0.5f
}, {-0.5f
}}, {0, {-0.5f
}, {-0.5f
}, {0.0f
}}
12562 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12563 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12564 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12565 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12566 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12567 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12569 /* No scheme has been found behind those return values. It seems to be
12570 * whatever data windows has when throwing the vertex away. Modify the
12571 * input test vertices to test this more. Depending on the input data
12572 * it can happen that the z coord gets written into y, or similar things. */
12575 static const struct vec4 cmp
[] =
12577 {138.0f
, 148.0f
, 0.0f
, 1.0f
}, {143.0f
, 143.0f
, 1.0f
, 1.0f
}, { -1.0f
, -1.0f
, 0.5f
, 1.0f
},
12578 {140.5f
, 145.5f
, 0.5f
, 1.0f
}, { -0.5f
, -0.5f
, -0.5f
, 1.0f
}, {135.5f
, 150.5f
, 0.0f
, 1.0f
}
12580 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12581 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12582 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12586 transformdata
.lpIn
= cliptest
;
12587 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12588 offscreen
= 0xdeadbeef;
12589 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12590 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12591 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12592 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12593 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12595 static const DWORD flags
[] =
12598 D3DCLIP_RIGHT
| D3DCLIP_BACK
| D3DCLIP_TOP
,
12600 D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,
12602 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12605 vp_data
= vp_template
;
12606 vp_data
.dwWidth
= 10;
12607 vp_data
.dwHeight
= 480;
12608 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12609 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12610 offscreen
= 0xdeadbeef;
12611 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12612 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12613 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12614 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12615 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12617 static const DWORD flags
[] =
12620 D3DCLIP_RIGHT
| D3DCLIP_BACK
,
12622 D3DCLIP_LEFT
| D3DCLIP_FRONT
,
12624 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12627 vp_data
= vp_template
;
12628 vp_data
.dwWidth
= 256;
12629 vp_data
.dwHeight
= 256;
12630 vp_data
.dvScaleX
= 1;
12631 vp_data
.dvScaleY
= 1;
12632 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12633 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12634 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12635 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12636 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12637 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12638 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12640 static const DWORD flags
[] =
12647 ok(flags
[i
] == out_h
[i
].dwFlags
, "Cliptest %u returned %#x.\n", i
, out_h
[i
].dwFlags
);
12650 /* Finally try to figure out how the DWORD dwOffscreen works.
12651 * It is a logical AND of the vertices' dwFlags members. */
12652 vp_data
= vp_template
;
12653 vp_data
.dwWidth
= 5;
12654 vp_data
.dwHeight
= 5;
12655 vp_data
.dvScaleX
= 10000.0f
;
12656 vp_data
.dvScaleY
= 10000.0f
;
12657 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12658 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12659 transformdata
.lpIn
= cliptest
;
12660 offscreen
= 0xdeadbeef;
12661 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12662 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12663 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12664 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12666 offscreen
= 0xdeadbeef;
12667 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12668 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12669 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12670 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12671 offscreen
= 0xdeadbeef;
12672 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12673 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12674 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12675 ok(offscreen
== (D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12676 hr
= IDirect3DViewport2_TransformVertices(viewport
, 3,
12677 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12678 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12679 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12681 transformdata
.lpIn
= cliptest
+ 1;
12682 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12683 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12684 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12685 ok(offscreen
== (D3DCLIP_BACK
| D3DCLIP_RIGHT
| D3DCLIP_TOP
), "Offscreen is %x.\n", offscreen
);
12687 transformdata
.lpIn
= cliptest
+ 2;
12688 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12689 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12690 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12691 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12692 offscreen
= 0xdeadbeef;
12693 hr
= IDirect3DViewport2_TransformVertices(viewport
, 2,
12694 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12695 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12696 ok(offscreen
== (D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12698 transformdata
.lpIn
= cliptest
+ 3;
12699 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12700 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12701 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12702 ok(offscreen
== (D3DCLIP_FRONT
| D3DCLIP_BOTTOM
| D3DCLIP_LEFT
), "Offscreen is %x.\n", offscreen
);
12704 transformdata
.lpIn
= offscreentest
;
12705 transformdata
.dwInSize
= sizeof(offscreentest
[0]);
12706 vp_data
= vp_template
;
12707 vp_data
.dwWidth
= 257;
12708 vp_data
.dwHeight
= 257;
12709 vp_data
.dvScaleX
= 1.0f
;
12710 vp_data
.dvScaleY
= 1.0f
;
12711 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12712 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12713 offscreen
= 0xdeadbeef;
12714 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12715 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12716 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12717 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12719 vp_data
.dwWidth
= 256;
12720 vp_data
.dwHeight
= 256;
12721 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12722 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12723 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12724 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12725 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12726 ok(offscreen
== D3DCLIP_RIGHT
, "Offscreen is %x.\n", offscreen
);
12728 /* Test the effect of Matrices.
12730 * Basically the x coordinate ends up as ((x + 1) * 2 + 0) * 5 and
12731 * y as ((y + 0) * 2 + 1) * 5. The 5 comes from dvScaleX/Y, 2 from
12732 * the view matrix and the +1's from the world and projection matrix. */
12735 vp_data
.dwWidth
= 256;
12736 vp_data
.dwHeight
= 256;
12737 vp_data
.dvScaleX
= 5.0f
;
12738 vp_data
.dvScaleY
= 5.0f
;
12739 vp_data
.dvMinZ
= 0.0f
;
12740 vp_data
.dvMaxZ
= 1.0f
;
12741 hr
= IDirect3DViewport2_SetViewport(viewport
, &vp_data
);
12742 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12744 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_translate1
);
12745 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12746 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_scale
);
12747 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12748 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_translate2
);
12749 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12751 transformdata
.lpIn
= position_tests
;
12752 transformdata
.dwInSize
= sizeof(position_tests
[0]);
12753 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12754 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12755 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12757 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12759 static const struct vec4 cmp
[] =
12761 {138.0f
, 123.0f
, 0.0f
, 1.0f
}, {148.0f
, 113.0f
, 2.0f
, 1.0f
}, {128.0f
, 133.0f
, -2.0f
, 1.0f
},
12762 {143.0f
, 118.0f
, 1.0f
, 1.0f
}, {133.0f
, 128.0f
, -1.0f
, 1.0f
}, {133.0f
, 128.0f
, 0.0f
, 1.0f
}
12765 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12766 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12767 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12770 /* Invalid flags. */
12771 offscreen
= 0xdeadbeef;
12772 hr
= IDirect3DViewport2_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12773 &transformdata
, 0, &offscreen
);
12774 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12775 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12777 /* NULL transform data. */
12778 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12779 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12780 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12781 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12782 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12783 NULL
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12784 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12785 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12787 /* NULL transform data and NULL dwOffscreen.
12789 * Valid transform data + NULL dwOffscreen -> crash. */
12790 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12791 NULL
, D3DTRANSFORM_UNCLIPPED
, NULL
);
12792 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12795 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12796 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12797 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12798 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12799 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12800 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12801 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12802 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12804 /* Invalid sizes. */
12805 offscreen
= 0xdeadbeef;
12806 transformdata
.dwSize
= sizeof(transformdata
) - 1;
12807 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12808 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12809 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12810 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12811 transformdata
.dwSize
= sizeof(transformdata
) + 1;
12812 hr
= IDirect3DViewport2_TransformVertices(viewport
, 1,
12813 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12814 ok(hr
== DDERR_INVALIDPARAMS
, "TransformVertices returned %#x.\n", hr
);
12815 ok(offscreen
== 0xdeadbeef, "Offscreen is %x.\n", offscreen
);
12817 /* NULL lpIn or lpOut -> crash, except when transforming 0 vertices. */
12818 transformdata
.dwSize
= sizeof(transformdata
);
12819 transformdata
.lpIn
= NULL
;
12820 transformdata
.lpOut
= NULL
;
12821 offscreen
= 0xdeadbeef;
12822 hr
= IDirect3DViewport2_TransformVertices(viewport
, 0,
12823 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12824 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12825 ok(offscreen
== ~0U, "Offscreen is %x.\n", offscreen
);
12827 /* Test how vertices are transformed during draws. */
12830 vp_data
.dwWidth
= 200;
12831 vp_data
.dwHeight
= 400;
12832 vp_data
.dvScaleX
= 20.0f
;
12833 vp_data
.dvScaleY
= 50.0f
;
12834 vp_data
.dvMinZ
= 0.0f
;
12835 vp_data
.dvMaxZ
= 1.0f
;
12836 hr
= IDirect3DViewport3_SetViewport(viewport
, &vp_data
);
12837 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#x.\n", hr
);
12838 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
12839 ok(SUCCEEDED(hr
), "Failed to activate the viewport, hr %#x.\n", hr
);
12841 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x000000ff, 0.0f
, 0);
12842 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12844 hr
= IDirect3DDevice3_BeginScene(device
);
12845 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12846 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12848 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12849 hr
= IDirect3DDevice3_EndScene(device
);
12850 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12852 color
= get_surface_color(rt
, 128, 143);
12853 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12854 color
= get_surface_color(rt
, 132, 143);
12855 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12856 color
= get_surface_color(rt
, 128, 147);
12857 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12858 color
= get_surface_color(rt
, 132, 147);
12859 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12861 color
= get_surface_color(rt
, 177, 217);
12862 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12863 color
= get_surface_color(rt
, 181, 217);
12864 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12865 color
= get_surface_color(rt
, 177, 221);
12866 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12867 color
= get_surface_color(rt
, 181, 221);
12868 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
12870 /* Test D3DVIEWPORT2 behavior. */
12871 vp2_data
.dwSize
= sizeof(vp2_data
);
12874 vp2_data
.dwWidth
= 200;
12875 vp2_data
.dwHeight
= 400;
12876 vp2_data
.dvClipX
= -0.5f
;
12877 vp2_data
.dvClipY
= 4.0f
;
12878 vp2_data
.dvClipWidth
= 5.0f
;
12879 vp2_data
.dvClipHeight
= 10.0f
;
12880 vp2_data
.dvMinZ
= 0.0f
;
12881 vp2_data
.dvMaxZ
= 2.0f
;
12882 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
12883 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12884 transformdata
.lpIn
= position_tests
;
12885 transformdata
.lpOut
= out
;
12886 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(position_tests
),
12887 &transformdata
, D3DTRANSFORM_UNCLIPPED
, &offscreen
);
12888 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12889 for (i
= 0; i
< ARRAY_SIZE(position_tests
); ++i
)
12891 static const struct vec4 cmp
[] =
12893 {120.0f
, 140.0f
, 0.0f
, 1.0f
}, {200.0f
, 60.0f
, 1.0f
, 1.0f
}, {40.0f
, 220.0f
, -1.0f
, 1.0f
},
12894 {160.0f
, 100.0f
, 0.5f
, 1.0f
}, { 80.0f
, 180.0f
, -0.5f
, 1.0f
}, {80.0f
, 180.0f
, 0.0f
, 1.0f
}
12897 ok(compare_vec4(&cmp
[i
], out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
, 4096),
12898 "Vertex %u differs. Got %f %f %f %f.\n", i
,
12899 out
[i
].x
, out
[i
].y
, out
[i
].z
, out
[i
].w
);
12902 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0x0000ff00, 0.0f
, 0);
12903 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
12905 hr
= IDirect3DDevice3_BeginScene(device
);
12906 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
12907 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
,
12909 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
12910 hr
= IDirect3DDevice3_EndScene(device
);
12911 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
12913 color
= get_surface_color(rt
, 58, 118);
12914 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12915 color
= get_surface_color(rt
, 62, 118);
12916 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12917 color
= get_surface_color(rt
, 58, 122);
12918 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12919 color
= get_surface_color(rt
, 62, 122);
12920 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12922 color
= get_surface_color(rt
, 157, 177);
12923 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
12924 color
= get_surface_color(rt
, 161, 177);
12925 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12926 color
= get_surface_color(rt
, 157, 181);
12927 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12928 color
= get_surface_color(rt
, 161, 181);
12929 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
12931 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &mat_identity
);
12932 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12933 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, &mat_identity
);
12934 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12935 hr
= IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, &mat_transform3
);
12936 ok(SUCCEEDED(hr
), "Failed to set world transform, hr %#x.\n", hr
);
12938 vp2_data
.dwX
= 0.0;
12939 vp2_data
.dwY
= 0.0;
12940 vp2_data
.dwWidth
= 1;
12941 vp2_data
.dwHeight
= 1;
12942 vp2_data
.dvClipX
= -12.8f
;
12943 vp2_data
.dvClipY
= 12.8f
+ mat_transform3
._42
/ mat_transform3
._44
;
12944 vp2_data
.dvClipWidth
= 25.6f
;
12945 vp2_data
.dvClipHeight
= 25.6f
;
12946 vp2_data
.dvMinZ
= 0.0f
;
12947 vp2_data
.dvMaxZ
= 0.5f
;
12948 hr
= IDirect3DViewport3_SetViewport2(viewport
, &vp2_data
);
12949 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
12950 transformdata
.lpIn
= cliptest
;
12951 transformdata
.dwInSize
= sizeof(cliptest
[0]);
12952 offscreen
= 0xdeadbeef;
12953 hr
= IDirect3DViewport3_TransformVertices(viewport
, ARRAY_SIZE(cliptest
),
12954 &transformdata
, D3DTRANSFORM_CLIPPED
, &offscreen
);
12955 ok(SUCCEEDED(hr
), "Failed to transform vertices, hr %#x.\n", hr
);
12956 ok(!offscreen
, "Offscreen is %x.\n", offscreen
);
12957 for (i
= 0; i
< ARRAY_SIZE(cliptest
); ++i
)
12959 static const D3DHVERTEX cmp_h
[] =
12961 {0, { 25.59f
}, { 44.79f
}, { 1.0f
}},
12962 {D3DCLIP_RIGHT
| D3DCLIP_TOP
| D3DCLIP_BACK
, { 25.61f
}, { 44.81f
}, { 1.01f
}},
12963 {0, {-25.59f
}, {-6.39f
}, { 0.0f
}},
12964 {D3DCLIP_LEFT
| D3DCLIP_BOTTOM
| D3DCLIP_FRONT
,{-25.61f
}, {-6.41f
}, {-0.01f
}},
12966 ok(compare_float(U1(cmp_h
[i
]).hx
, U1(out_h
[i
]).hx
, 4096)
12967 && compare_float(U2(cmp_h
[i
]).hy
, U2(out_h
[i
]).hy
, 4096)
12968 && compare_float(U3(cmp_h
[i
]).hz
, U3(out_h
[i
]).hz
, 4096)
12969 && cmp_h
[i
].dwFlags
== out_h
[i
].dwFlags
,
12970 "HVertex %u differs. Got %#x %f %f %f.\n", i
,
12971 out_h
[i
].dwFlags
, U1(out_h
[i
]).hx
, U2(out_h
[i
]).hy
, U3(out_h
[i
]).hz
);
12974 destroy_viewport(device
, viewport
);
12975 IDirectDrawSurface4_Release(rt
);
12976 refcount
= IDirect3DDevice3_Release(device
);
12977 ok(!refcount
, "Device has %u references left.\n", refcount
);
12978 DestroyWindow(window
);
12981 static void test_display_mode_surface_pixel_format(void)
12983 unsigned int width
, height
, bpp
;
12984 IDirectDrawSurface4
*surface
;
12985 DDSURFACEDESC2 surface_desc
;
12986 IDirectDraw4
*ddraw
;
12991 if (!(ddraw
= create_ddraw()))
12993 skip("Failed to create ddraw.\n");
12997 surface_desc
.dwSize
= sizeof(surface_desc
);
12998 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
12999 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13000 width
= surface_desc
.dwWidth
;
13001 height
= surface_desc
.dwHeight
;
13003 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
13004 0, 0, width
, height
, NULL
, NULL
, NULL
, NULL
);
13005 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
13006 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13009 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 16, 0, 0)))
13011 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 24, 0, 0)))
13013 if (SUCCEEDED(IDirectDraw4_SetDisplayMode(ddraw
, width
, height
, 32, 0, 0)))
13015 ok(bpp
, "Set display mode failed.\n");
13017 surface_desc
.dwSize
= sizeof(surface_desc
);
13018 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &surface_desc
);
13019 ok(SUCCEEDED(hr
), "Failed to get display mode, hr %#x.\n", hr
);
13020 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13021 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13022 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13023 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13025 memset(&surface_desc
, 0, sizeof(surface_desc
));
13026 surface_desc
.dwSize
= sizeof(surface_desc
);
13027 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_BACKBUFFERCOUNT
;
13028 U5(surface_desc
).dwBackBufferCount
= 1;
13029 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_COMPLEX
| DDSCAPS_FLIP
| DDSCAPS_PRIMARYSURFACE
;
13030 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13031 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13032 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13033 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13034 ok(surface_desc
.dwWidth
== width
, "Got width %u, expected %u.\n", surface_desc
.dwWidth
, width
);
13035 ok(surface_desc
.dwHeight
== height
, "Got height %u, expected %u.\n", surface_desc
.dwHeight
, height
);
13036 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13037 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13038 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13039 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13040 IDirectDrawSurface4_Release(surface
);
13042 memset(&surface_desc
, 0, sizeof(surface_desc
));
13043 surface_desc
.dwSize
= sizeof(surface_desc
);
13044 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13045 surface_desc
.dwWidth
= width
;
13046 surface_desc
.dwHeight
= height
;
13047 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13048 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13049 ok(hr
== D3D_OK
, "Failed to create surface, hr %#x.\n", hr
);
13050 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface
, &surface_desc
);
13051 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13052 ok(U4(surface_desc
).ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got unexpected pixel format flags %#x.\n",
13053 U4(surface_desc
).ddpfPixelFormat
.dwFlags
);
13054 ok(U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
== bpp
, "Got bpp %u, expected %u.\n",
13055 U1(U4(surface_desc
).ddpfPixelFormat
).dwRGBBitCount
, bpp
);
13056 IDirectDrawSurface4_Release(surface
);
13058 refcount
= IDirectDraw4_Release(ddraw
);
13059 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13060 DestroyWindow(window
);
13063 static void test_surface_desc_size(void)
13068 DDSURFACEDESC desc1
;
13069 DDSURFACEDESC2 desc2
;
13072 IDirectDrawSurface4
*surface4
;
13073 IDirectDrawSurface3
*surface3
;
13074 IDirectDrawSurface
*surface
;
13075 DDSURFACEDESC2 surface_desc
;
13076 HRESULT expected_hr
, hr
;
13077 IDirectDraw4
*ddraw
;
13081 static const struct
13088 {DDSCAPS_OFFSCREENPLAIN
, "offscreenplain"},
13089 {DDSCAPS_TEXTURE
| DDSCAPS_SYSTEMMEMORY
, "systemmemory texture"},
13090 {DDSCAPS_TEXTURE
| DDSCAPS_VIDEOMEMORY
, "videomemory texture"},
13092 static const unsigned int desc_sizes
[] =
13094 sizeof(DDSURFACEDESC
),
13095 sizeof(DDSURFACEDESC2
),
13096 sizeof(DDSURFACEDESC
) + 1,
13097 sizeof(DDSURFACEDESC2
) + 1,
13098 2 * sizeof(DDSURFACEDESC
),
13099 2 * sizeof(DDSURFACEDESC2
),
13100 sizeof(DDSURFACEDESC
) - 1,
13101 sizeof(DDSURFACEDESC2
) - 1,
13102 sizeof(DDSURFACEDESC
) / 2,
13103 sizeof(DDSURFACEDESC2
) / 2,
13108 sizeof(desc
) - 100,
13111 if (!(ddraw
= create_ddraw()))
13113 skip("Failed to create ddraw.\n");
13116 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
13117 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13119 for (i
= 0; i
< ARRAY_SIZE(surface_caps
); ++i
)
13121 memset(&surface_desc
, 0, sizeof(surface_desc
));
13122 surface_desc
.dwSize
= sizeof(surface_desc
);
13123 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_HEIGHT
| DDSD_WIDTH
;
13124 surface_desc
.ddsCaps
.dwCaps
= surface_caps
[i
].caps
;
13125 surface_desc
.dwHeight
= 128;
13126 surface_desc
.dwWidth
= 128;
13127 if (FAILED(IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface4
, NULL
)))
13129 skip("Failed to create surface, type %s.\n", surface_caps
[i
].name
);
13132 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface
, (void **)&surface
);
13133 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13134 hr
= IDirectDrawSurface_QueryInterface(surface4
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
13135 ok(hr
== DD_OK
, "Failed to query IDirectDrawSurface3, hr %#x, type %s.\n", hr
, surface_caps
[i
].name
);
13137 /* GetSurfaceDesc() */
13138 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13140 memset(&desc
, 0, sizeof(desc
));
13141 desc
.dwSize
= desc_sizes
[j
];
13142 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13143 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
.desc1
);
13144 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13145 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13147 memset(&desc
, 0, sizeof(desc
));
13148 desc
.dwSize
= desc_sizes
[j
];
13149 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13150 hr
= IDirectDrawSurface3_GetSurfaceDesc(surface3
, &desc
.desc1
);
13151 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13152 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13154 memset(&desc
, 0, sizeof(desc
));
13155 desc
.dwSize
= desc_sizes
[j
];
13156 expected_hr
= desc
.dwSize
== sizeof(DDSURFACEDESC2
) ? DD_OK
: DDERR_INVALIDPARAMS
;
13157 hr
= IDirectDrawSurface4_GetSurfaceDesc(surface4
, &desc
.desc2
);
13158 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13159 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13163 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13165 const BOOL valid_size
= desc_sizes
[j
] == sizeof(DDSURFACEDESC
)
13166 || desc_sizes
[j
] == sizeof(DDSURFACEDESC2
);
13167 DWORD expected_texture_stage
;
13169 memset(&desc
, 0, sizeof(desc
));
13170 desc
.dwSize
= desc_sizes
[j
];
13171 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13172 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13173 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
.desc1
, 0, 0);
13174 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13175 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13176 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13177 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13178 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13179 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13180 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13183 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13184 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13185 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13186 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13187 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13188 todo_wine_if(!expected_texture_stage
)
13189 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13190 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13191 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13192 IDirectDrawSurface_Unlock(surface
, NULL
);
13195 memset(&desc
, 0, sizeof(desc
));
13196 desc
.dwSize
= desc_sizes
[j
];
13197 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13198 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13199 hr
= IDirectDrawSurface3_Lock(surface3
, NULL
, &desc
.desc1
, 0, 0);
13200 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13201 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13202 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13203 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13204 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13205 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13206 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13209 ok(desc
.desc1
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13210 desc
.desc1
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13211 ok(desc
.desc1
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13212 desc
.desc1
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13213 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13214 todo_wine_if(!expected_texture_stage
)
13215 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13216 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13217 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13218 IDirectDrawSurface3_Unlock(surface3
, NULL
);
13221 memset(&desc
, 0, sizeof(desc
));
13222 desc
.dwSize
= desc_sizes
[j
];
13223 desc
.desc2
.dwTextureStage
= 0xdeadbeef;
13224 desc
.blob
[sizeof(DDSURFACEDESC2
)] = 0xef;
13225 hr
= IDirectDrawSurface4_Lock(surface4
, NULL
, &desc
.desc2
, 0, 0);
13226 expected_hr
= valid_size
? DD_OK
: DDERR_INVALIDPARAMS
;
13227 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, dwSize %u, type %s.\n",
13228 hr
, expected_hr
, desc_sizes
[j
], surface_caps
[i
].name
);
13229 ok(desc
.dwSize
== desc_sizes
[j
], "dwSize was changed from %u to %u, type %s.\n",
13230 desc_sizes
[j
], desc
.dwSize
, surface_caps
[i
].name
);
13231 ok(desc
.blob
[sizeof(DDSURFACEDESC2
)] == 0xef, "Got unexpected byte %02x, dwSize %u, type %s.\n",
13232 desc
.blob
[sizeof(DDSURFACEDESC2
)], desc_sizes
[j
], surface_caps
[i
].name
);
13235 ok(desc
.desc2
.dwWidth
== 128, "Got unexpected width %u, dwSize %u, type %s.\n",
13236 desc
.desc2
.dwWidth
, desc_sizes
[j
], surface_caps
[i
].name
);
13237 ok(desc
.desc2
.dwHeight
== 128, "Got unexpected height %u, dwSize %u, type %s.\n",
13238 desc
.desc2
.dwHeight
, desc_sizes
[j
], surface_caps
[i
].name
);
13239 expected_texture_stage
= desc_sizes
[j
] >= sizeof(DDSURFACEDESC2
) ? 0 : 0xdeadbeef;
13240 ok(desc
.desc2
.dwTextureStage
== expected_texture_stage
,
13241 "Got unexpected texture stage %#x, dwSize %u, type %s.\n",
13242 desc
.desc2
.dwTextureStage
, desc_sizes
[j
], surface_caps
[i
].name
);
13243 IDirectDrawSurface4_Unlock(surface4
, NULL
);
13247 IDirectDrawSurface4_Release(surface4
);
13248 IDirectDrawSurface3_Release(surface3
);
13249 IDirectDrawSurface_Release(surface
);
13252 /* GetDisplayMode() */
13253 for (j
= 0; j
< ARRAY_SIZE(desc_sizes
); ++j
)
13255 memset(&desc
, 0xcc, sizeof(desc
));
13256 desc
.dwSize
= desc_sizes
[j
];
13257 expected_hr
= (desc
.dwSize
== sizeof(DDSURFACEDESC
) || desc
.dwSize
== sizeof(DDSURFACEDESC2
))
13258 ? DD_OK
: DDERR_INVALIDPARAMS
;
13259 hr
= IDirectDraw4_GetDisplayMode(ddraw
, &desc
.desc2
);
13260 ok(hr
== expected_hr
, "Got hr %#x, expected %#x, size %u.\n", hr
, expected_hr
, desc_sizes
[j
]);
13263 ok(desc
.dwSize
== sizeof(DDSURFACEDESC2
), "Wrong size %u for %u.\n", desc
.dwSize
, desc_sizes
[j
]);
13264 ok(desc
.blob
[desc_sizes
[j
]] == 0xcc, "Overflow for size %u.\n", desc_sizes
[j
]);
13265 ok(desc
.blob
[desc_sizes
[j
] - 1] != 0xcc, "Struct not cleared for size %u.\n", desc_sizes
[j
]);
13269 refcount
= IDirectDraw4_Release(ddraw
);
13270 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13273 static void test_get_surface_from_dc(void)
13275 IDirectDrawSurface
*surface1
, *tmp
;
13276 IDirectDrawSurface4
*surface
;
13277 DDSURFACEDESC2 surface_desc
;
13278 IDirectDraw4
*ddraw
;
13285 window
= create_window();
13286 ddraw
= create_ddraw();
13287 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13288 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13289 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13291 memset(&surface_desc
, 0, sizeof(surface_desc
));
13292 surface_desc
.dwSize
= sizeof(surface_desc
);
13293 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
13294 surface_desc
.dwWidth
= 64;
13295 surface_desc
.dwHeight
= 64;
13296 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13298 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
13299 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13300 hr
= IDirectDrawSurface4_QueryInterface(surface
, &IID_IDirectDrawSurface
, (void **)&surface1
);
13301 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13303 refcount
= get_refcount((IUnknown
*)surface1
);
13304 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13305 refcount
= get_refcount((IUnknown
*)surface
);
13306 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13308 hr
= IDirectDrawSurface4_GetDC(surface
, &dc
);
13309 ok(SUCCEEDED(hr
), "Failed to get DC, hr %#x.\n", hr
);
13311 tmp
= (void *)0xdeadbeef;
13312 device_dc
= (void *)0xdeadbeef;
13313 hr
= GetSurfaceFromDC(NULL
, &tmp
, &device_dc
);
13314 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13315 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13316 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
13318 device_dc
= (void *)0xdeadbeef;
13319 hr
= GetSurfaceFromDC(dc
, NULL
, &device_dc
);
13320 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13321 ok(device_dc
== (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc
);
13323 tmp
= (void *)0xdeadbeef;
13324 hr
= GetSurfaceFromDC(dc
, &tmp
, NULL
);
13325 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13326 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13328 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
13329 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
13330 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
13331 IDirectDrawSurface_Release(tmp
);
13333 ret
= GetObjectType(device_dc
);
13334 todo_wine
ok(ret
== OBJ_DC
, "Got unexpected object type %#x.\n", ret
);
13335 ret
= GetDeviceCaps(device_dc
, TECHNOLOGY
);
13336 todo_wine
ok(ret
== DT_RASDISPLAY
, "Got unexpected technology %#x.\n", ret
);
13338 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, NULL
);
13339 ok(hr
== E_INVALIDARG
, "Got unexpected hr %#x.\n", hr
);
13341 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
13342 ok(SUCCEEDED(hr
), "GetSurfaceFromDC failed, hr %#x.\n", hr
);
13343 ok(tmp
== surface1
, "Got unexpected surface %p, expected %p.\n", tmp
, surface1
);
13345 refcount
= get_refcount((IUnknown
*)surface1
);
13346 ok(refcount
== 2, "Got unexpected refcount %u.\n", refcount
);
13347 refcount
= get_refcount((IUnknown
*)surface
);
13348 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
13350 hr
= IDirectDrawSurface4_ReleaseDC(surface
, dc
);
13351 ok(SUCCEEDED(hr
), "ReleaseDC failed, hr %#x.\n", hr
);
13353 IDirectDrawSurface_Release(tmp
);
13355 dc
= CreateCompatibleDC(NULL
);
13356 ok(!!dc
, "CreateCompatibleDC failed.\n");
13358 tmp
= (void *)0xdeadbeef;
13359 device_dc
= (void *)0xdeadbeef;
13360 hr
= GetSurfaceFromDC(dc
, &tmp
, &device_dc
);
13361 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13362 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13363 ok(!device_dc
, "Got unexpected device_dc %p.\n", device_dc
);
13365 tmp
= (void *)0xdeadbeef;
13366 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, dc
, (IDirectDrawSurface4
**)&tmp
);
13367 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13368 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13370 ok(DeleteDC(dc
), "DeleteDC failed.\n");
13372 tmp
= (void *)0xdeadbeef;
13373 hr
= IDirectDraw4_GetSurfaceFromDC(ddraw
, NULL
, (IDirectDrawSurface4
**)&tmp
);
13374 ok(hr
== DDERR_NOTFOUND
, "Got unexpected hr %#x.\n", hr
);
13375 ok(!tmp
, "Got unexpected surface %p.\n", tmp
);
13377 IDirectDrawSurface4_Release(surface
);
13378 IDirectDrawSurface_Release(surface1
);
13379 IDirectDraw4_Release(ddraw
);
13380 DestroyWindow(window
);
13383 static void test_ck_operation(void)
13385 IDirectDrawSurface4
*src
, *dst
;
13386 IDirectDrawSurface
*src1
, *dst1
;
13387 DDSURFACEDESC2 surface_desc
;
13388 IDirectDraw4
*ddraw
;
13397 window
= create_window();
13398 ddraw
= create_ddraw();
13399 ok(!!ddraw
, "Failed to create a ddraw object.\n");
13400 hr
= IDirectDraw4_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
13401 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
13403 memset(&surface_desc
, 0, sizeof(surface_desc
));
13404 surface_desc
.dwSize
= sizeof(surface_desc
);
13405 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13406 surface_desc
.dwWidth
= 4;
13407 surface_desc
.dwHeight
= 1;
13408 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13409 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
13410 U1(U4(surface_desc
.ddpfPixelFormat
)).dwRGBBitCount
= 32;
13411 U2(U4(surface_desc
.ddpfPixelFormat
)).dwRBitMask
= 0x00ff0000;
13412 U3(U4(surface_desc
.ddpfPixelFormat
)).dwGBitMask
= 0x0000ff00;
13413 U4(U4(surface_desc
.ddpfPixelFormat
)).dwBBitMask
= 0x000000ff;
13414 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
13415 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13417 surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
13418 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x00ff00ff;
13419 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x00ff00ff;
13420 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
13421 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13423 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13424 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13425 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13426 color
= surface_desc
.lpSurface
;
13427 color
[0] = 0x77010203;
13428 color
[1] = 0x00010203;
13429 color
[2] = 0x77ff00ff;
13430 color
[3] = 0x00ff00ff;
13431 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
13432 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13434 for (i
= 0; i
< 2; ++i
)
13436 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13437 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13438 color
= surface_desc
.lpSurface
;
13439 color
[0] = 0xcccccccc;
13440 color
[1] = 0xcccccccc;
13441 color
[2] = 0xcccccccc;
13442 color
[3] = 0xcccccccc;
13443 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13444 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13448 hr
= IDirectDrawSurface4_BltFast(dst
, 0, 0, src
, NULL
, DDBLTFAST_SRCCOLORKEY
);
13449 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13453 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, NULL
);
13454 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13457 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
| DDLOCK_READONLY
, NULL
);
13458 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13459 ok(!(surface_desc
.dwFlags
& DDSD_LPSURFACE
), "Surface desc has LPSURFACE Flags set.\n");
13460 color
= surface_desc
.lpSurface
;
13461 /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
13462 * color keying, but copy it to the destination surface. Others (sysmem surfaces) apply it for
13463 * color keying, but do not copy it into the destination surface. Nvidia neither uses it for
13464 * color keying nor copies it. */
13465 ok((color
[0] == 0x77010203 && color
[1] == 0x00010203
13466 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* AMD, Wine */
13467 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13468 && color
[2] == 0x00ff00ff && color
[3] == 0xcccccccc) /* Sysmem surfaces? */
13469 || broken(color
[0] == 0x00010203 && color
[1] == 0x00010203
13470 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Nvidia */
13471 || broken(color
[0] == 0xff010203 && color
[1] == 0xff010203
13472 && color
[2] == 0xcccccccc && color
[3] == 0xcccccccc) /* Testbot */,
13473 "Destination data after blitting is %08x %08x %08x %08x, i=%u.\n",
13474 color
[0], color
[1], color
[2], color
[3], i
);
13475 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13476 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13479 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13480 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13481 ok(ckey
.dwColorSpaceLowValue
== 0x00ff00ff && ckey
.dwColorSpaceHighValue
== 0x00ff00ff,
13482 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13484 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13485 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13486 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13488 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13489 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13490 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13491 ok(ckey
.dwColorSpaceLowValue
== 0x0000ff00 && ckey
.dwColorSpaceHighValue
== 0x0000ff00,
13492 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13494 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0;
13495 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0;
13496 hr
= IDirectDrawSurface4_GetSurfaceDesc(src
, &surface_desc
);
13497 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
13498 ok(surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0x0000ff00
13499 && surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0x0000ff00,
13500 "Got unexpected color key low=%08x high=%08x.\n", surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
,
13501 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
13503 /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
13504 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13505 ckey
.dwColorSpaceHighValue
= 0x00000000;
13506 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13507 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13509 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13510 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13511 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13512 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13513 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13515 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13516 ckey
.dwColorSpaceHighValue
= 0x00000001;
13517 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13518 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13520 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13521 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13522 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13523 ok(ckey
.dwColorSpaceLowValue
== 0x000000ff && ckey
.dwColorSpaceHighValue
== 0x000000ff,
13524 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13526 ckey
.dwColorSpaceLowValue
= 0x000000fe;
13527 ckey
.dwColorSpaceHighValue
= 0x000000fd;
13528 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13529 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13531 ckey
.dwColorSpaceLowValue
= ckey
.dwColorSpaceHighValue
= 0;
13532 hr
= IDirectDrawSurface4_GetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13533 ok(SUCCEEDED(hr
), "Failed to get color key, hr %#x.\n", hr
);
13534 ok(ckey
.dwColorSpaceLowValue
== 0x000000fe && ckey
.dwColorSpaceHighValue
== 0x000000fe,
13535 "Got unexpected color key low=%08x high=%08x.\n", ckey
.dwColorSpaceLowValue
, ckey
.dwColorSpaceHighValue
);
13537 IDirectDrawSurface4_Release(src
);
13538 IDirectDrawSurface4_Release(dst
);
13540 /* Test source and destination keys and where they are read from. Use a surface with alpha
13541 * to avoid driver-dependent content in the X channel. */
13542 memset(&surface_desc
, 0, sizeof(surface_desc
));
13543 surface_desc
.dwSize
= sizeof(surface_desc
);
13544 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
13545 surface_desc
.dwWidth
= 6;
13546 surface_desc
.dwHeight
= 1;
13547 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
13548 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
13549 U1(U4(surface_desc
.ddpfPixelFormat
)).dwRGBBitCount
= 32;
13550 U2(U4(surface_desc
.ddpfPixelFormat
)).dwRBitMask
= 0x00ff0000;
13551 U3(U4(surface_desc
.ddpfPixelFormat
)).dwGBitMask
= 0x0000ff00;
13552 U4(U4(surface_desc
.ddpfPixelFormat
)).dwBBitMask
= 0x000000ff;
13553 U5(U4(surface_desc
.ddpfPixelFormat
)).dwRGBAlphaBitMask
= 0xff000000;
13554 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &dst
, NULL
);
13555 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13556 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &src
, NULL
);
13557 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
13559 ckey
.dwColorSpaceLowValue
= 0x0000ff00;
13560 ckey
.dwColorSpaceHighValue
= 0x0000ff00;
13561 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, &ckey
);
13562 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13563 ckey
.dwColorSpaceLowValue
= 0x00ff0000;
13564 ckey
.dwColorSpaceHighValue
= 0x00ff0000;
13565 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, &ckey
);
13566 ok(SUCCEEDED(hr
) || hr
== DDERR_NOCOLORKEYHW
, "Failed to set color key, hr %#x.\n", hr
);
13569 /* Nvidia reject dest keys, AMD allows them. This applies to vidmem and sysmem surfaces. */
13570 skip("Failed to set destination color key, skipping related tests.\n");
13574 ckey
.dwColorSpaceLowValue
= 0x000000ff;
13575 ckey
.dwColorSpaceHighValue
= 0x000000ff;
13576 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, &ckey
);
13577 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13578 ckey
.dwColorSpaceLowValue
= 0x000000aa;
13579 ckey
.dwColorSpaceHighValue
= 0x000000aa;
13580 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, &ckey
);
13581 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13583 memset(&fx
, 0, sizeof(fx
));
13584 fx
.dwSize
= sizeof(fx
);
13585 fx
.ddckSrcColorkey
.dwColorSpaceHighValue
= 0x00110000;
13586 fx
.ddckSrcColorkey
.dwColorSpaceLowValue
= 0x00110000;
13587 fx
.ddckDestColorkey
.dwColorSpaceHighValue
= 0x00001100;
13588 fx
.ddckDestColorkey
.dwColorSpaceLowValue
= 0x00001100;
13590 hr
= IDirectDrawSurface4_Lock(src
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13591 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13592 color
= surface_desc
.lpSurface
;
13593 color
[0] = 0x000000ff; /* Applies to src blt key in src surface. */
13594 color
[1] = 0x000000aa; /* Applies to dst blt key in src surface. */
13595 color
[2] = 0x00ff0000; /* Dst color key in dst surface. */
13596 color
[3] = 0x0000ff00; /* Src color key in dst surface. */
13597 color
[4] = 0x00001100; /* Src color key in ddbltfx. */
13598 color
[5] = 0x00110000; /* Dst color key in ddbltfx. */
13599 hr
= IDirectDrawSurface4_Unlock(src
, NULL
);
13600 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13602 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13603 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13604 color
= surface_desc
.lpSurface
;
13605 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13606 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13607 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13609 /* Test a blit without keying. */
13610 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, 0, &fx
);
13611 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13613 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13614 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13615 color
= surface_desc
.lpSurface
;
13616 /* Should have copied src data unmodified to dst. */
13617 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13618 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13619 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13620 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13622 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13623 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13624 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13627 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13628 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13630 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13631 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13632 color
= surface_desc
.lpSurface
;
13633 /* Src key applied to color[0]. It is unmodified, the others are copied. */
13634 ok(color
[0] == 0x55555555 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13635 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13636 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13637 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13639 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13640 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13641 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13643 /* Src override. */
13644 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, &fx
);
13645 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13647 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13648 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13649 color
= surface_desc
.lpSurface
;
13650 /* Override key applied to color[5]. It is unmodified, the others are copied. */
13651 ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13652 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x55555555,
13653 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13654 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13656 color
[0] = color
[1] = color
[2] = color
[3] = color
[4] = color
[5] = 0x55555555;
13657 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13658 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13660 /* Src override AND src key. That is not supposed to work. */
13661 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
| DDBLT_KEYSRCOVERRIDE
, &fx
);
13662 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13664 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13665 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13666 color
= surface_desc
.lpSurface
;
13667 /* Ensure the destination was not changed. */
13668 ok(color
[0] == 0x55555555 && color
[1] == 0x55555555 && color
[2] == 0x55555555 &&
13669 color
[3] == 0x55555555 && color
[4] == 0x55555555 && color
[5] == 0x55555555,
13670 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13671 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13673 /* Use different dst colors for the dst key test. */
13674 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13675 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13676 color
[2] = 0x00001100; /* Dest key in override. */
13677 color
[3] = 0x00001100; /* Dest key in override. */
13678 color
[4] = 0x000000aa; /* Dest key in src surface. */
13679 color
[5] = 0x000000aa; /* Dest key in src surface. */
13680 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13681 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13683 /* Dest key blit. The key is taken from the DESTINATION surface in v4! */
13684 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13685 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13687 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13688 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13689 color
= surface_desc
.lpSurface
;
13690 /* Dst key applied to color[0,1], they are the only changed pixels. */
13691 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13692 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13693 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13694 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13696 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13697 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13698 color
[2] = 0x00001100; /* Dest key in override. */
13699 color
[3] = 0x00001100; /* Dest key in override. */
13700 color
[4] = 0x000000aa; /* Dest key in src surface. */
13701 color
[5] = 0x000000aa; /* Dest key in src surface. */
13702 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13703 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13705 /* What happens with a QI'd older version of the interface? It takes the key
13706 * from the source surface. */
13707 hr
= IDirectDrawSurface4_QueryInterface(src
, &IID_IDirectDrawSurface
, (void **)&src1
);
13708 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13709 hr
= IDirectDrawSurface4_QueryInterface(dst
, &IID_IDirectDrawSurface
, (void **)&dst1
);
13710 ok(SUCCEEDED(hr
), "Failed to query IDirectDrawSurface interface, hr %#x.\n", hr
);
13712 hr
= IDirectDrawSurface_Blt(dst1
, NULL
, src1
, NULL
, DDBLT_KEYDEST
, &fx
);
13713 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13715 IDirectDrawSurface_Release(dst1
);
13716 IDirectDrawSurface_Release(src1
);
13718 hr
= IDirectDrawSurface7_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13719 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13720 color
= surface_desc
.lpSurface
;
13721 /* Dst key applied to color[4,5], they are the only changed pixels. */
13722 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13723 color
[3] == 0x00001100 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13724 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13725 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13727 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13728 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13729 color
[2] = 0x00001100; /* Dest key in override. */
13730 color
[3] = 0x00001100; /* Dest key in override. */
13731 color
[4] = 0x000000aa; /* Dest key in src surface. */
13732 color
[5] = 0x000000aa; /* Dest key in src surface. */
13733 hr
= IDirectDrawSurface7_Unlock(dst
, NULL
);
13734 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13736 /* Dest override key blit. */
13737 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, &fx
);
13738 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13740 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13741 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13742 color
= surface_desc
.lpSurface
;
13743 /* Dst key applied to color[2,3], they are the only changed pixels. */
13744 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00ff0000 &&
13745 color
[3] == 0x0000ff00 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13746 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13747 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13749 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13750 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13751 color
[2] = 0x00001100; /* Dest key in override. */
13752 color
[3] = 0x00001100; /* Dest key in override. */
13753 color
[4] = 0x000000aa; /* Dest key in src surface. */
13754 color
[5] = 0x000000aa; /* Dest key in src surface. */
13755 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13756 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13758 /* Dest override together with surface key. Supposed to fail. */
13759 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYDESTOVERRIDE
, &fx
);
13760 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13762 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13763 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13764 color
= surface_desc
.lpSurface
;
13765 /* Destination is unchanged. */
13766 ok(color
[0] == 0x00ff0000 && color
[1] == 0x00ff0000 && color
[2] == 0x00001100 &&
13767 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13768 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13769 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13770 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13771 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13773 /* Source and destination key. This is driver dependent. New HW treats it like
13774 * DDBLT_KEYSRC. Older HW and some software renderers apply both keys. */
13777 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
| DDBLT_KEYSRC
, &fx
);
13778 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13780 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13781 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13782 color
= surface_desc
.lpSurface
;
13783 /* Color[0] is filtered by the src key, 2-5 are filtered by the dst key, if
13784 * the driver applies it. */
13785 ok(color
[0] == 0x00ff0000 && color
[1] == 0x000000aa && color
[2] == 0x00ff0000 &&
13786 color
[3] == 0x0000ff00 && color
[4] == 0x00001100 && color
[5] == 0x00110000,
13787 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13788 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13790 color
[0] = 0x00ff0000; /* Dest key in dst surface. */
13791 color
[1] = 0x00ff0000; /* Dest key in dst surface. */
13792 color
[2] = 0x00001100; /* Dest key in override. */
13793 color
[3] = 0x00001100; /* Dest key in override. */
13794 color
[4] = 0x000000aa; /* Dest key in src surface. */
13795 color
[5] = 0x000000aa; /* Dest key in src surface. */
13796 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13797 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13800 /* Override keys without ddbltfx parameter fail */
13801 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDESTOVERRIDE
, NULL
);
13802 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13803 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRCOVERRIDE
, NULL
);
13804 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13806 /* Try blitting without keys in the source surface. */
13807 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_SRCBLT
, NULL
);
13808 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13809 hr
= IDirectDrawSurface4_SetColorKey(src
, DDCKEY_DESTBLT
, NULL
);
13810 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13812 /* That fails now. Do not bother to check that the data is unmodified. */
13813 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYSRC
, &fx
);
13814 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13816 /* Dest key blit still works, the destination surface key is used in v4. */
13817 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13818 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
13820 hr
= IDirectDrawSurface4_Lock(dst
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
13821 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
13822 color
= surface_desc
.lpSurface
;
13823 /* Dst key applied to color[0,1], they are the only changed pixels. */
13824 todo_wine
ok(color
[0] == 0x000000ff && color
[1] == 0x000000aa && color
[2] == 0x00001100 &&
13825 color
[3] == 0x00001100 && color
[4] == 0x000000aa && color
[5] == 0x000000aa,
13826 "Got unexpected content %08x %08x %08x %08x %08x %08x.\n",
13827 color
[0], color
[1], color
[2], color
[3], color
[4], color
[5]);
13828 hr
= IDirectDrawSurface4_Unlock(dst
, NULL
);
13829 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
13831 /* Try blitting without keys in the destination surface. */
13832 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_SRCBLT
, NULL
);
13833 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13834 hr
= IDirectDrawSurface4_SetColorKey(dst
, DDCKEY_DESTBLT
, NULL
);
13835 ok(SUCCEEDED(hr
), "Failed to set color key, hr %#x.\n", hr
);
13837 /* This fails, as sanity would dictate. */
13838 hr
= IDirectDrawSurface4_Blt(dst
, NULL
, src
, NULL
, DDBLT_KEYDEST
, &fx
);
13839 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
13842 IDirectDrawSurface4_Release(src
);
13843 IDirectDrawSurface4_Release(dst
);
13844 refcount
= IDirectDraw4_Release(ddraw
);
13845 ok(!refcount
, "DirectDraw has %u references left.\n", refcount
);
13846 DestroyWindow(window
);
13849 static void test_vb_refcount(void)
13851 ULONG prev_d3d_refcount
, prev_device_refcount
;
13852 ULONG cur_d3d_refcount
, cur_device_refcount
;
13853 IDirect3DVertexBuffer
*vb
, *vb1
;
13854 IDirect3DVertexBuffer7
*vb7
;
13855 D3DVERTEXBUFFERDESC vb_desc
;
13856 IDirect3DDevice3
*device
;
13863 window
= create_window();
13864 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13866 skip("Failed to create a 3D device, skipping test.\n");
13867 DestroyWindow(window
);
13871 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
13872 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
13874 prev_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
13875 prev_device_refcount
= get_refcount((IUnknown
*)device
);
13877 memset(&vb_desc
, 0, sizeof(vb_desc
));
13878 vb_desc
.dwSize
= sizeof(vb_desc
);
13879 vb_desc
.dwFVF
= D3DFVF_XYZ
;
13880 vb_desc
.dwNumVertices
= 4;
13881 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &vb
, 0, NULL
);
13882 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
13884 cur_d3d_refcount
= get_refcount((IUnknown
*)d3d
);
13885 cur_device_refcount
= get_refcount((IUnknown
*)device
);
13886 ok(cur_d3d_refcount
== prev_d3d_refcount
, "D3D object refcount changed from %u to %u.\n",
13887 prev_d3d_refcount
, cur_d3d_refcount
);
13888 ok(cur_device_refcount
== prev_device_refcount
, "Device refcount changed from %u to %u.\n",
13889 prev_device_refcount
, cur_device_refcount
);
13891 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer
, (void **)&vb1
);
13892 ok(hr
== DD_OK
, "Failed to query IDirect3DVertexBuffer, hr %#x.\n", hr
);
13893 IDirect3DVertexBuffer_Release(vb1
);
13895 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IDirect3DVertexBuffer7
, (void **)&vb7
);
13896 ok(hr
== E_NOINTERFACE
, "Querying IDirect3DVertexBuffer7 returned unexpected hr %#x.\n", hr
);
13898 hr
= IDirect3DVertexBuffer_QueryInterface(vb
, &IID_IUnknown
, (void **)&unk
);
13899 ok(hr
== DD_OK
, "Failed to query IUnknown, hr %#x.\n", hr
);
13900 ok((IUnknown
*)vb
== unk
,
13901 "IDirect3DVertexBuffer and IUnknown interface pointers don't match, %p != %p.\n", vb
, unk
);
13902 IUnknown_Release(unk
);
13904 refcount
= IDirect3DVertexBuffer_Release(vb
);
13905 ok(!refcount
, "Vertex buffer has %u references left.\n", refcount
);
13906 IDirect3D3_Release(d3d
);
13907 refcount
= IDirect3DDevice3_Release(device
);
13908 ok(!refcount
, "Device has %u references left.\n", refcount
);
13909 DestroyWindow(window
);
13912 static void test_compute_sphere_visibility(void)
13914 static D3DMATRIX proj_1
=
13916 1.810660f
, 0.000000f
, 0.000000f
, 0.000000f
,
13917 0.000000f
, 2.414213f
, 0.000000f
, 0.000000f
,
13918 0.000000f
, 0.000000f
, 1.020408f
, 1.000000f
,
13919 0.000000f
, 0.000000f
, -0.102041f
, 0.000000f
,
13921 static D3DMATRIX proj_2
=
13923 10.0f
, 0.0f
, 0.0f
, 0.0f
,
13924 0.0f
, 10.0f
, 0.0f
, 0.0f
,
13925 0.0f
, 0.0f
, 10.0f
, 0.0f
,
13926 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13928 static D3DMATRIX view_1
=
13930 1.000000f
, 0.000000f
, 0.000000f
, 0.000000f
,
13931 0.000000f
, 0.768221f
, -0.640185f
, 0.000000f
,
13932 -0.000000f
, 0.640185f
, 0.768221f
, 0.000000f
,
13933 -14.852037f
, 9.857489f
, 11.600972f
, 1.000000f
,
13935 static D3DMATRIX identity
=
13937 1.0f
, 0.0f
, 0.0f
, 0.0f
,
13938 0.0f
, 1.0f
, 0.0f
, 0.0f
,
13939 0.0f
, 0.0f
, 1.0f
, 0.0f
,
13940 0.0f
, 0.0f
, 0.0f
, 1.0f
,
13944 D3DMATRIX
*view
, *proj
;
13945 unsigned int sphere_count
;
13946 D3DVECTOR center
[3];
13947 D3DVALUE radius
[3];
13948 const DWORD expected
[3];
13953 {&view_1
, &proj_1
, 1, {{{11.461533f
}, {-4.761727f
}, {-1.171646f
}}}, {38.252632f
}, {0x1555}},
13954 {&view_1
, &proj_1
, 3, {{{-3.515620f
}, {-1.560661f
}, {-12.464638f
}},
13955 {{14.290396f
}, {-2.981143f
}, {-24.311312f
}},
13956 {{1.461626f
}, {-6.093709f
}, {-13.901010f
}}},
13957 {4.354097f
, 12.500704f
, 17.251318f
}, {0x154a, 0x1555, 0x1555}},
13958 {&identity
, &proj_2
, 1, {{{0.0f
}, {0.0f
}, {0.05f
}}}, {0.04f
}, {0x1555}, TRUE
},
13959 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.5f
}}}, {0.5f
}, {0x1401}},
13960 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {0.0f
}}}, {0.0f
}, {0x401}},
13961 {&identity
, &identity
, 1, {{{-1.0f
}, {-1.0f
}, {0.5f
}}}, {0.25f
}, {0x1505}, TRUE
}, /* 5 */
13962 {&identity
, &identity
, 1, {{{-20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x154a}},
13963 {&identity
, &identity
, 1, {{{20.0f
}, {0.0f
}, {0.5f
}}}, {3.0f
}, {0x1562}},
13964 {&identity
, &identity
, 1, {{{0.0f
}, {-20.0f
}, {0.5f
}}}, {3.0f
}, {0x1616}},
13965 {&identity
, &identity
, 1, {{{0.0f
}, {20.0f
}, {0.5f
}}}, {3.0f
}, {0x1496}},
13966 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {-20.0f
}}}, {3.0f
}, {0x956}}, /* 10 */
13967 {&identity
, &identity
, 1, {{{0.0f
}, {0.0f
}, {20.0f
}}}, {3.0f
}, {0x2156}},
13969 IDirect3DViewport3
*viewport
;
13970 IDirect3DDevice3
*device
;
13977 window
= create_window();
13978 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
13980 skip("Failed to create a 3D device, skipping test.\n");
13981 DestroyWindow(window
);
13985 viewport
= create_viewport(device
, 0, 0, 640, 480);
13986 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
13987 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
13989 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_WORLD
, &identity
);
13991 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
13993 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_VIEW
, tests
[i
].view
);
13994 IDirect3DDevice3_SetTransform(device
, D3DTRANSFORMSTATE_PROJECTION
, tests
[i
].proj
);
13996 hr
= IDirect3DDevice3_ComputeSphereVisibility(device
, tests
[i
].center
, tests
[i
].radius
,
13997 tests
[i
].sphere_count
, 0, result
);
13998 ok(hr
== D3D_OK
, "Got unexpected hr %#x.\n", hr
);
14000 for (j
= 0; j
< tests
[i
].sphere_count
; ++j
)
14001 todo_wine_if(tests
[i
].todo
)
14002 ok(result
[j
] == tests
[i
].expected
[j
], "Test %u sphere %u: expected %#x, got %#x.\n",
14003 i
, j
, tests
[i
].expected
[j
], result
[j
]);
14006 destroy_viewport(device
, viewport
);
14007 refcount
= IDirect3DDevice3_Release(device
);
14008 ok(!refcount
, "Device has %u references left.\n", refcount
);
14009 DestroyWindow(window
);
14012 static void test_map_synchronisation(void)
14014 LARGE_INTEGER frequency
, diff
, ts
[3];
14015 IDirect3DVertexBuffer
*buffer
;
14016 IDirect3DViewport3
*viewport
;
14017 unsigned int i
, j
, tri_count
;
14018 D3DVERTEXBUFFERDESC vb_desc
;
14019 IDirect3DDevice3
*device
;
14020 BOOL unsynchronised
, ret
;
14021 IDirectDrawSurface4
*rt
;
14028 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14030 /* DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE were introduced with
14031 * ddraw7 and are ignored in earlier versions. */
14032 static const struct
14034 unsigned int flags
;
14035 BOOL unsynchronised
;
14040 {DDLOCK_NOOVERWRITE
, FALSE
},
14041 {DDLOCK_DISCARDCONTENTS
, FALSE
},
14042 {DDLOCK_NOOVERWRITE
| DDLOCK_DISCARDCONTENTS
, FALSE
},
14045 static const struct quad
14049 struct vec3 position
;
14056 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
14057 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14058 {{ 1.0f
, -1.0f
, 0.0f
}, 0xff0000ff},
14059 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffffff},
14065 {{-1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14066 {{-1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14067 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffffff00},
14068 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffffff00},
14071 struct quad
*quads
;
14073 window
= create_window();
14074 ok(!!window
, "Failed to create a window.\n");
14076 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14078 skip("Failed to create a D3D device, skipping tests.\n");
14079 DestroyWindow(window
);
14083 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14084 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14086 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14087 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14088 viewport
= create_viewport(device
, 0, 0, 640, 480);
14089 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14090 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14092 tri_count
= 0x1000;
14094 ret
= QueryPerformanceFrequency(&frequency
);
14095 ok(ret
, "Failed to get performance counter frequency.\n");
14097 vb_desc
.dwSize
= sizeof(vb_desc
);
14098 vb_desc
.dwCaps
= D3DVBCAPS_WRITEONLY
;
14099 vb_desc
.dwFVF
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
14100 vb_desc
.dwNumVertices
= tri_count
+ 2;
14101 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14102 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14103 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14104 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14105 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14109 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14110 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14112 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14113 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
14115 /* Initial draw to initialise states, compile shaders, etc. */
14116 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14117 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14118 hr
= IDirect3DDevice3_BeginScene(device
);
14119 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14120 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14121 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14122 hr
= IDirect3DDevice3_EndScene(device
);
14123 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14124 /* Read the result to ensure the GPU has finished drawing. */
14125 colour
= get_surface_color(rt
, 320, 240);
14127 /* Time drawing tri_count triangles. */
14128 ret
= QueryPerformanceCounter(&ts
[0]);
14129 ok(ret
, "Failed to read performance counter.\n");
14130 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14131 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14132 hr
= IDirect3DDevice3_BeginScene(device
);
14133 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14134 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14135 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14136 hr
= IDirect3DDevice3_EndScene(device
);
14137 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14138 colour
= get_surface_color(rt
, 320, 240);
14139 /* Time drawing a single triangle. */
14140 ret
= QueryPerformanceCounter(&ts
[1]);
14141 ok(ret
, "Failed to read performance counter.\n");
14142 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14143 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14144 hr
= IDirect3DDevice3_BeginScene(device
);
14145 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14146 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, 3, 0);
14147 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14148 hr
= IDirect3DDevice3_EndScene(device
);
14149 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14150 colour
= get_surface_color(rt
, 320, 240);
14151 ret
= QueryPerformanceCounter(&ts
[2]);
14152 ok(ret
, "Failed to read performance counter.\n");
14154 IDirect3DVertexBuffer_Release(buffer
);
14156 /* Estimate the number of triangles we can draw in 100ms. */
14157 diff
.QuadPart
= ts
[1].QuadPart
- ts
[0].QuadPart
+ ts
[1].QuadPart
- ts
[2].QuadPart
;
14158 tri_count
= (tri_count
* frequency
.QuadPart
) / (diff
.QuadPart
* 10);
14159 tri_count
= ((tri_count
+ 2 + 3) & ~3) - 2;
14160 vb_desc
.dwNumVertices
= tri_count
+ 2;
14162 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
14164 hr
= IDirect3D3_CreateVertexBuffer(d3d
, &vb_desc
, &buffer
, 0, NULL
);
14165 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#x.\n", hr
);
14166 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_DISCARDCONTENTS
, (void **)&quads
, NULL
);
14167 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14168 for (j
= 0; j
< vb_desc
.dwNumVertices
/ 4; ++j
)
14172 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14173 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14175 /* Start a draw operation. */
14176 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14177 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14178 hr
= IDirect3DDevice3_BeginScene(device
);
14179 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14180 hr
= IDirect3DDevice3_DrawPrimitiveVB(device
, D3DPT_TRIANGLESTRIP
, buffer
, 0, vb_desc
.dwNumVertices
, 0);
14181 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14182 hr
= IDirect3DDevice3_EndScene(device
);
14183 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14185 /* Map the last quad while the draw is in progress. */
14186 hr
= IDirect3DVertexBuffer_Lock(buffer
, DDLOCK_WAIT
| tests
[i
].flags
, (void **)&quads
, NULL
);
14187 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#x.\n", hr
);
14188 quads
[(vb_desc
.dwNumVertices
/ 4) - 1] = quad2
;
14189 hr
= IDirect3DVertexBuffer_Unlock(buffer
);
14190 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#x.\n", hr
);
14192 colour
= get_surface_color(rt
, 320, 240);
14193 unsynchronised
= compare_color(colour
, 0x00ffff00, 1);
14194 ok(tests
[i
].unsynchronised
== unsynchronised
, "Expected %s map for flags %#x.\n",
14195 tests
[i
].unsynchronised
? "unsynchronised" : "synchronised", tests
[i
].flags
);
14197 IDirect3DVertexBuffer_Release(buffer
);
14200 destroy_viewport(device
, viewport
);
14201 IDirectDrawSurface4_Release(rt
);
14202 IDirect3D3_Release(d3d
);
14203 refcount
= IDirect3DDevice3_Release(device
);
14204 ok(!refcount
, "Device has %u references left.\n", refcount
);
14205 DestroyWindow(window
);
14208 static void test_depth_readback(void)
14210 DWORD depth
, expected_depth
, max_diff
;
14211 IDirectDrawSurface4
*rt
, *ds
;
14212 IDirect3DViewport3
*viewport
;
14213 DDSURFACEDESC2 surface_desc
;
14214 IDirect3DDevice3
*device
;
14215 unsigned int i
, x
, y
;
14216 IDirectDraw4
*ddraw
;
14223 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
14226 struct vec3 position
;
14231 {{-1.0f
, -1.0f
, 0.1f
}, 0xff00ff00},
14232 {{-1.0f
, 1.0f
, 0.0f
}, 0xff00ff00},
14233 {{ 1.0f
, -1.0f
, 1.0f
}, 0xff00ff00},
14234 {{ 1.0f
, 1.0f
, 0.9f
}, 0xff00ff00},
14237 static const struct
14239 unsigned int z_depth
, s_depth
, z_mask
, s_mask
;
14244 {16, 0, 0x0000ffff, 0x00000000},
14245 {24, 0, 0x00ffffff, 0x00000000},
14246 {32, 0, 0x00ffffff, 0x00000000},
14247 {32, 8, 0x00ffffff, 0xff000000, TRUE
},
14248 {32, 0, 0xffffffff, 0x00000000},
14251 window
= create_window();
14252 ok(!!window
, "Failed to create a window.\n");
14254 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14256 skip("Failed to create a D3D device, skipping tests.\n");
14257 DestroyWindow(window
);
14261 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14262 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14263 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14264 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
14266 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14267 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14268 viewport
= create_viewport(device
, 0, 0, 640, 480);
14269 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14270 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14272 hr
= IDirect3DDevice3_SetRenderState(device
, D3DRENDERSTATE_LIGHTING
, FALSE
);
14273 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#x.\n", hr
);
14275 ds
= get_depth_stencil(device
);
14276 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
14277 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
14278 IDirectDrawSurface4_Release(ds
);
14280 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
14282 memset(&surface_desc
, 0, sizeof(surface_desc
));
14283 surface_desc
.dwSize
= sizeof(surface_desc
);
14284 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_PIXELFORMAT
| DDSD_WIDTH
| DDSD_HEIGHT
;
14285 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
| DDSCAPS_VIDEOMEMORY
;
14286 U4(surface_desc
).ddpfPixelFormat
.dwSize
= sizeof(U4(surface_desc
).ddpfPixelFormat
);
14287 U4(surface_desc
).ddpfPixelFormat
.dwFlags
= DDPF_ZBUFFER
;
14288 if (tests
[i
].s_depth
)
14289 U4(surface_desc
).ddpfPixelFormat
.dwFlags
|= DDPF_STENCILBUFFER
;
14290 U1(U4(surface_desc
).ddpfPixelFormat
).dwZBufferBitDepth
= tests
[i
].z_depth
;
14291 U2(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitDepth
= tests
[i
].s_depth
;
14292 U3(U4(surface_desc
).ddpfPixelFormat
).dwZBitMask
= tests
[i
].z_mask
;
14293 U4(U4(surface_desc
).ddpfPixelFormat
).dwStencilBitMask
= tests
[i
].s_mask
;
14294 surface_desc
.dwWidth
= 640;
14295 surface_desc
.dwHeight
= 480;
14296 hr
= IDirectDraw4_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
14299 skip("Format %u not supported, skipping test.\n", i
);
14303 hr
= IDirectDrawSurface_AddAttachedSurface(rt
, ds
);
14304 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
14305 hr
= IDirect3DDevice3_SetRenderTarget(device
, rt
, 0);
14306 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#x.\n", hr
);
14308 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &clear_rect
,
14309 D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xff0000ff, 1.0f
, 0);
14310 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14311 hr
= IDirect3DDevice3_BeginScene(device
);
14312 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
14313 hr
= IDirect3DDevice3_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
, quad
, 4, 0);
14314 ok(SUCCEEDED(hr
), "Failed to draw, hr %#x.\n", hr
);
14315 hr
= IDirect3DDevice3_EndScene(device
);
14316 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
14318 for (y
= 60; y
< 480; y
+= 120)
14320 for (x
= 80; x
< 640; x
+= 160)
14322 SetRect(&r
, x
, y
, x
+ 1, y
+ 1);
14323 memset(&surface_desc
, 0, sizeof(surface_desc
));
14324 surface_desc
.dwSize
= sizeof(surface_desc
);
14325 hr
= IDirectDrawSurface4_Lock(ds
, &r
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
14326 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
14328 depth
= *((DWORD
*)surface_desc
.lpSurface
) & tests
[i
].z_mask
;
14329 expected_depth
= (x
* (0.9 / 640.0) + y
* (0.1 / 480.0)) * tests
[i
].z_mask
;
14330 max_diff
= ((0.5f
* 0.9f
) / 640.0f
) * tests
[i
].z_mask
;
14331 todo_wine_if(tests
[i
].todo
)
14332 ok(abs(expected_depth
- depth
) <= max_diff
,
14333 "Test %u: Got depth 0x%08x (diff %d), expected 0x%08x+/-%u, at %u, %u.\n",
14334 i
, depth
, expected_depth
- depth
, expected_depth
, max_diff
, x
, y
);
14336 hr
= IDirectDrawSurface4_Unlock(ds
, &r
);
14337 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
14341 hr
= IDirectDrawSurface4_DeleteAttachedSurface(rt
, 0, ds
);
14342 ok(SUCCEEDED(hr
), "Failed to detach depth buffer, hr %#x.\n", hr
);
14343 IDirectDrawSurface4_Release(ds
);
14346 destroy_viewport(device
, viewport
);
14347 IDirectDrawSurface4_Release(rt
);
14348 IDirectDraw4_Release(ddraw
);
14349 IDirect3D3_Release(d3d
);
14350 refcount
= IDirect3DDevice3_Release(device
);
14351 ok(!refcount
, "Device has %u references left.\n", refcount
);
14352 DestroyWindow(window
);
14355 static void test_clear(void)
14357 D3DRECT rect_negneg
, rect_full
= {{0}, {0}, {640}, {480}};
14358 IDirect3DViewport3
*viewport
, *viewport2
, *viewport3
;
14359 IDirect3DDevice3
*device
;
14360 IDirectDrawSurface4
*rt
;
14361 IDirectDraw4
*ddraw
;
14369 window
= create_window();
14370 if (!(device
= create_device(window
, DDSCL_NORMAL
)))
14372 skip("Failed to create 3D device.\n");
14373 DestroyWindow(window
);
14377 hr
= IDirect3DDevice3_GetDirect3D(device
, &d3d
);
14378 ok(SUCCEEDED(hr
), "Failed to get Direct3D3 interface, hr %#x.\n", hr
);
14379 hr
= IDirect3D3_QueryInterface(d3d
, &IID_IDirectDraw4
, (void **)&ddraw
);
14380 ok(SUCCEEDED(hr
), "Failed to get ddraw interface, hr %#x.\n", hr
);
14382 hr
= IDirect3DDevice3_GetRenderTarget(device
, &rt
);
14383 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
14385 viewport
= create_viewport(device
, 0, 0, 640, 480);
14386 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14387 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14389 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
14390 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14392 /* Positive x, negative y. */
14393 U1(rect
[0]).x1
= 0;
14394 U2(rect
[0]).y1
= 480;
14395 U3(rect
[0]).x2
= 320;
14396 U4(rect
[0]).y2
= 240;
14398 /* Positive x, positive y. */
14399 U1(rect
[1]).x1
= 0;
14400 U2(rect
[1]).y1
= 0;
14401 U3(rect
[1]).x2
= 320;
14402 U4(rect
[1]).y2
= 240;
14404 /* Clear 2 rectangles with one call. Unlike d3d8/9, the refrast does not
14405 * refuse negative rectangles, but it will not clear them either. */
14406 hr
= IDirect3DViewport3_Clear2(viewport
, 2, rect
, D3DCLEAR_TARGET
, 0xffff0000, 0.0f
, 0);
14407 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14409 color
= get_surface_color(rt
, 160, 360);
14410 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 3 (pos, neg) has color 0x%08x.\n", color
);
14411 color
= get_surface_color(rt
, 160, 120);
14412 ok(compare_color(color
, 0x00ff0000, 0), "Clear rectangle 1 (pos, pos) has color 0x%08x.\n", color
);
14413 color
= get_surface_color(rt
, 480, 360);
14414 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (NULL) has color 0x%08x.\n", color
);
14415 color
= get_surface_color(rt
, 480, 120);
14416 ok(compare_color(color
, 0x00ffffff, 0), "Clear rectangle 4 (neg, neg) has color 0x%08x.\n", color
);
14418 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0, 0);
14419 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14420 /* negative x, negative y.
14421 * Also ignored, except on WARP, which clears the entire screen. */
14422 rect_negneg
.x1
= 640;
14423 rect_negneg
.y1
= 240;
14424 rect_negneg
.x2
= 320;
14425 rect_negneg
.y2
= 0;
14426 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_negneg
, D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14427 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14429 color
= get_surface_color(rt
, 160, 360);
14430 ok(compare_color(color
, 0x00ffffff, 0)
14431 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14432 "Got unexpected color 0x%08x.\n", color
);
14433 color
= get_surface_color(rt
, 160, 120);
14434 ok(compare_color(color
, 0x00ffffff, 0)
14435 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14436 "Got unexpected color 0x%08x.\n", color
);
14437 color
= get_surface_color(rt
, 480, 360);
14438 ok(compare_color(color
, 0x00ffffff, 0)
14439 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14440 "Got unexpected color 0x%08x.\n", color
);
14441 color
= get_surface_color(rt
, 480, 120);
14442 ok(compare_color(color
, 0x00ffffff, 0)
14443 || broken(ddraw_is_warp(ddraw
) && compare_color(color
, 0x0000ff00, 0)),
14444 "Got unexpected color 0x%08x.\n", color
);
14446 /* Test how the viewport affects clears. */
14447 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
14448 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14450 viewport2
= create_viewport(device
, 160, 120, 160, 120);
14451 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport2
);
14452 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14454 hr
= IDirect3DViewport3_Clear2(viewport2
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xff0000ff, 0.0f
, 0);
14455 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14457 viewport3
= create_viewport(device
, 320, 240, 320, 240);
14458 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport3
);
14459 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14461 U1(rect
[0]).x1
= 160;
14462 U2(rect
[0]).y1
= 120;
14463 U3(rect
[0]).x2
= 480;
14464 U4(rect
[0]).y2
= 360;
14465 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14466 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14468 hr
= IDirect3DDevice3_SetCurrentViewport(device
, viewport
);
14469 ok(SUCCEEDED(hr
), "Failed to set current viewport, hr %#x.\n", hr
);
14471 color
= get_surface_color(rt
, 158, 118);
14472 ok(compare_color(color
, 0x00ffffff, 0), "(158, 118) has color 0x%08x.\n", color
);
14473 color
= get_surface_color(rt
, 162, 118);
14474 ok(compare_color(color
, 0x00ffffff, 0), "(162, 118) has color 0x%08x.\n", color
);
14475 color
= get_surface_color(rt
, 158, 122);
14476 ok(compare_color(color
, 0x00ffffff, 0), "(158, 122) has color 0x%08x.\n", color
);
14477 color
= get_surface_color(rt
, 162, 122);
14478 ok(compare_color(color
, 0x000000ff, 0), "(162, 122) has color 0x%08x.\n", color
);
14480 color
= get_surface_color(rt
, 318, 238);
14481 ok(compare_color(color
, 0x000000ff, 0), "(318, 238) has color 0x%08x.\n", color
);
14482 color
= get_surface_color(rt
, 322, 238);
14483 ok(compare_color(color
, 0x00ffffff, 0), "(322, 328) has color 0x%08x.\n", color
);
14484 color
= get_surface_color(rt
, 318, 242);
14485 ok(compare_color(color
, 0x00ffffff, 0), "(318, 242) has color 0x%08x.\n", color
);
14486 color
= get_surface_color(rt
, 322, 242);
14487 ok(compare_color(color
, 0x0000ff00, 0), "(322, 242) has color 0x%08x.\n", color
);
14489 color
= get_surface_color(rt
, 478, 358);
14490 ok(compare_color(color
, 0x0000ff00, 0), "(478, 358) has color 0x%08x.\n", color
);
14491 color
= get_surface_color(rt
, 482, 358);
14492 ok(compare_color(color
, 0x00ffffff, 0), "(482, 358) has color 0x%08x.\n", color
);
14493 color
= get_surface_color(rt
, 478, 362);
14494 ok(compare_color(color
, 0x00ffffff, 0), "(478, 362) has color 0x%08x.\n", color
);
14495 color
= get_surface_color(rt
, 482, 362);
14496 ok(compare_color(color
, 0x00ffffff, 0), "(482, 362) has color 0x%08x.\n", color
);
14498 /* The clear rectangle is rendertarget absolute, not relative to the
14500 hr
= IDirect3DViewport3_Clear2(viewport
, 1, &rect_full
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
14501 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14502 U1(rect
[0]).x1
= 330;
14503 U2(rect
[0]).y1
= 250;
14504 U3(rect
[0]).x2
= 340;
14505 U4(rect
[0]).y2
= 260;
14506 hr
= IDirect3DViewport3_Clear2(viewport3
, 1, &rect
[0], D3DCLEAR_TARGET
, 0xff00ff00, 0.0f
, 0);
14507 ok(SUCCEEDED(hr
), "Failed to clear, hr %#x.\n", hr
);
14509 color
= get_surface_color(rt
, 328, 248);
14510 ok(compare_color(color
, 0x00ffffff, 0), "(328, 248) has color 0x%08x.\n", color
);
14511 color
= get_surface_color(rt
, 332, 248);
14512 ok(compare_color(color
, 0x00ffffff, 0), "(332, 248) has color 0x%08x.\n", color
);
14513 color
= get_surface_color(rt
, 328, 252);
14514 ok(compare_color(color
, 0x00ffffff, 0), "(328, 252) has color 0x%08x.\n", color
);
14515 color
= get_surface_color(rt
, 332, 252);
14516 ok(compare_color(color
, 0x0000ff00, 0), "(332, 252) has color 0x%08x.\n", color
);
14518 color
= get_surface_color(rt
, 338, 248);
14519 ok(compare_color(color
, 0x00ffffff, 0), "(338, 248) has color 0x%08x.\n", color
);
14520 color
= get_surface_color(rt
, 342, 248);
14521 ok(compare_color(color
, 0x00ffffff, 0), "(342, 248) has color 0x%08x.\n", color
);
14522 color
= get_surface_color(rt
, 338, 252);
14523 ok(compare_color(color
, 0x0000ff00, 0), "(338, 252) has color 0x%08x.\n", color
);
14524 color
= get_surface_color(rt
, 342, 252);
14525 ok(compare_color(color
, 0x00ffffff, 0), "(342, 252) has color 0x%08x.\n", color
);
14527 color
= get_surface_color(rt
, 328, 258);
14528 ok(compare_color(color
, 0x00ffffff, 0), "(328, 258) has color 0x%08x.\n", color
);
14529 color
= get_surface_color(rt
, 332, 258);
14530 ok(compare_color(color
, 0x0000ff00, 0), "(332, 258) has color 0x%08x.\n", color
);
14531 color
= get_surface_color(rt
, 328, 262);
14532 ok(compare_color(color
, 0x00ffffff, 0), "(328, 262) has color 0x%08x.\n", color
);
14533 color
= get_surface_color(rt
, 332, 262);
14534 ok(compare_color(color
, 0x00ffffff, 0), "(332, 262) has color 0x%08x.\n", color
);
14536 color
= get_surface_color(rt
, 338, 258);
14537 ok(compare_color(color
, 0x0000ff00, 0), "(338, 258) has color 0x%08x.\n", color
);
14538 color
= get_surface_color(rt
, 342, 258);
14539 ok(compare_color(color
, 0x00ffffff, 0), "(342, 258) has color 0x%08x.\n", color
);
14540 color
= get_surface_color(rt
, 338, 262);
14541 ok(compare_color(color
, 0x00ffffff, 0), "(338, 262) has color 0x%08x.\n", color
);
14542 color
= get_surface_color(rt
, 342, 262);
14543 ok(compare_color(color
, 0x00ffffff, 0), "(342, 262) has color 0x%08x.\n", color
);
14545 /* COLORWRITEENABLE, SRGBWRITEENABLE and scissor rectangles do not exist
14548 IDirect3DViewport3_Release(viewport3
);
14549 IDirect3DViewport3_Release(viewport2
);
14550 IDirect3DViewport3_Release(viewport
);
14551 IDirectDrawSurface4_Release(rt
);
14552 IDirectDraw4_Release(ddraw
);
14553 IDirect3D3_Release(d3d
);
14554 refcount
= IDirect3DDevice3_Release(device
);
14555 ok(!refcount
, "Device has %u references left.\n", refcount
);
14556 DestroyWindow(window
);
14561 DDDEVICEIDENTIFIER identifier
;
14562 DEVMODEW current_mode
;
14563 IDirectDraw4
*ddraw
;
14566 if (!(ddraw
= create_ddraw()))
14568 skip("Failed to create a ddraw object, skipping tests.\n");
14572 if (ddraw_get_identifier(ddraw
, &identifier
))
14574 trace("Driver string: \"%s\"\n", identifier
.szDriver
);
14575 trace("Description string: \"%s\"\n", identifier
.szDescription
);
14576 trace("Driver version %d.%d.%d.%d\n",
14577 HIWORD(U(identifier
.liDriverVersion
).HighPart
), LOWORD(U(identifier
.liDriverVersion
).HighPart
),
14578 HIWORD(U(identifier
.liDriverVersion
).LowPart
), LOWORD(U(identifier
.liDriverVersion
).LowPart
));
14580 IDirectDraw4_Release(ddraw
);
14582 memset(¤t_mode
, 0, sizeof(current_mode
));
14583 current_mode
.dmSize
= sizeof(current_mode
);
14584 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
14585 registry_mode
.dmSize
= sizeof(registry_mode
);
14586 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
14587 if (registry_mode
.dmPelsWidth
!= current_mode
.dmPelsWidth
14588 || registry_mode
.dmPelsHeight
!= current_mode
.dmPelsHeight
)
14590 skip("Current mode does not match registry mode, skipping test.\n");
14594 if ((dwmapi
= LoadLibraryA("dwmapi.dll")))
14595 pDwmIsCompositionEnabled
= (void *)GetProcAddress(dwmapi
, "DwmIsCompositionEnabled");
14597 test_process_vertices();
14598 test_coop_level_create_device_window();
14599 test_clipper_blt();
14600 test_coop_level_d3d_state();
14601 test_surface_interface_mismatch();
14602 test_coop_level_threaded();
14604 test_texture_load_ckey();
14613 test_window_style();
14614 test_redundant_mode_set();
14615 test_coop_level_mode_set();
14616 test_coop_level_mode_set_multi();
14618 test_coop_level_surf_create();
14620 test_coop_level_multi_window();
14621 test_draw_strided();
14623 test_specular_lighting();
14624 test_clear_rect_count();
14625 test_coop_level_versions();
14626 test_lighting_interface_versions();
14627 test_coop_level_activateapp();
14628 test_texturemanage();
14629 test_block_formats_creation();
14630 test_unsupported_formats();
14632 test_primary_caps();
14633 test_surface_lock();
14634 test_surface_discard();
14636 test_set_surface_desc();
14637 test_user_memory_getdc();
14638 test_sysmem_overlay();
14639 test_primary_palette();
14640 test_surface_attachment();
14641 test_private_data();
14642 test_pixel_format();
14643 test_create_surface_pitch();
14645 test_palette_complex();
14648 test_palette_gdi();
14649 test_palette_alpha();
14650 test_vb_writeonly();
14651 test_lost_device();
14652 test_surface_desc_lock();
14653 test_texturemapblend();
14654 test_signed_formats();
14656 test_texcoordindex();
14657 test_colorkey_precision();
14658 test_range_colorkey();
14660 test_lockrect_invalid();
14661 test_yv12_overlay();
14662 test_offscreen_overlay();
14663 test_overlay_rect();
14665 test_blt_z_alpha();
14666 test_color_clamping();
14668 test_draw_primitive();
14669 test_edge_antialiasing_blending();
14670 test_transform_vertices();
14671 test_display_mode_surface_pixel_format();
14672 test_surface_desc_size();
14673 test_get_surface_from_dc();
14674 test_ck_operation();
14675 test_vb_refcount();
14676 test_compute_sphere_visibility();
14677 test_map_synchronisation();
14678 test_depth_readback();