2 * Copyright (C) 2008 Stefan Dösinger(for CodeWeavers)
3 * Copyright (C) 2010 Louis Lenders
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* This file contains tests specific to IDirect3D9Ex and IDirect3DDevice9Ex, like
21 * how to obtain them. For testing rendering with extended functions use visual.c
25 #include "wine/test.h"
31 static HMODULE d3d9_handle
= 0;
33 static BOOL (WINAPI
*pEnumDisplaySettingsExA
)(LPCSTR
, DWORD
, DEVMODEA
*, DWORD
);
34 static LONG (WINAPI
*pChangeDisplaySettingsExA
)(LPCSTR
, LPDEVMODE
, HWND
, DWORD
, LPVOID
);
36 static IDirect3D9
* (WINAPI
*pDirect3DCreate9
)(UINT SDKVersion
);
37 static HRESULT (WINAPI
*pDirect3DCreate9Ex
)(UINT SDKVersion
, IDirect3D9Ex
**d3d9ex
);
39 static HWND
create_window(void)
43 wc
.lpfnWndProc
= DefWindowProc
;
44 wc
.lpszClassName
= "d3d9_test_wc";
47 ret
= CreateWindow("d3d9_test_wc", "d3d9_test",
48 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
52 static ULONG
getref(IUnknown
*obj
) {
54 return IUnknown_Release(obj
);
57 static void test_qi_base_to_ex(void)
59 IDirect3D9
*d3d9
= pDirect3DCreate9(D3D_SDK_VERSION
);
60 IDirect3D9Ex
*d3d9ex
= (void *) 0xdeadbeef;
61 IDirect3DDevice9
*device
;
62 IDirect3DDevice9Ex
*deviceEx
= (void *) 0xdeadbeef;
64 HWND window
= create_window();
65 D3DPRESENT_PARAMETERS present_parameters
;
69 skip("Direct3D9 is not available\n");
73 hr
= IDirect3D9_QueryInterface(d3d9
, &IID_IDirect3D9Ex
, (void **) &d3d9ex
);
74 ok(hr
== E_NOINTERFACE
,
75 "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n",
77 ok(d3d9ex
== NULL
, "QueryInterface returned interface %p, expected NULL\n", d3d9ex
);
78 if(d3d9ex
) IDirect3D9Ex_Release(d3d9ex
);
80 memset(&present_parameters
, 0, sizeof(present_parameters
));
81 present_parameters
.Windowed
= TRUE
;
82 present_parameters
.hDeviceWindow
= window
;
83 present_parameters
.SwapEffect
= D3DSWAPEFFECT_COPY
;
84 present_parameters
.BackBufferWidth
= 640;
85 present_parameters
.BackBufferHeight
= 480;
86 present_parameters
.EnableAutoDepthStencil
= FALSE
;
87 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
88 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
90 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
94 hr
= IDirect3DDevice9_QueryInterface(device
, &IID_IDirect3DDevice9Ex
, (void **) &deviceEx
);
95 ok(hr
== E_NOINTERFACE
,
96 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n",
98 ok(deviceEx
== NULL
, "QueryInterface returned interface %p, expected NULL\n", deviceEx
);
99 if(deviceEx
) IDirect3DDevice9Ex_Release(deviceEx
);
101 IDirect3DDevice9_Release(device
);
104 IDirect3D9_Release(d3d9
);
105 DestroyWindow(window
);
108 static void test_qi_ex_to_base(void)
110 IDirect3D9
*d3d9
= (void *) 0xdeadbeef;
111 IDirect3D9Ex
*d3d9ex
;
112 IDirect3DDevice9
*device
;
113 IDirect3DDevice9Ex
*deviceEx
= (void *) 0xdeadbeef;
115 HWND window
= create_window();
116 D3DPRESENT_PARAMETERS present_parameters
;
119 hr
= pDirect3DCreate9Ex(D3D_SDK_VERSION
, &d3d9ex
);
120 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Direct3DCreate9Ex returned %08x\n", hr
);
122 skip("Direct3D9Ex is not available\n");
126 hr
= IDirect3D9Ex_QueryInterface(d3d9ex
, &IID_IDirect3D9
, (void **) &d3d9
);
128 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
130 ok(d3d9
!= NULL
&& d3d9
!= (void *) 0xdeadbeef,
131 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9
);
132 ref
= getref((IUnknown
*) d3d9ex
);
133 ok(ref
== 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref
);
134 ref
= getref((IUnknown
*) d3d9
);
135 ok(ref
== 2, "IDirect3D9 refcount is %d, expected 2\n", ref
);
137 memset(&present_parameters
, 0, sizeof(present_parameters
));
138 present_parameters
.Windowed
= TRUE
;
139 present_parameters
.hDeviceWindow
= window
;
140 present_parameters
.SwapEffect
= D3DSWAPEFFECT_COPY
;
141 present_parameters
.BackBufferWidth
= 640;
142 present_parameters
.BackBufferHeight
= 480;
143 present_parameters
.EnableAutoDepthStencil
= FALSE
;
144 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
146 /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
147 hr
= IDirect3D9Ex_CreateDevice(d3d9ex
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
149 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
153 hr
= IDirect3DDevice9_QueryInterface(device
, &IID_IDirect3DDevice9Ex
, (void **) &deviceEx
);
155 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
157 ok(deviceEx
!= NULL
&& deviceEx
!= (void *) 0xdeadbeef,
158 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx
);
159 ref
= getref((IUnknown
*) device
);
160 ok(ref
== 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref
);
161 ref
= getref((IUnknown
*) deviceEx
);
162 ok(ref
== 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref
);
163 if(deviceEx
) IDirect3DDevice9Ex_Release(deviceEx
);
164 IDirect3DDevice9_Release(device
);
166 /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
167 hr
= IDirect3D9_CreateDevice(d3d9
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, present_parameters
.hDeviceWindow
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
169 skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n");
173 hr
= IDirect3DDevice9_QueryInterface(device
, &IID_IDirect3DDevice9Ex
, (void **) &deviceEx
);
175 "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n",
177 ok(deviceEx
!= NULL
&& deviceEx
!= (void *) 0xdeadbeef,
178 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx
);
179 ref
= getref((IUnknown
*) device
);
180 ok(ref
== 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref
);
181 ref
= getref((IUnknown
*) deviceEx
);
182 ok(ref
== 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref
);
183 if(deviceEx
) IDirect3DDevice9Ex_Release(deviceEx
);
184 IDirect3DDevice9_Release(device
);
186 IDirect3D9_Release(d3d9
);
187 IDirect3D9Ex_Release(d3d9ex
);
190 DestroyWindow(window
);
193 static void test_get_adapter_luid(void)
195 HWND window
= create_window();
196 IDirect3D9Ex
*d3d9ex
;
201 hr
= pDirect3DCreate9Ex(D3D_SDK_VERSION
, &d3d9ex
);
204 skip("Direct3D9Ex is not available.\n");
205 DestroyWindow(window
);
209 count
= IDirect3D9Ex_GetAdapterCount(d3d9ex
);
212 skip("No adapters available.\n");
213 IDirect3D9Ex_Release(d3d9ex
);
214 DestroyWindow(window
);
218 hr
= IDirect3D9Ex_GetAdapterLUID(d3d9ex
, D3DADAPTER_DEFAULT
, &luid
);
219 ok(SUCCEEDED(hr
), "GetAdapterLUID failed, hr %#x.\n", hr
);
220 trace("adapter luid: %08x:%08x.\n", luid
.HighPart
, luid
.LowPart
);
222 IDirect3D9Ex_Release(d3d9ex
);
225 static void test_get_adapter_displaymode_ex(void)
227 HWND window
= create_window();
228 IDirect3D9
*d3d9
= (void *) 0xdeadbeef;
229 IDirect3D9Ex
*d3d9ex
;
233 D3DDISPLAYMODEEX mode_ex
;
234 D3DDISPLAYROTATION rotation
;
239 hr
= pDirect3DCreate9Ex(D3D_SDK_VERSION
, &d3d9ex
);
242 skip("Direct3D9Ex is not available (%#x)\n", hr
);
243 DestroyWindow(window
);
247 count
= IDirect3D9Ex_GetAdapterCount(d3d9ex
);
250 skip("No adapters available.\n");
251 IDirect3D9Ex_Release(d3d9ex
);
252 DestroyWindow(window
);
256 hr
= IDirect3D9Ex_QueryInterface(d3d9ex
, &IID_IDirect3D9
, (void **) &d3d9
);
258 "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n",
260 ok(d3d9
!= NULL
&& d3d9
!= (void *) 0xdeadbeef,
261 "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9
);
262 /* change displayorientation*/
263 hdll
= GetModuleHandleA("user32.dll");
264 pEnumDisplaySettingsExA
= (void*)GetProcAddress(hdll
, "EnumDisplaySettingsExA");
265 pChangeDisplaySettingsExA
= (void*)GetProcAddress(hdll
, "ChangeDisplaySettingsExA");
267 if (!pEnumDisplaySettingsExA
|| !pChangeDisplaySettingsExA
) goto out
;
269 memset(&startmode
, 0, sizeof(startmode
));
270 startmode
.dmSize
= sizeof(startmode
);
271 retval
= pEnumDisplaySettingsExA(NULL
, ENUM_CURRENT_SETTINGS
, &startmode
, 0);
272 ok(retval
, "Failed to retrieve current display mode, retval %d.\n", retval
);
273 if (!retval
) goto out
;
275 startmode
.dmFields
= DM_DISPLAYORIENTATION
| DM_PELSWIDTH
| DM_PELSHEIGHT
;
276 S2(U1(startmode
)).dmDisplayOrientation
= DMDO_180
;
277 retval
= pChangeDisplaySettingsExA(NULL
, &startmode
, NULL
, 0, NULL
);
279 if(retval
== DISP_CHANGE_BADMODE
)
281 trace(" Test skipped: graphics mode is not supported\n");
285 ok(retval
== DISP_CHANGE_SUCCESSFUL
,"ChangeDisplaySettingsEx failed with %d\n", retval
);
286 /* try retrieve orientation info with EnumDisplaySettingsEx*/
287 startmode
.dmFields
= 0;
288 S2(U1(startmode
)).dmDisplayOrientation
= 0;
289 ok(pEnumDisplaySettingsExA(NULL
, ENUM_CURRENT_SETTINGS
, &startmode
, EDS_ROTATEDMODE
), "EnumDisplaySettingsEx failed\n");
291 /*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
292 memset(&mode_ex
, 0, sizeof(mode_ex
));
293 hr
= IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex
, D3DADAPTER_DEFAULT
, &mode_ex
, &rotation
);
294 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr
);
296 mode_ex
.Size
= sizeof(D3DDISPLAYMODEEX
);
298 hr
= IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex
, count
+ 1, &mode_ex
, &rotation
);
299 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr
);
300 /*valid count and valid Size*/
301 hr
= IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex
, D3DADAPTER_DEFAULT
, &mode_ex
, &rotation
);
302 todo_wine
ok(SUCCEEDED(hr
), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr
);
304 /* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
305 hr
= IDirect3D9_GetAdapterDisplayMode(d3d9
, D3DADAPTER_DEFAULT
, &mode
);
306 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#x.\n", hr
);
308 ok(mode_ex
.Size
== sizeof(D3DDISPLAYMODEEX
), "size is %d\n", mode_ex
.Size
);
309 todo_wine
ok(mode_ex
.Width
== mode
.Width
, "width is %d instead of %d\n", mode_ex
.Width
, mode
.Width
);
310 todo_wine
ok(mode_ex
.Height
== mode
.Height
, "height is %d instead of %d\n", mode_ex
.Height
, mode
.Height
);
311 todo_wine
ok(mode_ex
.RefreshRate
== mode
.RefreshRate
, "RefreshRate is %d instead of %d\n", mode_ex
.RefreshRate
, mode
.RefreshRate
);
312 todo_wine
ok(mode_ex
.Format
== mode
.Format
, "format is %x instead of %x\n", mode_ex
.Format
, mode
.Format
);
313 /* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
314 todo_wine
ok(mode_ex
.ScanLineOrdering
!= 0, "ScanLineOrdering returned 0\n");
315 /* check that orientation is returned correctly by GetAdapterDisplayModeEx and EnumDisplaySettingsEx*/
316 todo_wine
ok(S2(U1(startmode
)).dmDisplayOrientation
== DMDO_180
&& rotation
== D3DDISPLAYROTATION_180
, "rotation is %d instead of %d\n", rotation
, S2(U1(startmode
)).dmDisplayOrientation
);
318 trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
319 mode_ex
.Width
, mode_ex
.Height
, mode_ex
.RefreshRate
, mode_ex
.Format
, mode_ex
.ScanLineOrdering
, rotation
);
321 /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
322 memset(&mode_ex
, 0, sizeof(mode_ex
));
323 mode_ex
.Size
= sizeof(D3DDISPLAYMODEEX
);
325 hr
= IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex
, D3DADAPTER_DEFAULT
, &mode_ex
, NULL
);
326 todo_wine
ok(SUCCEEDED(hr
), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr
);
328 ok(mode_ex
.Size
== sizeof(D3DDISPLAYMODEEX
), "size is %d\n", mode_ex
.Size
);
329 todo_wine
ok(mode_ex
.Width
== mode
.Width
, "width is %d instead of %d\n", mode_ex
.Width
, mode
.Width
);
330 todo_wine
ok(mode_ex
.Height
== mode
.Height
, "height is %d instead of %d\n", mode_ex
.Height
, mode
.Height
);
331 todo_wine
ok(mode_ex
.RefreshRate
== mode
.RefreshRate
, "RefreshRate is %d instead of %d\n", mode_ex
.RefreshRate
, mode
.RefreshRate
);
332 todo_wine
ok(mode_ex
.Format
== mode
.Format
, "format is %x instead of %x\n", mode_ex
.Format
, mode
.Format
);
333 /* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
334 todo_wine
ok(mode_ex
.ScanLineOrdering
!= 0, "ScanLineOrdering returned 0\n");
336 /* return to the default mode */
337 pChangeDisplaySettingsExA(NULL
, NULL
, NULL
, 0, NULL
);
339 IDirect3D9_Release(d3d9
);
340 IDirect3D9Ex_Release(d3d9ex
);
345 d3d9_handle
= LoadLibraryA("d3d9.dll");
348 skip("Could not load d3d9.dll\n");
351 pDirect3DCreate9
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
352 ok(pDirect3DCreate9
!= NULL
, "Failed to get address of Direct3DCreate9\n");
353 if(!pDirect3DCreate9
) {
357 pDirect3DCreate9Ex
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9Ex");
358 if (!pDirect3DCreate9Ex
) {
359 win_skip("Failed to get address of Direct3DCreate9Ex\n");
363 test_qi_base_to_ex();
364 test_qi_ex_to_base();
365 test_get_adapter_luid();
366 test_get_adapter_displaymode_ex();