2008-02-28 21:31:25 +01:00
/*
2008-10-18 19:19:23 +02:00
* Copyright ( C ) 2008 Stefan Dösinger ( for CodeWeavers )
2010-07-09 13:25:56 +02:00
* Copyright ( C ) 2010 Louis Lenders
2008-02-28 21:31:25 +01:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
*/
/* This file contains tests specific to IDirect3D9Ex and IDirect3DDevice9Ex, like
* how to obtain them . For testing rendering with extended functions use visual . c
*/
# define COBJMACROS
2010-07-09 13:25:56 +02:00
# include "wine/test.h"
# include "winuser.h"
# include "wingdi.h"
2008-07-08 16:17:17 +02:00
# include <initguid.h>
2008-02-28 21:31:25 +01:00
# include <d3d9.h>
static HMODULE d3d9_handle = 0 ;
2010-07-09 13:25:56 +02:00
static BOOL ( WINAPI * pEnumDisplaySettingsExA ) ( LPCSTR , DWORD , DEVMODEA * , DWORD ) ;
static LONG ( WINAPI * pChangeDisplaySettingsExA ) ( LPCSTR , LPDEVMODE , HWND , DWORD , LPVOID ) ;
2008-02-28 21:31:25 +01:00
static IDirect3D9 * ( WINAPI * pDirect3DCreate9 ) ( UINT SDKVersion ) ;
static HRESULT ( WINAPI * pDirect3DCreate9Ex ) ( UINT SDKVersion , IDirect3D9Ex * * d3d9ex ) ;
static HWND create_window ( void )
{
WNDCLASS wc = { 0 } ;
HWND ret ;
2008-06-04 05:04:20 +02:00
wc . lpfnWndProc = DefWindowProc ;
2008-02-28 21:31:25 +01:00
wc . lpszClassName = " d3d9_test_wc " ;
RegisterClass ( & wc ) ;
ret = CreateWindow ( " d3d9_test_wc " , " d3d9_test " ,
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0 , 0 , 640 , 480 , 0 , 0 , 0 , 0 ) ;
return ret ;
}
2009-03-18 10:55:22 +01:00
static ULONG getref ( IUnknown * obj ) {
2008-02-28 21:31:25 +01:00
IUnknown_AddRef ( obj ) ;
return IUnknown_Release ( obj ) ;
}
static void test_qi_base_to_ex ( void )
{
IDirect3D9 * d3d9 = pDirect3DCreate9 ( D3D_SDK_VERSION ) ;
IDirect3D9Ex * d3d9ex = ( void * ) 0xdeadbeef ;
IDirect3DDevice9 * device ;
IDirect3DDevice9Ex * deviceEx = ( void * ) 0xdeadbeef ;
HRESULT hr ;
HWND window = create_window ( ) ;
D3DPRESENT_PARAMETERS present_parameters ;
2008-12-03 18:00:40 +01:00
if ( ! d3d9 )
{
skip ( " Direct3D9 is not available \n " ) ;
return ;
}
2008-06-24 11:09:47 +02:00
2008-02-28 21:31:25 +01:00
hr = IDirect3D9_QueryInterface ( d3d9 , & IID_IDirect3D9Ex , ( void * * ) & d3d9ex ) ;
ok ( hr = = E_NOINTERFACE ,
2008-07-08 17:48:50 +02:00
" IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE \n " ,
hr ) ;
2008-02-28 21:31:25 +01:00
ok ( d3d9ex = = NULL , " QueryInterface returned interface %p, expected NULL \n " , d3d9ex ) ;
if ( d3d9ex ) IDirect3D9Ex_Release ( d3d9ex ) ;
memset ( & present_parameters , 0 , sizeof ( present_parameters ) ) ;
present_parameters . Windowed = TRUE ;
present_parameters . hDeviceWindow = window ;
present_parameters . SwapEffect = D3DSWAPEFFECT_COPY ;
present_parameters . BackBufferWidth = 640 ;
present_parameters . BackBufferHeight = 480 ;
present_parameters . EnableAutoDepthStencil = FALSE ;
present_parameters . AutoDepthStencilFormat = D3DFMT_D16 ;
hr = IDirect3D9_CreateDevice ( d3d9 , D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL , present_parameters . hDeviceWindow , D3DCREATE_SOFTWARE_VERTEXPROCESSING , & present_parameters , & device ) ;
if ( FAILED ( hr ) ) {
skip ( " Failed to create a regular Direct3DDevice9, skipping QI tests \n " ) ;
goto out ;
}
hr = IDirect3DDevice9_QueryInterface ( device , & IID_IDirect3DDevice9Ex , ( void * * ) & deviceEx ) ;
ok ( hr = = E_NOINTERFACE ,
2008-07-08 17:48:50 +02:00
" IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE \n " ,
hr ) ;
2008-02-28 21:31:25 +01:00
ok ( deviceEx = = NULL , " QueryInterface returned interface %p, expected NULL \n " , deviceEx ) ;
if ( deviceEx ) IDirect3DDevice9Ex_Release ( deviceEx ) ;
IDirect3DDevice9_Release ( device ) ;
out :
IDirect3D9_Release ( d3d9 ) ;
DestroyWindow ( window ) ;
}
static void test_qi_ex_to_base ( void )
{
IDirect3D9 * d3d9 = ( void * ) 0xdeadbeef ;
IDirect3D9Ex * d3d9ex ;
IDirect3DDevice9 * device ;
IDirect3DDevice9Ex * deviceEx = ( void * ) 0xdeadbeef ;
HRESULT hr ;
HWND window = create_window ( ) ;
D3DPRESENT_PARAMETERS present_parameters ;
2009-03-18 10:55:22 +01:00
ULONG ref ;
2008-02-28 21:31:25 +01:00
hr = pDirect3DCreate9Ex ( D3D_SDK_VERSION , & d3d9ex ) ;
2008-07-08 17:48:50 +02:00
ok ( hr = = D3D_OK | | hr = = D3DERR_NOTAVAILABLE , " Direct3DCreate9Ex returned %08x \n " , hr ) ;
2008-02-28 21:31:25 +01:00
if ( FAILED ( hr ) ) {
skip ( " Direct3D9Ex is not available \n " ) ;
goto out ;
}
hr = IDirect3D9Ex_QueryInterface ( d3d9ex , & IID_IDirect3D9 , ( void * * ) & d3d9 ) ;
ok ( hr = = D3D_OK ,
2008-07-08 17:48:50 +02:00
" IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK \n " ,
hr ) ;
2008-02-28 21:31:25 +01:00
ok ( d3d9 ! = NULL & & d3d9 ! = ( void * ) 0xdeadbeef ,
" QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef \n " , d3d9 ) ;
ref = getref ( ( IUnknown * ) d3d9ex ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3D9Ex refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
ref = getref ( ( IUnknown * ) d3d9 ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3D9 refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
memset ( & present_parameters , 0 , sizeof ( present_parameters ) ) ;
present_parameters . Windowed = TRUE ;
present_parameters . hDeviceWindow = window ;
present_parameters . SwapEffect = D3DSWAPEFFECT_COPY ;
present_parameters . BackBufferWidth = 640 ;
present_parameters . BackBufferHeight = 480 ;
present_parameters . EnableAutoDepthStencil = FALSE ;
present_parameters . AutoDepthStencilFormat = D3DFMT_D16 ;
/* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */
hr = IDirect3D9Ex_CreateDevice ( d3d9ex , D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL , present_parameters . hDeviceWindow , D3DCREATE_SOFTWARE_VERTEXPROCESSING , & present_parameters , & device ) ;
if ( FAILED ( hr ) ) {
skip ( " Failed to create a regular Direct3DDevice9, skipping QI tests \n " ) ;
goto out ;
}
hr = IDirect3DDevice9_QueryInterface ( device , & IID_IDirect3DDevice9Ex , ( void * * ) & deviceEx ) ;
ok ( hr = = D3D_OK ,
2008-07-08 17:48:50 +02:00
" IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK \n " ,
hr ) ;
2008-02-28 21:31:25 +01:00
ok ( deviceEx ! = NULL & & deviceEx ! = ( void * ) 0xdeadbeef ,
" QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef \n " , deviceEx ) ;
ref = getref ( ( IUnknown * ) device ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3DDevice9 refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
ref = getref ( ( IUnknown * ) deviceEx ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3DDevice9Ex refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
if ( deviceEx ) IDirect3DDevice9Ex_Release ( deviceEx ) ;
IDirect3DDevice9_Release ( device ) ;
/* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */
hr = IDirect3D9_CreateDevice ( d3d9 , D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL , present_parameters . hDeviceWindow , D3DCREATE_SOFTWARE_VERTEXPROCESSING , & present_parameters , & device ) ;
if ( FAILED ( hr ) ) {
skip ( " Failed to create a regular Direct3DDevice9, skipping QI tests \n " ) ;
goto out ;
}
hr = IDirect3DDevice9_QueryInterface ( device , & IID_IDirect3DDevice9Ex , ( void * * ) & deviceEx ) ;
ok ( hr = = D3D_OK ,
2008-07-08 17:48:50 +02:00
" IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK \n " ,
hr ) ;
2008-02-28 21:31:25 +01:00
ok ( deviceEx ! = NULL & & deviceEx ! = ( void * ) 0xdeadbeef ,
" QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef \n " , deviceEx ) ;
ref = getref ( ( IUnknown * ) device ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3DDevice9 refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
ref = getref ( ( IUnknown * ) deviceEx ) ;
2009-03-18 10:55:22 +01:00
ok ( ref = = 2 , " IDirect3DDevice9Ex refcount is %d, expected 2 \n " , ref ) ;
2008-02-28 21:31:25 +01:00
if ( deviceEx ) IDirect3DDevice9Ex_Release ( deviceEx ) ;
IDirect3DDevice9_Release ( device ) ;
IDirect3D9_Release ( d3d9 ) ;
2009-10-23 10:26:09 +02:00
IDirect3D9Ex_Release ( d3d9ex ) ;
2008-02-28 21:31:25 +01:00
out :
DestroyWindow ( window ) ;
}
2009-12-02 10:41:24 +01:00
static void test_get_adapter_luid ( void )
{
HWND window = create_window ( ) ;
IDirect3D9Ex * d3d9ex ;
UINT count ;
HRESULT hr ;
LUID luid ;
hr = pDirect3DCreate9Ex ( D3D_SDK_VERSION , & d3d9ex ) ;
if ( FAILED ( hr ) )
{
skip ( " Direct3D9Ex is not available. \n " ) ;
DestroyWindow ( window ) ;
return ;
}
count = IDirect3D9Ex_GetAdapterCount ( d3d9ex ) ;
if ( ! count )
{
skip ( " No adapters available. \n " ) ;
IDirect3D9Ex_Release ( d3d9ex ) ;
DestroyWindow ( window ) ;
return ;
}
hr = IDirect3D9Ex_GetAdapterLUID ( d3d9ex , D3DADAPTER_DEFAULT , & luid ) ;
ok ( SUCCEEDED ( hr ) , " GetAdapterLUID failed, hr %#x. \n " , hr ) ;
trace ( " adapter luid: %08x:%08x. \n " , luid . HighPart , luid . LowPart ) ;
IDirect3D9Ex_Release ( d3d9ex ) ;
}
2010-07-09 13:25:56 +02:00
static void test_get_adapter_displaymode_ex ( void )
{
HWND window = create_window ( ) ;
IDirect3D9 * d3d9 = ( void * ) 0xdeadbeef ;
IDirect3D9Ex * d3d9ex ;
UINT count ;
HRESULT hr ;
D3DDISPLAYMODE mode ;
D3DDISPLAYMODEEX mode_ex ;
D3DDISPLAYROTATION rotation ;
HANDLE hdll ;
DEVMODEA startmode ;
LONG retval ;
hr = pDirect3DCreate9Ex ( D3D_SDK_VERSION , & d3d9ex ) ;
if ( FAILED ( hr ) )
{
skip ( " Direct3D9Ex is not available (%#x) \n " , hr ) ;
DestroyWindow ( window ) ;
return ;
}
count = IDirect3D9Ex_GetAdapterCount ( d3d9ex ) ;
if ( ! count )
{
skip ( " No adapters available. \n " ) ;
IDirect3D9Ex_Release ( d3d9ex ) ;
DestroyWindow ( window ) ;
return ;
}
hr = IDirect3D9Ex_QueryInterface ( d3d9ex , & IID_IDirect3D9 , ( void * * ) & d3d9 ) ;
ok ( hr = = D3D_OK ,
" IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK \n " ,
hr ) ;
ok ( d3d9 ! = NULL & & d3d9 ! = ( void * ) 0xdeadbeef ,
" QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef \n " , d3d9 ) ;
/* change displayorientation*/
hdll = GetModuleHandleA ( " user32.dll " ) ;
pEnumDisplaySettingsExA = ( void * ) GetProcAddress ( hdll , " EnumDisplaySettingsExA " ) ;
pChangeDisplaySettingsExA = ( void * ) GetProcAddress ( hdll , " ChangeDisplaySettingsExA " ) ;
if ( ! pEnumDisplaySettingsExA | | ! pChangeDisplaySettingsExA ) goto out ;
memset ( & startmode , 0 , sizeof ( startmode ) ) ;
startmode . dmSize = sizeof ( startmode ) ;
2010-11-09 11:38:41 +01:00
retval = pEnumDisplaySettingsExA ( NULL , ENUM_CURRENT_SETTINGS , & startmode , 0 ) ;
ok ( retval , " Failed to retrieve current display mode, retval %d. \n " , retval ) ;
if ( ! retval ) goto out ;
2010-07-09 13:25:56 +02:00
2010-11-09 11:38:41 +01:00
startmode . dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT ;
S2 ( U1 ( startmode ) ) . dmDisplayOrientation = DMDO_180 ;
2010-07-09 13:25:56 +02:00
retval = pChangeDisplaySettingsExA ( NULL , & startmode , NULL , 0 , NULL ) ;
if ( retval = = DISP_CHANGE_BADMODE )
{
trace ( " Test skipped: graphics mode is not supported \n " ) ;
goto out ;
}
ok ( retval = = DISP_CHANGE_SUCCESSFUL , " ChangeDisplaySettingsEx failed with %d \n " , retval ) ;
/* try retrieve orientation info with EnumDisplaySettingsEx*/
startmode . dmFields = 0 ;
2010-08-29 23:38:14 +02:00
S2 ( U1 ( startmode ) ) . dmDisplayOrientation = 0 ;
2010-07-09 13:25:56 +02:00
ok ( pEnumDisplaySettingsExA ( NULL , ENUM_CURRENT_SETTINGS , & startmode , EDS_ROTATEDMODE ) , " EnumDisplaySettingsEx failed \n " ) ;
/*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
memset ( & mode_ex , 0 , sizeof ( mode_ex ) ) ;
hr = IDirect3D9Ex_GetAdapterDisplayModeEx ( d3d9ex , D3DADAPTER_DEFAULT , & mode_ex , & rotation ) ;
todo_wine ok ( hr = = D3DERR_INVALIDCALL , " GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL \n " , hr ) ;
mode_ex . Size = sizeof ( D3DDISPLAYMODEEX ) ;
/* invalid count*/
hr = IDirect3D9Ex_GetAdapterDisplayModeEx ( d3d9ex , count + 1 , & mode_ex , & rotation ) ;
todo_wine ok ( hr = = D3DERR_INVALIDCALL , " GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL \n " , hr ) ;
/*valid count and valid Size*/
hr = IDirect3D9Ex_GetAdapterDisplayModeEx ( d3d9ex , D3DADAPTER_DEFAULT , & mode_ex , & rotation ) ;
todo_wine ok ( SUCCEEDED ( hr ) , " GetAdapterDisplayModeEx failed, hr %#x. \n " , hr ) ;
/* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
hr = IDirect3D9_GetAdapterDisplayMode ( d3d9 , D3DADAPTER_DEFAULT , & mode ) ;
ok ( SUCCEEDED ( hr ) , " GetAdapterDisplayMode failed, hr %#x. \n " , hr ) ;
2010-07-21 11:06:32 +02:00
ok ( mode_ex . Size = = sizeof ( D3DDISPLAYMODEEX ) , " size is %d \n " , mode_ex . Size ) ;
2010-07-09 13:25:56 +02:00
todo_wine ok ( mode_ex . Width = = mode . Width , " width is %d instead of %d \n " , mode_ex . Width , mode . Width ) ;
todo_wine ok ( mode_ex . Height = = mode . Height , " height is %d instead of %d \n " , mode_ex . Height , mode . Height ) ;
todo_wine ok ( mode_ex . RefreshRate = = mode . RefreshRate , " RefreshRate is %d instead of %d \n " , mode_ex . RefreshRate , mode . RefreshRate ) ;
todo_wine ok ( mode_ex . Format = = mode . Format , " format is %x instead of %x \n " , mode_ex . Format , mode . Format ) ;
/* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
todo_wine ok ( mode_ex . ScanLineOrdering ! = 0 , " ScanLineOrdering returned 0 \n " ) ;
/* check that orientation is returned correctly by GetAdapterDisplayModeEx and EnumDisplaySettingsEx*/
2010-08-29 23:38:14 +02:00
todo_wine ok ( S2 ( U1 ( startmode ) ) . dmDisplayOrientation = = DMDO_180 & & rotation = = D3DDISPLAYROTATION_180 , " rotation is %d instead of %d \n " , rotation , S2 ( U1 ( startmode ) ) . dmDisplayOrientation ) ;
2010-07-09 13:25:56 +02:00
trace ( " GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d \n " ,
mode_ex . Width , mode_ex . Height , mode_ex . RefreshRate , mode_ex . Format , mode_ex . ScanLineOrdering , rotation ) ;
2010-07-25 21:05:55 +02:00
/* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */
memset ( & mode_ex , 0 , sizeof ( mode_ex ) ) ;
mode_ex . Size = sizeof ( D3DDISPLAYMODEEX ) ;
hr = IDirect3D9Ex_GetAdapterDisplayModeEx ( d3d9ex , D3DADAPTER_DEFAULT , & mode_ex , NULL ) ;
todo_wine ok ( SUCCEEDED ( hr ) , " GetAdapterDisplayModeEx failed, hr %#x. \n " , hr ) ;
ok ( mode_ex . Size = = sizeof ( D3DDISPLAYMODEEX ) , " size is %d \n " , mode_ex . Size ) ;
todo_wine ok ( mode_ex . Width = = mode . Width , " width is %d instead of %d \n " , mode_ex . Width , mode . Width ) ;
todo_wine ok ( mode_ex . Height = = mode . Height , " height is %d instead of %d \n " , mode_ex . Height , mode . Height ) ;
todo_wine ok ( mode_ex . RefreshRate = = mode . RefreshRate , " RefreshRate is %d instead of %d \n " , mode_ex . RefreshRate , mode . RefreshRate ) ;
todo_wine ok ( mode_ex . Format = = mode . Format , " format is %x instead of %x \n " , mode_ex . Format , mode . Format ) ;
/* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
todo_wine ok ( mode_ex . ScanLineOrdering ! = 0 , " ScanLineOrdering returned 0 \n " ) ;
/* return to the default mode */
pChangeDisplaySettingsExA ( NULL , NULL , NULL , 0 , NULL ) ;
2010-07-09 13:25:56 +02:00
out :
IDirect3D9_Release ( d3d9 ) ;
IDirect3D9Ex_Release ( d3d9ex ) ;
}
2008-02-28 21:31:25 +01:00
START_TEST ( d3d9ex )
{
d3d9_handle = LoadLibraryA ( " d3d9.dll " ) ;
if ( ! d3d9_handle )
{
skip ( " Could not load d3d9.dll \n " ) ;
return ;
}
pDirect3DCreate9 = ( void * ) GetProcAddress ( d3d9_handle , " Direct3DCreate9 " ) ;
ok ( pDirect3DCreate9 ! = NULL , " Failed to get address of Direct3DCreate9 \n " ) ;
if ( ! pDirect3DCreate9 ) {
return ;
}
pDirect3DCreate9Ex = ( void * ) GetProcAddress ( d3d9_handle , " Direct3DCreate9Ex " ) ;
if ( ! pDirect3DCreate9Ex ) {
2009-02-25 10:27:26 +01:00
win_skip ( " Failed to get address of Direct3DCreate9Ex \n " ) ;
2008-02-28 21:31:25 +01:00
return ;
}
test_qi_base_to_ex ( ) ;
test_qi_ex_to_base ( ) ;
2009-12-02 10:41:24 +01:00
test_get_adapter_luid ( ) ;
2010-07-09 13:25:56 +02:00
test_get_adapter_displaymode_ex ( ) ;
2008-02-28 21:31:25 +01:00
}