ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

d3d9_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.