Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygend3d9_impl.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS ReactX 00004 * FILE: dll/directx/d3d9/d3d9_impl.c 00005 * PURPOSE: IDirect3D9 implementation 00006 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se> 00007 */ 00008 00009 #include "d3d9_common.h" 00010 #include <d3d9.h> 00011 #include <debug.h> 00012 #include "d3d9_helpers.h" 00013 #include "adapter.h" 00014 #include "device.h" 00015 #include "format.h" 00016 00017 #define LOCK_D3D9() EnterCriticalSection(&This->d3d9_cs); 00018 #define UNLOCK_D3D9() LeaveCriticalSection(&This->d3d9_cs); 00019 00020 /* Convert a IDirect3D9 pointer safely to the internal implementation struct */ 00021 static LPDIRECT3D9_INT IDirect3D9ToImpl(LPDIRECT3D9 iface) 00022 { 00023 if (NULL == iface) 00024 return NULL; 00025 00026 return (LPDIRECT3D9_INT)((ULONG_PTR)iface - FIELD_OFFSET(DIRECT3D9_INT, lpVtbl)); 00027 } 00028 00029 /* IDirect3D9: IUnknown implementation */ 00030 static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9 iface, REFIID riid, LPVOID* ppvObject) 00031 { 00032 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00033 00034 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3D9)) 00035 { 00036 IUnknown_AddRef(iface); 00037 *ppvObject = &This->lpVtbl; 00038 return S_OK; 00039 } 00040 00041 *ppvObject = NULL; 00042 return E_NOINTERFACE; 00043 } 00044 00045 static ULONG WINAPI IDirect3D9Impl_AddRef(LPDIRECT3D9 iface) 00046 { 00047 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00048 ULONG ref = InterlockedIncrement(&This->lRefCnt); 00049 00050 return ref; 00051 } 00052 00053 static ULONG WINAPI IDirect3D9Impl_Release(LPDIRECT3D9 iface) 00054 { 00055 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00056 ULONG ref = InterlockedDecrement(&This->lRefCnt); 00057 00058 if (ref == 0) 00059 { 00060 EnterCriticalSection(&This->d3d9_cs); 00061 /* TODO: Free resources here */ 00062 LeaveCriticalSection(&This->d3d9_cs); 00063 AlignedFree(This); 00064 } 00065 00066 return ref; 00067 } 00068 00069 /* IDirect3D9 interface */ 00070 static HRESULT WINAPI IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9 iface, void* pInitializeFunction) 00071 { 00072 UNIMPLEMENTED 00073 00074 return D3D_OK; 00075 } 00076 00077 /*++ 00078 * @name IDirect3D9::GetAdapterCount 00079 * @implemented 00080 * 00081 * The function IDirect3D9Impl_GetAdapterCount returns the number of adapters 00082 * 00083 * @param LPDIRECT3D iface 00084 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00085 * 00086 * @return UINT 00087 * The number of display adapters on the system when Direct3DCreate9() was called. 00088 * 00089 */ 00090 static UINT WINAPI IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9 iface) 00091 { 00092 UINT NumDisplayAdapters; 00093 00094 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00095 LOCK_D3D9(); 00096 00097 NumDisplayAdapters = This->NumDisplayAdapters; 00098 00099 UNLOCK_D3D9(); 00100 return NumDisplayAdapters; 00101 } 00102 00103 /*++ 00104 * @name IDirect3D9::GetAdapterIdentifier 00105 * @implemented 00106 * 00107 * The function IDirect3D9Impl_GetAdapterIdentifier gathers information about 00108 * a specified display adapter and fills the pIdentifier argument with the available information. 00109 * 00110 * @param LPDIRECT3D iface 00111 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00112 * 00113 * @param UINT Adapter 00114 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00115 * The maximum value for this is the value returned by IDirect3D::GetAdapterCount() - 1. 00116 * 00117 * @param DWORD Flags 00118 * Ignored at the moment, but the only valid flag is D3DENUM_WHQL_LEVEL 00119 * 00120 * @param D3DADAPTER_IDENTIFIER9* pIdentifier 00121 * Pointer to a D3DADAPTER_IDENTIFIER9 structure to be filled with the available information 00122 * about the display adapter. 00123 * 00124 * @return HRESULT 00125 * If the method successfully fills the pIdentified structure, the return value is D3D_OK. 00126 * If Adapter is out of range, Flags is invalid or pIdentifier is a bad pointer, the return value 00127 * will be D3DERR_INVALIDCALL. 00128 * 00129 */ 00130 HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags, 00131 D3DADAPTER_IDENTIFIER9* pIdentifier) 00132 { 00133 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00134 LOCK_D3D9(); 00135 00136 if (Adapter >= This->NumDisplayAdapters) 00137 { 00138 DPRINT1("Invalid Adapter number specified"); 00139 UNLOCK_D3D9(); 00140 return D3DERR_INVALIDCALL; 00141 } 00142 00143 if (Flags & ~D3DENUM_WHQL_LEVEL) 00144 { 00145 DPRINT1("Invalid Flags specified"); 00146 UNLOCK_D3D9(); 00147 return D3DERR_INVALIDCALL; 00148 } 00149 00150 if (NULL == pIdentifier) 00151 { 00152 DPRINT1("Invalid pIdentifier parameter specified"); 00153 UNLOCK_D3D9(); 00154 return D3DERR_INVALIDCALL; 00155 } 00156 00157 memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER9)); 00158 00159 if (FALSE == GetAdapterInfo(This->DisplayAdapters[Adapter].szDeviceName, pIdentifier)) 00160 { 00161 DPRINT1("Internal error: Couldn't get the adapter info for device (%d): %s", Adapter, This->DisplayAdapters[Adapter].szDeviceName); 00162 UNLOCK_D3D9(); 00163 return D3DERR_INVALIDCALL; 00164 } 00165 00166 UNLOCK_D3D9(); 00167 return D3D_OK; 00168 } 00169 00170 /*++ 00171 * @name IDirect3D9::GetAdapterModeCount 00172 * @implemented 00173 * 00174 * The function IDirect3D9Impl_GetAdapterModeCount looks if the specified display adapter supports 00175 * a specific pixel format and counts the available display modes for that format. 00176 * 00177 * @param LPDIRECT3D iface 00178 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00179 * 00180 * @param UINT Adapter 00181 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00182 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00183 * 00184 * @param D3DFORMAT Format 00185 * The pixel format to search for 00186 * 00187 * @return HRESULT 00188 * If the method is successful it returns the number of display modes with the specified Format. 00189 * If Adapter is out of range, the return value will be 0. 00190 * 00191 */ 00192 static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format) 00193 { 00194 UINT AdapterModeCount; 00195 00196 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00197 LOCK_D3D9(); 00198 00199 if (Adapter >= This->NumDisplayAdapters) 00200 { 00201 DPRINT1("Invalid Adapter number specified"); 00202 UNLOCK_D3D9(); 00203 return D3DERR_INVALIDCALL; 00204 } 00205 00206 if (Format != D3DFMT_A2R10G10B10) 00207 { 00208 AdapterModeCount = GetDisplayFormatCount( 00209 Format, 00210 This->DisplayAdapters[Adapter].pSupportedD3DFormats, 00211 This->DisplayAdapters[Adapter].NumSupportedD3DFormats); 00212 } 00213 else 00214 { 00215 AdapterModeCount = GetDisplayFormatCount( 00216 Format, 00217 This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats, 00218 This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats); 00219 } 00220 00221 UNLOCK_D3D9(); 00222 return AdapterModeCount; 00223 } 00224 00225 /*++ 00226 * @name IDirect3D9::EnumAdapterModes 00227 * @implemented 00228 * 00229 * The function IDirect3D9Impl_EnumAdapterModes looks if the specified display adapter supports 00230 * a specific pixel format and fills the pMode argument with the available display modes for that format. 00231 * This function is often used in a loop to enumerate all the display modes the adapter supports. 00232 * 00233 * @param LPDIRECT3D iface 00234 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00235 * 00236 * @param UINT Adapter 00237 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00238 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00239 * 00240 * @param D3DFORMAT Format 00241 * The pixel format to search for 00242 * 00243 * @param UINT Mode 00244 * Index within the pixel format to be returned. 00245 * The maximym value for this is the value returned by IDirect3D9::GetAdapterModeCount() - 1. 00246 * 00247 * @param D3DDISPLAYMODE* pMode 00248 * Pointer to a D3DDISPLAYMODE structure to be filled with the display mode information 00249 * for the specified format. 00250 * 00251 * @return HRESULT 00252 * If the method successfully fills the pMode structure, the return value is D3D_OK. 00253 * If Adapter is out of range, pMode is a bad pointer or, no modes for the specified 00254 * format was found or the mode parameter was invalid - the return value will be D3DERR_INVALIDCALL. 00255 * 00256 */ 00257 static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format, 00258 UINT Mode, D3DDISPLAYMODE* pMode) 00259 { 00260 const D3DDISPLAYMODE* pMatchingDisplayFormat; 00261 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00262 LOCK_D3D9(); 00263 00264 if (Adapter >= This->NumDisplayAdapters) 00265 { 00266 DPRINT1("Invalid Adapter number specified"); 00267 UNLOCK_D3D9(); 00268 return D3DERR_INVALIDCALL; 00269 } 00270 00271 if (NULL == pMode) 00272 { 00273 DPRINT1("Invalid pMode parameter specified"); 00274 UNLOCK_D3D9(); 00275 return D3DERR_INVALIDCALL; 00276 } 00277 00278 if (Format != D3DFMT_A2R10G10B10) 00279 { 00280 pMatchingDisplayFormat = FindDisplayFormat( 00281 Format, 00282 Mode, 00283 This->DisplayAdapters[Adapter].pSupportedD3DFormats, 00284 This->DisplayAdapters[Adapter].NumSupportedD3DFormats); 00285 } 00286 else 00287 { 00288 pMatchingDisplayFormat = FindDisplayFormat( 00289 Format, 00290 Mode, 00291 This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats, 00292 This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats); 00293 } 00294 00295 if (pMatchingDisplayFormat != NULL) 00296 { 00297 *pMode = *pMatchingDisplayFormat; 00298 } 00299 UNLOCK_D3D9(); 00300 00301 00302 if (pMatchingDisplayFormat == NULL) 00303 return D3DERR_INVALIDCALL; 00304 00305 return D3D_OK; 00306 } 00307 00308 /*++ 00309 * @name IDirect3D9::GetAdapterDisplayMode 00310 * @implemented 00311 * 00312 * The function IDirect3D9Impl_GetAdapterDisplayMode fills the pMode argument with the 00313 * currently set display mode. 00314 * 00315 * @param LPDIRECT3D iface 00316 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00317 * 00318 * @param UINT Adapter 00319 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00320 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00321 * 00322 * @param D3DDISPLAYMODE* pMode 00323 * Pointer to a D3DDISPLAYMODE structure to be filled with the current display mode information. 00324 * 00325 * @return HRESULT 00326 * If the method successfully fills the pMode structure, the return value is D3D_OK. 00327 * If Adapter is out of range or pMode is a bad pointer, the return value will be D3DERR_INVALIDCALL. 00328 * 00329 */ 00330 static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode) 00331 { 00332 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00333 LOCK_D3D9(); 00334 00335 if (Adapter >= This->NumDisplayAdapters) 00336 { 00337 DPRINT1("Invalid Adapter number specified"); 00338 UNLOCK_D3D9(); 00339 return D3DERR_INVALIDCALL; 00340 } 00341 00342 if (NULL == pMode) 00343 { 00344 DPRINT1("Invalid pMode parameter specified"); 00345 UNLOCK_D3D9(); 00346 return D3DERR_INVALIDCALL; 00347 } 00348 00349 /* TODO: Handle (This->DisplayAdapters[Adapter].bInUseFlag == FALSE) */ 00350 if (FALSE == GetAdapterMode(This->DisplayAdapters[Adapter].szDeviceName, pMode)) 00351 DPRINT1("Internal error, GetAdapterMode() failed."); 00352 00353 UNLOCK_D3D9(); 00354 return D3D_OK; 00355 } 00356 00357 00358 /*++ 00359 * @name IDirect3D9::CheckDeviceType 00360 * @implemented 00361 * 00362 * The function IDirect3D9Impl_CheckDeviceType checks if a specific D3DFORMAT is hardware accelerated 00363 * on the specified display adapter. 00364 * 00365 * @param LPDIRECT3D iface 00366 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00367 * 00368 * @param UINT Adapter 00369 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00370 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00371 * 00372 * @param D3DDEVTYPE DeviceType 00373 * One of the D3DDEVTYPE enum members. 00374 * 00375 * @param D3DFORMAT DisplayFormat 00376 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be checked. 00377 * 00378 * @param D3DFORMAT BackBufferFormat 00379 * One of the D3DFORMAT enum members for the render target mode to be checked. D3DFMT_UNKNOWN is only allowed in windowed mode. 00380 * 00381 * @param BOOL Windowed 00382 * If this value is TRUE, the D3DFORMAT check will be done for windowed mode and FALSE equals fullscreen mode. 00383 * 00384 * @return HRESULT 00385 * If the format is hardware accelerated, the method returns D3D_OK. 00386 * If the format isn't hardware accelerated or unsupported - the return value will be D3DERR_NOTAVAILABLE. 00387 * If Adapter is out of range, DeviceType is invalid, 00388 * DisplayFormat or BackBufferFormat is invalid - the return value will be D3DERR_INVALIDCALL. 00389 * 00390 */ 00391 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00392 D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed) 00393 { 00394 HRESULT hResult; 00395 00396 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00397 LOCK_D3D9(); 00398 00399 if (Adapter >= This->NumDisplayAdapters) 00400 { 00401 DPRINT1("Invalid Adapter number specified"); 00402 UNLOCK_D3D9(); 00403 return D3DERR_INVALIDCALL; 00404 } 00405 00406 if (DeviceType != D3DDEVTYPE_HAL && 00407 DeviceType != D3DDEVTYPE_REF && 00408 DeviceType != D3DDEVTYPE_SW) 00409 { 00410 DPRINT1("Invalid DeviceType specified"); 00411 UNLOCK_D3D9(); 00412 return D3DERR_INVALIDCALL; 00413 } 00414 00415 if (BackBufferFormat == D3DFMT_UNKNOWN && 00416 Windowed == TRUE) 00417 { 00418 BackBufferFormat = DisplayFormat; 00419 } 00420 00421 if (DisplayFormat == D3DFMT_UNKNOWN && BackBufferFormat == D3DFMT_UNKNOWN) 00422 { 00423 DPRINT1("Invalid D3DFORMAT specified"); 00424 UNLOCK_D3D9(); 00425 return D3DERR_INVALIDCALL; 00426 } 00427 00428 if (FALSE == IsBackBufferFormat(BackBufferFormat)) 00429 { 00430 DPRINT1("Invalid D3DFORMAT specified"); 00431 UNLOCK_D3D9(); 00432 return D3DERR_NOTAVAILABLE; 00433 } 00434 00435 if (TRUE == Windowed && TRUE == IsExtendedFormat(DisplayFormat)) 00436 { 00437 DPRINT1("Extended diplay modes can only be used in fullscreen mode"); 00438 UNLOCK_D3D9(); 00439 return D3DERR_NOTAVAILABLE; 00440 } 00441 00442 hResult = CheckDeviceType(&This->DisplayAdapters[Adapter].DriverCaps, DisplayFormat, BackBufferFormat, Windowed); 00443 00444 UNLOCK_D3D9(); 00445 return hResult; 00446 } 00447 00448 00449 /*++ 00450 * @name IDirect3D9::CheckDeviceFormat 00451 * @implemented 00452 * 00453 * The function IDirect3D9Impl_CheckDeviceFormat checks if a specific D3DFORMAT 00454 * can be used for a specific purpose like texture, depth/stencil buffer or as a render target 00455 * on the specified display adapter. 00456 * 00457 * @param LPDIRECT3D iface 00458 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00459 * 00460 * @param UINT Adapter 00461 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00462 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00463 * 00464 * @param D3DDEVTYPE DeviceType 00465 * One of the D3DDEVTYPE enum members. 00466 * 00467 * @param D3DFORMAT AdapterFormat 00468 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be checked. 00469 * 00470 * @param DWORD Usage 00471 * Valid values are any of the D3DUSAGE_QUERY constants or any of these D3DUSAGE constants: 00472 * D3DUSAGE_AUTOGENMIPMAP, D3DUSAGE_DEPTHSTENCIL, D3DUSAGE_DMAP, D3DUSAGE_DYNAMIC, 00473 * D3DUSAGE_NONSECURE, D3DUSAGE_RENDERTARGET and D3DUSAGE_SOFTWAREPROCESSING. 00474 * 00475 * @param D3DRESOURCETYPE RType 00476 * One of the D3DRESOURCETYPE enum members. Specifies what format will be used for. 00477 * 00478 * @param D3DFORMAT CheckFormat 00479 * One of the D3DFORMAT enum members for the surface format to be checked. 00480 * 00481 * @return HRESULT 00482 * If the format is compatible with the specified usage and resource type, the method returns D3D_OK. 00483 * If the format isn't compatible with the specified usage and resource type - the return value will be D3DERR_NOTAVAILABLE. 00484 * If Adapter is out of range, DeviceType is invalid, AdapterFormat or CheckFormat is invalid, 00485 * Usage and RType isn't compatible - the return value will be D3DERR_INVALIDCALL. 00486 * 00487 */ 00488 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00489 D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, 00490 D3DFORMAT CheckFormat) 00491 { 00492 LPD3D9_DRIVERCAPS pDriverCaps; 00493 BOOL bIsTextureRType = FALSE; 00494 HRESULT hResult; 00495 00496 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00497 LOCK_D3D9(); 00498 00499 if (Adapter >= This->NumDisplayAdapters) 00500 { 00501 DPRINT1("Invalid Adapter number specified"); 00502 UNLOCK_D3D9(); 00503 return D3DERR_INVALIDCALL; 00504 } 00505 00506 if (DeviceType != D3DDEVTYPE_HAL && 00507 DeviceType != D3DDEVTYPE_REF && 00508 DeviceType != D3DDEVTYPE_SW) 00509 { 00510 DPRINT1("Invalid DeviceType specified"); 00511 UNLOCK_D3D9(); 00512 return D3DERR_INVALIDCALL; 00513 } 00514 00515 if (AdapterFormat == D3DFMT_UNKNOWN || 00516 CheckFormat == D3DFMT_UNKNOWN) 00517 { 00518 DPRINT1("Invalid D3DFORMAT specified"); 00519 UNLOCK_D3D9(); 00520 return D3DERR_INVALIDCALL; 00521 } 00522 00523 if ((Usage & (D3DUSAGE_DONOTCLIP | D3DUSAGE_NPATCHES | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_TEXTAPI | D3DUSAGE_WRITEONLY)) != 0) 00524 { 00525 DPRINT1("Invalid Usage specified"); 00526 UNLOCK_D3D9(); 00527 return D3DERR_INVALIDCALL; 00528 } 00529 00530 if (RType == D3DRTYPE_TEXTURE || 00531 RType == D3DRTYPE_VOLUMETEXTURE || 00532 RType == D3DRTYPE_CUBETEXTURE) 00533 { 00534 bIsTextureRType = TRUE; 00535 } 00536 else if (RType == D3DRTYPE_SURFACE && 00537 (Usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)) == 0 && 00538 Usage != 0) 00539 { 00540 DPRINT1("When RType is set to D3DRTYPE_SURFACE, Usage must be 0 or have set D3DUSAGE_DEPTHSTENCIL or D3DUSAGE_RENDERTARGET"); 00541 UNLOCK_D3D9(); 00542 return D3DERR_INVALIDCALL; 00543 } 00544 00545 if ((Usage & D3DUSAGE_DEPTHSTENCIL) != 0) 00546 { 00547 if (FALSE == IsZBufferFormat(CheckFormat)) 00548 { 00549 DPRINT1("Invalid CheckFormat Z-Buffer format"); 00550 UNLOCK_D3D9(); 00551 return D3DERR_INVALIDCALL; 00552 } 00553 00554 if ((Usage & D3DUSAGE_AUTOGENMIPMAP) != 0) 00555 { 00556 DPRINT1("Invalid Usage specified, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_AUTOGENMIPMAP can't be combined."); 00557 UNLOCK_D3D9(); 00558 return D3DERR_INVALIDCALL; 00559 } 00560 } 00561 00562 if (FALSE == bIsTextureRType && 00563 RType != D3DRTYPE_SURFACE && 00564 RType != D3DRTYPE_VOLUME) 00565 { 00566 DPRINT1("Invalid RType specified"); 00567 UNLOCK_D3D9(); 00568 return D3DERR_INVALIDCALL; 00569 } 00570 00571 if ((Usage & (D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)) != 0) 00572 { 00573 if (RType == D3DRTYPE_VOLUME || RType == D3DRTYPE_VOLUMETEXTURE) 00574 { 00575 DPRINT1("Invalid Usage specified, D3DUSAGE_AUTOGENMIPMAP, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_RENDERTARGET can't be combined with RType D3DRTYPE_VOLUME or D3DRTYPE_VOLUMETEXTURE"); 00576 UNLOCK_D3D9(); 00577 return D3DERR_INVALIDCALL; 00578 } 00579 } 00580 00581 if (FALSE == bIsTextureRType && 00582 (Usage & D3DUSAGE_QUERY_VERTEXTEXTURE) != 0) 00583 { 00584 DPRINT1("Invalid Usage specified, D3DUSAGE_QUERY_VERTEXTEXTURE can only be used with a texture RType"); 00585 UNLOCK_D3D9(); 00586 return D3DERR_INVALIDCALL; 00587 } 00588 00589 if ((Usage & D3DUSAGE_AUTOGENMIPMAP) != 0 && 00590 TRUE == IsMultiElementFormat(CheckFormat)) 00591 { 00592 DPRINT1("Invalid Usage specified, D3DUSAGE_AUTOGENMIPMAP can't be used with a multi-element format"); 00593 UNLOCK_D3D9(); 00594 return D3DERR_INVALIDCALL; 00595 } 00596 00597 pDriverCaps = &This->DisplayAdapters[Adapter].DriverCaps; 00598 if ((Usage & D3DUSAGE_DYNAMIC) != 0 && bIsTextureRType == TRUE) 00599 { 00600 if ((pDriverCaps->DriverCaps9.Caps2 & D3DCAPS2_DYNAMICTEXTURES) == 0) 00601 { 00602 DPRINT1("Driver doesn't support dynamic textures"); 00603 UNLOCK_D3D9(); 00604 return D3DERR_NOTAVAILABLE; 00605 } 00606 00607 if ((Usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)) != 0) 00608 { 00609 DPRINT1("Invalid Usage specified, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_RENDERTARGET can't be combined with D3DUSAGE_DYNAMIC and a texture RType"); 00610 UNLOCK_D3D9(); 00611 return D3DERR_INVALIDCALL; 00612 } 00613 } 00614 00615 if ((Usage & D3DUSAGE_DMAP) != 0) 00616 { 00617 if ((pDriverCaps->DriverCaps9.DevCaps2 & (D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH | D3DDEVCAPS2_DMAPNPATCH)) == 0) 00618 { 00619 DPRINT1("Driver doesn't support displacement mapping"); 00620 UNLOCK_D3D9(); 00621 return D3DERR_NOTAVAILABLE; 00622 } 00623 00624 if (RType != D3DRTYPE_TEXTURE) 00625 { 00626 DPRINT1("Invalid Usage speficied, D3DUSAGE_DMAP must be combined with RType D3DRTYPE_TEXTURE"); 00627 UNLOCK_D3D9(); 00628 return D3DERR_INVALIDCALL; 00629 } 00630 } 00631 00632 hResult = CheckDeviceFormat(pDriverCaps, AdapterFormat, Usage, RType, CheckFormat); 00633 00634 UNLOCK_D3D9(); 00635 return hResult; 00636 } 00637 00638 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00639 D3DFORMAT SurfaceFormat, BOOL Windowed, 00640 D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) 00641 { 00642 UNIMPLEMENTED 00643 00644 return D3D_OK; 00645 } 00646 00647 00648 /*++ 00649 * @name IDirect3D9::CheckDepthStencilMatch 00650 * @implemented 00651 * 00652 * The function IDirect3D9Impl_CheckDepthStencilMatch checks if a specific combination 00653 * of a render target D3DFORMAT and a depth-stencil D3DFORMAT can be used with a specified 00654 * D3DFORMAT on the specified display adapter. 00655 * 00656 * @param LPDIRECT3D iface 00657 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00658 * 00659 * @param UINT Adapter 00660 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00661 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00662 * 00663 * @param D3DDEVTYPE DeviceType 00664 * One of the D3DDEVTYPE enum members. 00665 * 00666 * @param D3DFORMAT AdapterFormat 00667 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN that the display adapter mode where the test should occurr. 00668 * 00669 * @param D3DFORMAT RenderTargetFormat 00670 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode's render target format to be tested. 00671 * 00672 * @param D3DFORMAT DepthStencilFormat 00673 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode's depth-stencil format to be tested. 00674 * 00675 * @return HRESULT 00676 * If the DepthStencilFormat can be used with the RenderTargetFormat under the specified AdapterFormat, 00677 * the method returns D3D_OK. 00678 * If the DepthStencilFormat can NOT used with the RenderTargetFormat under the specified AdapterFormat, 00679 * the method returns D3DERR_NOTAVAILABLE. 00680 * If Adapter is out of range, DeviceType is invalid, 00681 * AdapterFormat, RenderTargetFormat or DepthStencilFormat is invalid, the method returns D3DERR_INVALIDCALL. 00682 * 00683 */ 00684 static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00685 D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, 00686 D3DFORMAT DepthStencilFormat) 00687 { 00688 HRESULT hResult; 00689 00690 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00691 LOCK_D3D9(); 00692 00693 if (Adapter >= This->NumDisplayAdapters) 00694 { 00695 DPRINT1("Invalid Adapter number specified"); 00696 UNLOCK_D3D9(); 00697 return D3DERR_INVALIDCALL; 00698 } 00699 00700 if (DeviceType != D3DDEVTYPE_HAL && 00701 DeviceType != D3DDEVTYPE_REF && 00702 DeviceType != D3DDEVTYPE_SW) 00703 { 00704 DPRINT1("Invalid DeviceType specified"); 00705 UNLOCK_D3D9(); 00706 return D3DERR_INVALIDCALL; 00707 } 00708 00709 if (AdapterFormat == D3DFMT_UNKNOWN || 00710 RenderTargetFormat == D3DFMT_UNKNOWN || 00711 DepthStencilFormat == D3DFMT_UNKNOWN) 00712 { 00713 DPRINT1("Invalid D3DFORMAT specified"); 00714 UNLOCK_D3D9(); 00715 return D3DERR_INVALIDCALL; 00716 } 00717 00718 hResult = CheckDepthStencilMatch(&This->DisplayAdapters[Adapter].DriverCaps, AdapterFormat, RenderTargetFormat, DepthStencilFormat); 00719 00720 UNLOCK_D3D9(); 00721 return hResult; 00722 } 00723 00724 00725 /*++ 00726 * @name IDirect3D9::CheckDeviceFormatConversion 00727 * @implemented 00728 * 00729 * The function IDirect3D9Impl_CheckDeviceFormatConversion checks if a specific D3DFORMAT 00730 * can be converted to another on the specified display adapter. 00731 * 00732 * @param LPDIRECT3D iface 00733 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00734 * 00735 * @param UINT Adapter 00736 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00737 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00738 * 00739 * @param D3DDEVTYPE DeviceType 00740 * One of the D3DDEVTYPE enum members. Only D3DDEVTYPE_HAL can potentially return D3D_OK. 00741 * 00742 * @param D3DFORMAT SourceFormat 00743 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted from. 00744 * 00745 * @param D3DFORMAT TargetFormat 00746 * One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted to. 00747 * 00748 * @return HRESULT 00749 * If the SourceFormat can be converted to the TargetFormat, the method returns D3D_OK. 00750 * If the SourceFormat can NOT be converted to the TargetFormat, the method returns D3DERR_NOTAVAILABLE. 00751 * If Adapter is out of range, DeviceType is invalid, 00752 * SourceFormat or TargetFormat is invalid, the method returns D3DERR_INVALIDCALL. 00753 * 00754 */ 00755 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00756 D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) 00757 { 00758 HRESULT hResult; 00759 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00760 LOCK_D3D9(); 00761 00762 if (Adapter >= This->NumDisplayAdapters) 00763 { 00764 DPRINT1("Invalid Adapter number specified"); 00765 UNLOCK_D3D9(); 00766 return D3DERR_INVALIDCALL; 00767 } 00768 00769 if (DeviceType != D3DDEVTYPE_HAL && 00770 DeviceType != D3DDEVTYPE_REF && 00771 DeviceType != D3DDEVTYPE_SW) 00772 { 00773 DPRINT1("Invalid DeviceType specified"); 00774 UNLOCK_D3D9(); 00775 return D3DERR_INVALIDCALL; 00776 } 00777 00778 if (SourceFormat == D3DFMT_UNKNOWN || 00779 TargetFormat == D3DFMT_UNKNOWN) 00780 { 00781 DPRINT1("Invalid D3DFORMAT specified"); 00782 UNLOCK_D3D9(); 00783 return D3DERR_NOTAVAILABLE; 00784 } 00785 00786 if (DeviceType == D3DDEVTYPE_HAL) 00787 { 00788 hResult = CheckDeviceFormatConversion(&This->DisplayAdapters[Adapter].DriverCaps, SourceFormat, TargetFormat); 00789 } 00790 else 00791 { 00792 hResult = D3DERR_NOTAVAILABLE; 00793 } 00794 00795 UNLOCK_D3D9(); 00796 return hResult; 00797 } 00798 00799 00800 /*++ 00801 * @name IDirect3D9::GetDeviceCaps 00802 * @implemented 00803 * 00804 * The function IDirect3D9Impl_GetDeviceCaps fills the pCaps argument with the 00805 * capabilities of the specified adapter and device type. 00806 * 00807 * @param LPDIRECT3D iface 00808 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00809 * 00810 * @param UINT Adapter 00811 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00812 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00813 * 00814 * @param D3DDEVTYPE DeviceType 00815 * One of the D3DDEVTYPE enum members. 00816 * NOTE: Currently only D3DDEVTYPE_HAL is implemented. 00817 * 00818 * @param D3DCAPS9* pCaps 00819 * Pointer to a D3DCAPS9 structure to be filled with the adapter's device type capabilities. 00820 * 00821 * @return HRESULT 00822 * If the method successfully fills the pCaps structure, the return value is D3D_OK. 00823 * If Adapter is out of range or pCaps is a bad pointer, the return value will be D3DERR_INVALIDCALL. 00824 * If DeviceType is invalid, the return value will be D3DERR_INVALIDDEVICE. 00825 * 00826 */ 00827 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) 00828 { 00829 HRESULT hResult; 00830 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00831 LOCK_D3D9(); 00832 00833 if (Adapter >= This->NumDisplayAdapters) 00834 { 00835 DPRINT1("Invalid Adapter number specified"); 00836 UNLOCK_D3D9(); 00837 return D3DERR_INVALIDCALL; 00838 } 00839 00840 if (NULL == pCaps) 00841 { 00842 DPRINT1("Invalid pCaps parameter specified"); 00843 UNLOCK_D3D9(); 00844 return D3DERR_INVALIDCALL; 00845 } 00846 00847 hResult = GetAdapterCaps(&This->DisplayAdapters[Adapter], DeviceType, pCaps); 00848 00849 UNLOCK_D3D9(); 00850 return hResult; 00851 } 00852 00853 /*++ 00854 * @name IDirect3D9::GetAdapterMonitor 00855 * @implemented 00856 * 00857 * The function IDirect3D9Impl_GetAdapterMonitor returns the monitor associated 00858 * with the specified display adapter. 00859 * 00860 * @param LPDIRECT3D iface 00861 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00862 * 00863 * @param UINT Adapter 00864 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00865 * The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1. 00866 * 00867 * @return HMONITOR 00868 * If the method successfully it returns the HMONITOR belonging to the specified adapter. 00869 * If the method fails, the return value is NULL. 00870 * 00871 */ 00872 static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9 iface, UINT Adapter) 00873 { 00874 HMONITOR hAdapterMonitor = NULL; 00875 00876 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00877 LOCK_D3D9(); 00878 00879 if (Adapter < This->NumDisplayAdapters) 00880 { 00881 hAdapterMonitor = GetAdapterMonitor(This->DisplayAdapters[Adapter].szDeviceName); 00882 } 00883 else 00884 { 00885 DPRINT1("Invalid Adapter number specified"); 00886 } 00887 00888 UNLOCK_D3D9(); 00889 return hAdapterMonitor; 00890 } 00891 00892 /*++ 00893 * @name IDirect3D9::CreateDevice 00894 * @implemented 00895 * 00896 * The function IDirect3D9Impl_CreateDevice creates an IDirect3DDevice9 object 00897 * that represents the display adapter. 00898 * 00899 * @param LPDIRECT3D iface 00900 * Pointer to the IDirect3D9 object returned from Direct3DCreate9() 00901 * 00902 * @param UINT Adapter 00903 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display. 00904 * The maximum value for this is the value returned by IDirect3D::GetAdapterCount() - 1. 00905 * 00906 * @param D3DDEVTYPE DeviceType 00907 * One of the D3DDEVTYPE enum members. 00908 * 00909 * @param HWND hFocusWindow 00910 * A window handle that is used as a reference when Direct3D should switch between 00911 * foreground mode and background mode. 00912 * 00913 * @param DWORD BehaviourFlags 00914 * Any valid combination of the D3DCREATE constants. 00915 * 00916 * @param D3DPRESENT_PARAMETERS* pPresentationParameters 00917 * Pointer to a D3DPRESENT_PARAMETERS structure describing the parameters for the device 00918 * to be created. If D3DCREATE_ADAPTERGROUP_DEVICE is specified in the BehaviourFlags parameter, 00919 * the pPresentationParameters is treated as an array. 00920 * 00921 * @param IDirect3DDevice9** ppReturnedDeviceInterface 00922 * Return object that represents the created device. 00923 * 00924 * @return HRESULT 00925 * If the method successfully creates a device and returns a valid ppReturnedDeviceInterface object, 00926 * the return value is D3D_OK. 00927 * If Adapter is out of range, DeviceType is invalid, hFocusWindow is not a valid, BehaviourFlags is invalid 00928 * pPresentationParameters is invalid or ppReturnedDeviceInterface is a bad pointer, the return value 00929 * will be D3DERR_INVALIDCALL. 00930 * 00931 */ 00932 static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, 00933 HWND hFocusWindow, DWORD BehaviourFlags, 00934 D3DPRESENT_PARAMETERS* pPresentationParameters, 00935 struct IDirect3DDevice9** ppReturnedDeviceInterface) 00936 { 00937 DWORD NumAdaptersToCreate; 00938 HRESULT Ret; 00939 00940 LPDIRECT3D9_INT This = IDirect3D9ToImpl(iface); 00941 LOCK_D3D9(); 00942 00943 if (Adapter >= This->NumDisplayAdapters) 00944 { 00945 DPRINT1("Invalid Adapter number specified"); 00946 UNLOCK_D3D9(); 00947 return D3DERR_INVALIDCALL; 00948 } 00949 00950 if (DeviceType != D3DDEVTYPE_HAL && 00951 DeviceType != D3DDEVTYPE_REF && 00952 DeviceType != D3DDEVTYPE_SW) 00953 { 00954 DPRINT1("Invalid DeviceType specified"); 00955 UNLOCK_D3D9(); 00956 return D3DERR_INVALIDCALL; 00957 } 00958 00959 if (DeviceType != D3DDEVTYPE_HAL) 00960 { 00961 UNIMPLEMENTED 00962 DPRINT1("Sorry, only D3DDEVTYPE_HAL is implemented at this time..."); 00963 return D3DERR_INVALIDCALL; 00964 } 00965 00966 if (hFocusWindow != NULL && FALSE == IsWindow(hFocusWindow)) 00967 { 00968 DPRINT1("Invalid hFocusWindow parameter specified, expected NULL or a valid HWND"); 00969 UNLOCK_D3D9(); 00970 return D3DERR_INVALIDCALL; 00971 } 00972 00973 if (NULL == pPresentationParameters) 00974 { 00975 DPRINT1("Invalid pPresentationParameters parameter specified"); 00976 UNLOCK_D3D9(); 00977 return D3DERR_INVALIDCALL; 00978 } 00979 00980 if (pPresentationParameters->hDeviceWindow != NULL && FALSE == IsWindow(pPresentationParameters->hDeviceWindow)) 00981 { 00982 DPRINT1("Invalid pPresentationParameters->hDeviceWindow parameter specified, expected NULL or a valid HWND"); 00983 UNLOCK_D3D9(); 00984 return D3DERR_INVALIDCALL; 00985 } 00986 00987 if (FALSE == pPresentationParameters->Windowed && hFocusWindow == NULL) 00988 { 00989 DPRINT1("When pPresentationParameters->Windowed is not set, hFocusWindow must be a valid HWND"); 00990 UNLOCK_D3D9(); 00991 return D3DERR_INVALIDCALL; 00992 } 00993 00994 if (NULL == hFocusWindow && NULL == pPresentationParameters->hDeviceWindow) 00995 { 00996 DPRINT1("Any of pPresentationParameters->Windowed and hFocusWindow must be set to a valid HWND"); 00997 UNLOCK_D3D9(); 00998 return D3DERR_INVALIDCALL; 00999 } 01000 01001 if (Adapter > 0 && NULL == pPresentationParameters->hDeviceWindow) 01002 { 01003 DPRINT1("Invalid pPresentationParameters->hDeviceWindow, must be set to a valid unique HWND when Adapter is greater than 0"); 01004 UNLOCK_D3D9(); 01005 return D3DERR_INVALIDCALL; 01006 } 01007 01008 if (NULL == ppReturnedDeviceInterface) 01009 { 01010 DPRINT1("Invalid ppReturnedDeviceInterface parameter specified"); 01011 UNLOCK_D3D9(); 01012 return D3DERR_INVALIDCALL; 01013 } 01014 01015 if ((BehaviourFlags & D3DCREATE_ADAPTERGROUP_DEVICE) != 0) 01016 NumAdaptersToCreate = This->DisplayAdapters[Adapter].NumAdaptersInGroup; 01017 else 01018 NumAdaptersToCreate = 1; 01019 01020 *ppReturnedDeviceInterface = 0; 01021 01022 Ret = CreateD3D9HalDevice(This, Adapter, hFocusWindow, BehaviourFlags, pPresentationParameters, NumAdaptersToCreate, ppReturnedDeviceInterface); 01023 01024 UNLOCK_D3D9(); 01025 return Ret; 01026 } 01027 01028 IDirect3D9Vtbl Direct3D9_Vtbl = 01029 { 01030 /* IUnknown */ 01031 IDirect3D9Impl_QueryInterface, 01032 IDirect3D9Impl_AddRef, 01033 IDirect3D9Impl_Release, 01034 01035 /* IDirect3D9 */ 01036 IDirect3D9Impl_RegisterSoftwareDevice, 01037 IDirect3D9Impl_GetAdapterCount, 01038 IDirect3D9Impl_GetAdapterIdentifier, 01039 IDirect3D9Impl_GetAdapterModeCount, 01040 IDirect3D9Impl_EnumAdapterModes, 01041 IDirect3D9Impl_GetAdapterDisplayMode, 01042 IDirect3D9Impl_CheckDeviceType, 01043 IDirect3D9Impl_CheckDeviceFormat, 01044 IDirect3D9Impl_CheckDeviceMultiSampleType, 01045 IDirect3D9Impl_CheckDepthStencilMatch, 01046 IDirect3D9Impl_CheckDeviceFormatConversion, 01047 IDirect3D9Impl_GetDeviceCaps, 01048 IDirect3D9Impl_GetAdapterMonitor, 01049 IDirect3D9Impl_CreateDevice 01050 }; Generated on Sun May 27 2012 04:21:14 for ReactOS by
1.7.6.1
|