Torque3D Documentation / _generateds / gfxPCD3D9Device.cpp

gfxPCD3D9Device.cpp

Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp

More...

Classes:

Public Functions

D3D_GetBackBufferNoRef(IDirect3DSurface9 ** ppSurface)

Parse command line arguments for window creation.

Detailed Description

Public Variables

GFXPCD3D9RegisterDevice pPCD3D9RegisterDevice 
ProcessRegisterCommandLine sgCommandLine (sgPCD3D9DeviceHandleCommandLine)

Public Functions

D3D_GetBackBufferNoRef(IDirect3DSurface9 ** ppSurface)

sgPCD3D9DeviceHandleCommandLine(S32 argc, const char ** argv)

Parse command line arguments for window creation.

   1
   2//-----------------------------------------------------------------------------
   3// Copyright (c) 2012 GarageGames, LLC
   4//
   5// Permission is hereby granted, free of charge, to any person obtaining a copy
   6// of this software and associated documentation files (the "Software"), to
   7// deal in the Software without restriction, including without limitation the
   8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   9// sell copies of the Software, and to permit persons to whom the Software is
  10// furnished to do so, subject to the following conditions:
  11//
  12// The above copyright notice and this permission notice shall be included in
  13// all copies or substantial portions of the Software.
  14//
  15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21// IN THE SOFTWARE.
  22//-----------------------------------------------------------------------------
  23
  24#include "gfx/D3D9/pc/gfxPCD3D9Device.h"
  25#include "gfx/D3D9/pc/gfxPCD3D9Target.h"
  26#include "gfx/D3D9/gfxD3D9CardProfiler.h"
  27#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
  28#include "platformWin32/platformWin32.h"
  29#include "windowManager/win32/win32Window.h"
  30#include "gfx/screenshot.h"
  31#include "gfx/D3D9/screenshotD3D9.h"
  32#include "gfx/D3D9/videoCaptureD3D9.h"
  33#include "core/util/journal/process.h"
  34
  35
  36bool GFXPCD3D9Device::mEnableNVPerfHUD = false;
  37
  38GFXAdapter::CreateDeviceInstanceDelegate GFXPCD3D9Device::mCreateDeviceInstance(GFXPCD3D9Device::createInstance);
  39
  40GFXPCD3D9Device::~GFXPCD3D9Device()
  41{
  42   if( mVideoFrameGrabber )
  43   {
  44      if( ManagedSingleton< VideoCapture >::instanceOrNull() )
  45         VIDCAP->setFrameGrabber( NULL );
  46      delete mVideoFrameGrabber;
  47   }
  48}
  49
  50void GFXPCD3D9Device::createDirect3D9(LPDIRECT3D9 &d3d9, LPDIRECT3D9EX &d3d9ex)
  51{
  52   d3d9 = NULL;
  53   d3d9ex = NULL;
  54
  55   if ( !Con::getBoolVariable( "$pref::Video::preferDirect3D9Ex", false ) )
  56   {
  57      d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  58      return;
  59   }
  60
  61   HMODULE hD3D = LoadLibrary(TEXT("d3d9.dll"));
  62
  63   if (hD3D)
  64   {
  65
  66      HRESULT (WINAPI *pfnCreate9Ex)(UINT SDKVersion, IDirect3D9Ex**) = (HRESULT ( WINAPI *)(UINT SDKVersion, IDirect3D9Ex**)) GetProcAddress(hD3D, "Direct3DCreate9Ex");
  67      
  68      if (pfnCreate9Ex)
  69      {
  70        if (d3d9ex && !FAILED(pfnCreate9Ex(D3D_SDK_VERSION, &d3d9ex)))
  71            d3d9ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d9));
  72      }
  73
  74      if (!pfnCreate9Ex || !d3d9)
  75      {
  76         if (d3d9ex)
  77         {
  78            SAFE_RELEASE(d3d9ex)
  79            d3d9ex = NULL;
  80         }
  81
  82         d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  83      }
  84
  85      FreeLibrary(hD3D);
  86   }
  87}
  88
  89GFXDevice *GFXPCD3D9Device::createInstance( U32 adapterIndex )
  90{
  91   LPDIRECT3D9 d3d9;
  92   LPDIRECT3D9EX d3d9ex;
  93   
  94   createDirect3D9(d3d9, d3d9ex);
  95   
  96   GFXPCD3D9Device* dev = new GFXPCD3D9Device( d3d9, adapterIndex );
  97   dev->mD3DEx = d3d9ex;
  98   return dev;
  99}
 100
 101//-----------------------------------------------------------------------------
 102
 103GFXFormat GFXPCD3D9Device::selectSupportedFormat(GFXTextureProfile *profile,
 104      const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter)
 105{
 106   DWORD usage = 0;
 107
 108   if(profile->isDynamic())
 109      usage |= D3DUSAGE_DYNAMIC;
 110
 111   if(profile->isRenderTarget())
 112      usage |= D3DUSAGE_RENDERTARGET;
 113
 114   if(profile->isZTarget())
 115      usage |= D3DUSAGE_DEPTHSTENCIL;
 116
 117   if(mustblend)
 118      usage |= D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
 119
 120   if(mustfilter)
 121      usage |= D3DUSAGE_QUERY_FILTER;
 122
 123   D3DDISPLAYMODE mode;
 124   D3D9Assert(mD3D->GetAdapterDisplayMode(mAdapterIndex, &mode), "Unable to get adapter mode.");
 125
 126   D3DRESOURCETYPE type;
 127   if(texture)
 128      type = D3DRTYPE_TEXTURE;
 129   else
 130      type = D3DRTYPE_SURFACE;
 131
 132   for(U32 i=0; i<formats.size(); i++)
 133   {
 134      if(mD3D->CheckDeviceFormat(mAdapterIndex, D3DDEVTYPE_HAL, mode.Format,
 135         usage, type, GFXD3D9TextureFormat[formats[i]]) == D3D_OK)
 136         return formats[i];
 137   }
 138
 139   return GFXFormatR8G8B8A8;
 140}
 141
 142HRESULT GFXPCD3D9Device::createDevice(U32 adapter, D3DDEVTYPE deviceType, HWND hFocusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters)
 143{
 144   HRESULT hres = E_FAIL;
 145
 146   if (mD3DEx)
 147   {
 148      hres = mD3DEx->CreateDeviceEx( adapter, deviceType, 
 149         hFocusWindow,
 150         behaviorFlags, 
 151         pPresentationParameters, NULL, &mD3DDeviceEx ); 
 152
 153      if (!FAILED(hres) && mD3DDeviceEx)
 154         hres = mD3DDeviceEx->QueryInterface(__uuidof(IDirect3DDevice9), reinterpret_cast<void**>(&mD3DDevice));  
 155   }
 156   else
 157   {
 158      hres = mD3D->CreateDevice( adapter, deviceType, 
 159         hFocusWindow,
 160         behaviorFlags, 
 161         pPresentationParameters, &mD3DDevice ); 
 162   }   
 163
 164   return hres;
 165
 166}
 167
 168//-----------------------------------------------------------------------------
 169
 170//-----------------------------------------------------------------------------
 171// Setup D3D present parameters - init helper function
 172//-----------------------------------------------------------------------------
 173D3DPRESENT_PARAMETERS GFXPCD3D9Device::setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const
 174{
 175   // Create D3D Presentation params
 176   D3DPRESENT_PARAMETERS d3dpp; 
 177   dMemset( &d3dpp, 0, sizeof( d3dpp ) );
 178
 179   D3DFORMAT fmt = D3DFMT_X8R8G8B8; // 32 bit
 180
 181   if( mode.bitDepth == 16 )
 182      fmt = D3DFMT_R5G6B5;
 183
 184   D3DMULTISAMPLE_TYPE aatype;
 185   DWORD aalevel;
 186
 187   // Setup the AA flags...  If we've been ask to 
 188   // disable  hardware AA then do that now.
 189   if ( mode.antialiasLevel == 0 || Con::getBoolVariable( "$pref::Video::disableHardwareAA", false ) )
 190   {
 191      aatype = D3DMULTISAMPLE_NONE;
 192      aalevel = 0;
 193   } 
 194   else 
 195   {
 196      aatype = D3DMULTISAMPLE_NONMASKABLE;
 197      aalevel = mode.antialiasLevel-1;
 198   }
 199  
 200   _validateMultisampleParams(fmt, aatype, aalevel);
 201   
 202   d3dpp.BackBufferWidth  = mode.resolution.x;
 203   d3dpp.BackBufferHeight = mode.resolution.y;
 204   d3dpp.BackBufferFormat = fmt;
 205   d3dpp.BackBufferCount  = 1;
 206   d3dpp.MultiSampleType  = aatype;
 207   d3dpp.MultiSampleQuality = aalevel;
 208   d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
 209   d3dpp.hDeviceWindow    = hwnd;
 210   d3dpp.Windowed         = !mode.fullScreen;
 211   d3dpp.EnableAutoDepthStencil = TRUE;
 212   d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
 213   d3dpp.Flags            = 0;
 214   d3dpp.FullScreen_RefreshRateInHz = (mode.refreshRate == 0 || !mode.fullScreen) ? 
 215                                       D3DPRESENT_RATE_DEFAULT : mode.refreshRate;
 216   d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
 217
 218   if ( smDisableVSync )
 219      d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // This does NOT wait for vsync
 220
 221   return d3dpp;
 222}
 223
 224//-----------------------------------------------------------------------------
 225// Enumerate D3D adapters
 226//-----------------------------------------------------------------------------
 227void GFXPCD3D9Device::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
 228{
 229   // Grab a D3D9 handle here to first get the D3D9 devices
 230   LPDIRECT3D9 d3d9;
 231   LPDIRECT3D9EX d3d9ex;
 232   createDirect3D9( d3d9, d3d9ex); 
 233
 234   // If we could not create the d3d9 object then either the system
 235   // is corrupt or they need to update the directx runtime.
 236   if ( !d3d9 )
 237   {
 238      Con::errorf( "Unsupported DirectX version!" );
 239      Platform::messageBox(   Con::getVariable( "$appName" ),
 240                              "DirectX could not be started!\r\n"
 241                              "Please be sure you have the latest version of DirectX installed.",
 242                              MBOk, MIStop );
 243      Platform::forceShutdown( -1 );
 244   }
 245
 246   for( U32 adapterIndex = 0; adapterIndex < d3d9->GetAdapterCount(); adapterIndex++ ) 
 247   {
 248      GFXAdapter *toAdd = new GFXAdapter;
 249      toAdd->mType  = Direct3D9;
 250      toAdd->mIndex = adapterIndex;
 251      toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;
 252
 253      // Grab the shader model.
 254      D3DCAPS9 caps;
 255      d3d9->GetDeviceCaps(adapterIndex, D3DDEVTYPE_HAL, &caps);
 256      U8 *pxPtr = (U8*) &caps.PixelShaderVersion;
 257      toAdd->mShaderModel = pxPtr[1] + pxPtr[0] * 0.1;
 258
 259      // Get the device description string.
 260      D3DADAPTER_IDENTIFIER9 temp;
 261      d3d9->GetAdapterIdentifier( adapterIndex, NULL, &temp ); // The NULL is the flags which deal with WHQL
 262
 263      dStrncpy(toAdd->mName, temp.Description, GFXAdapter::MaxAdapterNameLen);
 264      dStrncat(toAdd->mName, " (D3D9)", GFXAdapter::MaxAdapterNameLen);
 265
 266      // And the output display device name
 267      dStrncpy(toAdd->mOutputName, temp.DeviceName, GFXAdapter::MaxAdapterNameLen);
 268
 269      // Video mode enumeration.
 270      Vector<D3DFORMAT> formats( __FILE__, __LINE__ );
 271      formats.push_back( D3DFMT_R5G6B5 );    // D3DFMT_R5G6B5 - 16bit format
 272      formats.push_back( D3DFMT_X8R8G8B8 );  // D3DFMT_X8R8G8B8 - 32bit format
 273
 274      for( S32 i = 0; i < formats.size(); i++ ) 
 275      {
 276         DWORD MaxSampleQualities;
 277         d3d9->CheckDeviceMultiSampleType(adapterIndex, D3DDEVTYPE_HAL, formats[i], FALSE, D3DMULTISAMPLE_NONMASKABLE, &MaxSampleQualities);
 278
 279         for( U32 j = 0; j < d3d9->GetAdapterModeCount( adapterIndex, formats[i] ); j++ ) 
 280         {
 281            D3DDISPLAYMODE mode;
 282            d3d9->EnumAdapterModes( adapterIndex, formats[i], j, &mode );
 283
 284            GFXVideoMode vmAdd;
 285
 286            vmAdd.bitDepth    = ( i == 0 ? 16 : 32 ); // This will need to be changed later
 287            vmAdd.fullScreen  = true;
 288            vmAdd.refreshRate = mode.RefreshRate;
 289            vmAdd.resolution  = Point2I( mode.Width, mode.Height );
 290            vmAdd.antialiasLevel = MaxSampleQualities;
 291
 292            toAdd->mAvailableModes.push_back( vmAdd );
 293         }
 294      }
 295
 296      adapterList.push_back( toAdd );
 297   }
 298
 299   d3d9->Release();
 300}
 301
 302void GFXPCD3D9Device::enumerateVideoModes() 
 303{
 304   Vector<D3DFORMAT> formats( __FILE__, __LINE__ );
 305   formats.push_back( D3DFMT_R5G6B5 );    // D3DFMT_R5G6B5 - 16bit format
 306   formats.push_back( D3DFMT_X8R8G8B8 );  // D3DFMT_X8R8G8B8 - 32bit format
 307
 308   for( S32 i = 0; i < formats.size(); i++ ) 
 309   {
 310      for( U32 j = 0; j < mD3D->GetAdapterModeCount( mAdapterIndex, formats[i] ); j++ ) 
 311      {
 312         D3DDISPLAYMODE mode;
 313         mD3D->EnumAdapterModes( mAdapterIndex, formats[i], j, &mode );
 314
 315         GFXVideoMode toAdd;
 316
 317         toAdd.bitDepth = ( i == 0 ? 16 : 32 ); // This will need to be changed later
 318         toAdd.fullScreen = false;
 319         toAdd.refreshRate = mode.RefreshRate;
 320         toAdd.resolution = Point2I( mode.Width, mode.Height );
 321
 322         mVideoModes.push_back( toAdd );
 323      }
 324   }
 325}
 326
 327//-----------------------------------------------------------------------------
 328// Initialize - create window, device, etc
 329//-----------------------------------------------------------------------------
 330void GFXPCD3D9Device::init( const GFXVideoMode &mode, PlatformWindow *window /* = NULL */ )
 331{
 332   AssertFatal(window, "GFXPCD3D9Device::init - must specify a window!");
 333
 334   initD3DXFnTable();
 335
 336   HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
 337   AssertISV(winHwnd, "GFXPCD3D9WindowTarget::initPresentationParams() - no HWND");
 338
 339   // Create D3D Presentation params
 340   D3DPRESENT_PARAMETERS d3dpp = setupPresentParams( mode, winHwnd );
 341   mMultisampleType = d3dpp.MultiSampleType;
 342   mMultisampleLevel = d3dpp.MultiSampleQuality;
 343      
 344#ifndef TORQUE_SHIPPING
 345   bool usePerfHud = GFXPCD3D9Device::mEnableNVPerfHUD || Con::getBoolVariable("$Video::useNVPerfHud", false);   
 346#else
 347   bool usePerfHud = false;
 348#endif
 349
 350   HRESULT hres = E_FAIL;
 351   if ( usePerfHud )
 352   {  
 353      hres = createDevice(  mD3D->GetAdapterCount() - 1, D3DDEVTYPE_REF, winHwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp);
 354   }
 355   else 
 356   {
 357      // Vertex processing was changed from MIXED to HARDWARE because of the switch to a pure D3D device.
 358
 359      // Set up device flags from our compile flags.
 360      U32 deviceFlags = 0;
 361      deviceFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
 362
 363      // Currently, offscreen rendering is only used by WPF apps and we need to create with D3DCREATE_MULTITHREAD for it
 364      // In all other cases, you can do better by locking/creating resources in the primary thread
 365      // and passing them to worker threads.
 366      if (window->getOffscreenRender())
 367      {
 368         deviceFlags |= D3DCREATE_MULTITHREADED;
 369         d3dpp.Windowed = TRUE;
 370         d3dpp.BackBufferHeight = 1;
 371         d3dpp.BackBufferWidth = 1;
 372         d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
 373         d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
 374         d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
 375      }
 376
 377      // DirectX will switch the floating poing control word to single precision
 378      // and disable exceptions by default.  There are a few issues with this...
 379      //
 380      // 1. It can cause rendering problems when running in WPF.
 381      // 2. Firefox embedding issues.
 382      // 3. Physics engines depend on the higher precision.
 383      //
 384      // Interestingly enough... DirectX 10 and 11 do not modifiy the floating point
 385      // settings and are always in full precision.
 386      //
 387      // The down side is we supposedly loose some performance, but so far i've not
 388      // seen a measurable impact.
 389      // 
 390      deviceFlags |= D3DCREATE_FPU_PRESERVE;
 391
 392      // Try to do pure, unless we're doing debug (and thus doing more paranoid checking).
 393#ifndef TORQUE_DEBUG_RENDER
 394      deviceFlags |= D3DCREATE_PUREDEVICE;
 395#endif
 396
 397      hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, winHwnd, deviceFlags, &d3dpp);
 398
 399      if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY)
 400      {
 401         Con::errorf("   Failed to create hardware device, trying mixed device");
 402         // turn off pure
 403         deviceFlags &= (~D3DCREATE_PUREDEVICE);
 404
 405         // try mixed mode
 406         deviceFlags &= (~D3DCREATE_HARDWARE_VERTEXPROCESSING);
 407         deviceFlags |= D3DCREATE_MIXED_VERTEXPROCESSING;
 408         hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, 
 409            winHwnd, deviceFlags, 
 410            &d3dpp);
 411
 412         // try software 
 413         if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY)
 414         {
 415            Con::errorf("   Failed to create mixed mode device, trying software device");
 416            deviceFlags &= (~D3DCREATE_MIXED_VERTEXPROCESSING);
 417            deviceFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
 418            hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, 
 419               winHwnd, deviceFlags,
 420               &d3dpp);
 421
 422            if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY)
 423               Con::errorf("   Failed to create software device, giving up");
 424            D3D9Assert(hres, "GFXPCD3D9Device::init - CreateDevice failed!");
 425         }
 426      }
 427   }
 428
 429   // Gracefully die if they can't give us a device.
 430   if(!mD3DDevice)
 431   {
 432      if (hres == D3DERR_OUTOFVIDEOMEMORY)
 433      {
 434         char errorMsg[4096];
 435         dSprintf(errorMsg, sizeof(errorMsg),
 436            "Out of video memory. Close other windows, reboot, and/or upgrade your video card drivers. Your video card is: %s", getAdapter().getName());
 437         Platform::AlertOK("DirectX Error", errorMsg);
 438      }
 439      else
 440      {
 441         Platform::AlertOK("DirectX Error!", "Failed to initialize Direct3D! Make sure you have DirectX 9 installed, and "
 442            "are running a graphics card that supports Pixel Shader 1.1.");
 443      }
 444      Platform::forceShutdown(1);
 445   }
 446
 447   // Check up on things
 448   Con::printf("   Cur. D3DDevice ref count=%d", mD3DDevice->AddRef() - 1);
 449   mD3DDevice->Release();
 450   
 451   mTextureManager = new GFXD3D9TextureManager( mD3DDevice, mAdapterIndex );
 452
 453   // Now reacquire all the resources we trashed earlier
 454   reacquireDefaultPoolResources();
 455      
 456   // Setup default states
 457   initStates();
 458
 459   //-------- Output init info ---------   
 460   D3DCAPS9 caps;
 461   mD3DDevice->GetDeviceCaps( &caps );
 462
 463   U8 *pxPtr = (U8*) &caps.PixelShaderVersion;
 464   mPixVersion = pxPtr[1] + pxPtr[0] * 0.1;
 465   if (mPixVersion >= 2.0f && mPixVersion < 3.0f && caps.PS20Caps.NumTemps >= 32)
 466      mPixVersion += 0.2f;
 467   else if (mPixVersion >= 2.0f && mPixVersion < 3.0f && caps.PS20Caps.NumTemps >= 22)
 468      mPixVersion += 0.1f;
 469   Con::printf( "   Pix version detected: %f", mPixVersion );
 470
 471   if ( smForcedPixVersion >= 0.0f && smForcedPixVersion < mPixVersion )
 472   {
 473      mPixVersion = smForcedPixVersion;
 474      Con::errorf( "   Forced pix version: %f", mPixVersion );
 475   }
 476
 477   U8 *vertPtr = (U8*) &caps.VertexShaderVersion;
 478   F32 vertVersion = vertPtr[1] + vertPtr[0] * 0.1;
 479   Con::printf( "   Vert version detected: %f", vertVersion );
 480
 481   // The sampler count is based on the shader model and
 482   // not found in the caps.
 483   //
 484   // MaxSimultaneousTextures is only valid for fixed
 485   // function rendering.
 486   //
 487   if ( mPixVersion >= 2.0f )
 488      mNumSamplers = 16;
 489   else if ( mPixVersion >= 1.4f )
 490      mNumSamplers = 6;
 491   else if ( mPixVersion > 0.0f )
 492      mNumSamplers = 4;
 493   else
 494      mNumSamplers = caps.MaxSimultaneousTextures;      
 495
 496   // This shouldn't happen until SM5 or some other
 497   // radical change in GPU hardware occurs.
 498   AssertFatal( mNumSamplers <= TEXTURE_STAGE_COUNT, 
 499      "GFXPCD3D9Device::init - Sampler count greater than TEXTURE_STAGE_COUNT!" );
 500            
 501   Con::printf( "   Maximum number of simultaneous samplers: %d", mNumSamplers );
 502
 503   // detect max number of simultaneous render targets
 504   mNumRenderTargets = caps.NumSimultaneousRTs;
 505   Con::printf( "   Number of simultaneous render targets: %d", mNumRenderTargets );
 506   
 507   // detect occlusion query support
 508   if (SUCCEEDED(mD3DDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, NULL )))
 509      mOcclusionQuerySupported = true;
 510      
 511   Con::printf( "   Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No" );      
 512
 513   Con::printf( "   Using Direct3D9Ex: %s", isD3D9Ex() ? "Yes" : "No" );
 514   
 515   mCardProfiler = new GFXD3D9CardProfiler(mAdapterIndex);
 516   mCardProfiler->init();
 517
 518   gScreenShot = new ScreenShotD3D9;
 519
 520   // Set the video capture frame grabber.
 521   mVideoFrameGrabber = new VideoFrameGrabberD3D9();
 522   VIDCAP->setFrameGrabber( mVideoFrameGrabber );
 523
 524   // Grab the depth-stencil...
 525   SAFE_RELEASE(mDeviceDepthStencil);
 526   D3D9Assert(mD3DDevice->GetDepthStencilSurface(&mDeviceDepthStencil), "GFXD3D9Device::init - couldn't grab reference to device's depth-stencil surface.");  
 527
 528   mInitialized = true;
 529
 530   deviceInited();
 531
 532   // Uncomment to dump out code needed in initStates, you may also need to enable the reference device (get rid of code in initStates first as well)
 533   // regenStates();
 534}
 535
 536//------------------------------------------------------------------------------
 537void GFXPCD3D9Device::enterDebugEvent(ColorI color, const char *name)
 538{
 539   // BJGFIX
 540   WCHAR  eventName[260];
 541   MultiByteToWideChar( CP_ACP, 0, name, -1, eventName, 260 );
 542
 543   D3DPERF_BeginEvent(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
 544      (LPCWSTR)&eventName);
 545}
 546
 547//------------------------------------------------------------------------------
 548void GFXPCD3D9Device::leaveDebugEvent()
 549{
 550   D3DPERF_EndEvent();
 551}
 552
 553//------------------------------------------------------------------------------
 554void GFXPCD3D9Device::setDebugMarker(ColorI color, const char *name)
 555{
 556   // BJGFIX
 557   WCHAR  eventName[260];
 558   MultiByteToWideChar( CP_ACP, 0, name, -1, eventName, 260 );
 559
 560   D3DPERF_SetMarker(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue), 
 561      (LPCWSTR)&eventName);
 562}
 563
 564//-----------------------------------------------------------------------------
 565
 566void GFXPCD3D9Device::setMatrix( GFXMatrixType mtype, const MatrixF &mat ) 
 567{
 568   mat.transposeTo( mTempMatrix );
 569
 570   mD3DDevice->SetTransform( (_D3DTRANSFORMSTATETYPE)mtype, (D3DMATRIX *)&mTempMatrix );
 571}
 572
 573//-----------------------------------------------------------------------------
 574
 575void GFXPCD3D9Device::_setTextureStageState( U32 stage, U32 state, U32 value ) 
 576{
 577   switch( state )
 578   {
 579      case GFXTSSColorOp:
 580      case GFXTSSAlphaOp:
 581         mD3DDevice->SetTextureStageState( stage, GFXD3D9TextureStageState[state], GFXD3D9TextureOp[value] );
 582         break;
 583
 584      default:
 585         mD3DDevice->SetTextureStageState( stage, GFXD3D9TextureStageState[state], value );
 586         break;
 587   }
 588}
 589
 590//------------------------------------------------------------------------------
 591
 592void GFXPCD3D9Device::initStates() 
 593{
 594   //-------------------------------------
 595   // Auto-generated default states, see regenStates() for details
 596   //
 597
 598   // Render states
 599   mD3DDevice->SetRenderState( GFXD3D9RenderState[0], 1 );
 600   mD3DDevice->SetRenderState( GFXD3D9RenderState[1], 3 );
 601   mD3DDevice->SetRenderState( GFXD3D9RenderState[2], 2 );
 602   mD3DDevice->SetRenderState( GFXD3D9RenderState[3], 1 );
 603   mD3DDevice->SetRenderState( GFXD3D9RenderState[4], 0 );
 604   mD3DDevice->SetRenderState( GFXD3D9RenderState[5], 1 );
 605   mD3DDevice->SetRenderState( GFXD3D9RenderState[6], 2 );
 606   mD3DDevice->SetRenderState( GFXD3D9RenderState[7], 1 );
 607   mD3DDevice->SetRenderState( GFXD3D9RenderState[8], 3 );
 608   mD3DDevice->SetRenderState( GFXD3D9RenderState[9], 4 );
 609   mD3DDevice->SetRenderState( GFXD3D9RenderState[10], 0 );
 610   mD3DDevice->SetRenderState( GFXD3D9RenderState[11], 8 );
 611   mD3DDevice->SetRenderState( GFXD3D9RenderState[12], 0 );
 612   mD3DDevice->SetRenderState( GFXD3D9RenderState[13], 0 );
 613   mD3DDevice->SetRenderState( GFXD3D9RenderState[14], 0 );
 614   mD3DDevice->SetRenderState( GFXD3D9RenderState[15], 0 );
 615   mD3DDevice->SetRenderState( GFXD3D9RenderState[16], 0 );
 616   mD3DDevice->SetRenderState( GFXD3D9RenderState[17], 0 );
 617   mD3DDevice->SetRenderState( GFXD3D9RenderState[18], 0 );
 618   mD3DDevice->SetRenderState( GFXD3D9RenderState[19], 1065353216 );
 619   mD3DDevice->SetRenderState( GFXD3D9RenderState[20], 1065353216 );
 620   mD3DDevice->SetRenderState( GFXD3D9RenderState[21], 0 );
 621   mD3DDevice->SetRenderState( GFXD3D9RenderState[22], 0 );
 622   mD3DDevice->SetRenderState( GFXD3D9RenderState[23], 1 );
 623   mD3DDevice->SetRenderState( GFXD3D9RenderState[24], 1 );
 624   mD3DDevice->SetRenderState( GFXD3D9RenderState[25], 1 );
 625   mD3DDevice->SetRenderState( GFXD3D9RenderState[26], 8 );
 626   mD3DDevice->SetRenderState( GFXD3D9RenderState[27], 0 );
 627   mD3DDevice->SetRenderState( GFXD3D9RenderState[28], -1 );
 628   mD3DDevice->SetRenderState( GFXD3D9RenderState[29], -1 );
 629   mD3DDevice->SetRenderState( GFXD3D9RenderState[30], -1 );
 630   mD3DDevice->SetRenderState( GFXD3D9RenderState[31], 0 );
 631   mD3DDevice->SetRenderState( GFXD3D9RenderState[32], 0 );
 632   mD3DDevice->SetRenderState( GFXD3D9RenderState[33], 0 );
 633   mD3DDevice->SetRenderState( GFXD3D9RenderState[34], 0 );
 634   mD3DDevice->SetRenderState( GFXD3D9RenderState[35], 0 );
 635   mD3DDevice->SetRenderState( GFXD3D9RenderState[36], 0 );
 636   mD3DDevice->SetRenderState( GFXD3D9RenderState[37], 0 );
 637   mD3DDevice->SetRenderState( GFXD3D9RenderState[38], 0 );
 638   mD3DDevice->SetRenderState( GFXD3D9RenderState[39], 1 );
 639   mD3DDevice->SetRenderState( GFXD3D9RenderState[40], 1 );
 640   mD3DDevice->SetRenderState( GFXD3D9RenderState[41], 0 );
 641   mD3DDevice->SetRenderState( GFXD3D9RenderState[42], 0 );
 642   mD3DDevice->SetRenderState( GFXD3D9RenderState[43], 1 );
 643   mD3DDevice->SetRenderState( GFXD3D9RenderState[44], 1 );
 644   mD3DDevice->SetRenderState( GFXD3D9RenderState[45], 0 );
 645   mD3DDevice->SetRenderState( GFXD3D9RenderState[46], 1 );
 646   mD3DDevice->SetRenderState( GFXD3D9RenderState[47], 2 );
 647   mD3DDevice->SetRenderState( GFXD3D9RenderState[48], 0 );
 648   mD3DDevice->SetRenderState( GFXD3D9RenderState[49], 0 );
 649   mD3DDevice->SetRenderState( GFXD3D9RenderState[50], 0 );
 650   mD3DDevice->SetRenderState( GFXD3D9RenderState[51], 0 );
 651   mD3DDevice->SetRenderState( GFXD3D9RenderState[52], 1065353216 );
 652   mD3DDevice->SetRenderState( GFXD3D9RenderState[53], 1065353216 );
 653   mD3DDevice->SetRenderState( GFXD3D9RenderState[54], 0 );
 654   mD3DDevice->SetRenderState( GFXD3D9RenderState[55], 0 );
 655   mD3DDevice->SetRenderState( GFXD3D9RenderState[56], 1065353216 );
 656   mD3DDevice->SetRenderState( GFXD3D9RenderState[57], 0 );
 657   mD3DDevice->SetRenderState( GFXD3D9RenderState[58], 0 );
 658   mD3DDevice->SetRenderState( GFXD3D9RenderState[59], 1 );
 659   mD3DDevice->SetRenderState( GFXD3D9RenderState[60], -1 );
 660   mD3DDevice->SetRenderState( GFXD3D9RenderState[61], 0 );
 661   mD3DDevice->SetRenderState( GFXD3D9RenderState[62], 0 );
 662   mD3DDevice->SetRenderState( GFXD3D9RenderState[63], 1115684864 );
 663   mD3DDevice->SetRenderState( GFXD3D9RenderState[64], 0 );
 664   mD3DDevice->SetRenderState( GFXD3D9RenderState[65], 15 );
 665   mD3DDevice->SetRenderState( GFXD3D9RenderState[66], 0 );
 666   mD3DDevice->SetRenderState( GFXD3D9RenderState[67], 1 );
 667   mD3DDevice->SetRenderState( GFXD3D9RenderState[68], 3 );
 668   mD3DDevice->SetRenderState( GFXD3D9RenderState[69], 1 );
 669   mD3DDevice->SetRenderState( GFXD3D9RenderState[70], 0 );
 670   mD3DDevice->SetRenderState( GFXD3D9RenderState[71], 0 );
 671   mD3DDevice->SetRenderState( GFXD3D9RenderState[72], 0 );
 672   mD3DDevice->SetRenderState( GFXD3D9RenderState[73], 1065353216 );
 673   mD3DDevice->SetRenderState( GFXD3D9RenderState[74], 1065353216 );
 674   mD3DDevice->SetRenderState( GFXD3D9RenderState[75], 0 );
 675   mD3DDevice->SetRenderState( GFXD3D9RenderState[76], 0 );
 676   mD3DDevice->SetRenderState( GFXD3D9RenderState[77], 1065353216 );
 677   mD3DDevice->SetRenderState( GFXD3D9RenderState[78], 0 );
 678   mD3DDevice->SetRenderState( GFXD3D9RenderState[79], 0 );
 679   mD3DDevice->SetRenderState( GFXD3D9RenderState[80], 0 );
 680   mD3DDevice->SetRenderState( GFXD3D9RenderState[81], 1 );
 681   mD3DDevice->SetRenderState( GFXD3D9RenderState[82], 1 );
 682   mD3DDevice->SetRenderState( GFXD3D9RenderState[83], 1 );
 683   mD3DDevice->SetRenderState( GFXD3D9RenderState[84], 8 );
 684   mD3DDevice->SetRenderState( GFXD3D9RenderState[85], 15 );
 685   mD3DDevice->SetRenderState( GFXD3D9RenderState[86], 15 );
 686   mD3DDevice->SetRenderState( GFXD3D9RenderState[87], 15 );
 687   mD3DDevice->SetRenderState( GFXD3D9RenderState[88], -1 );
 688   mD3DDevice->SetRenderState( GFXD3D9RenderState[89], 0 );
 689   mD3DDevice->SetRenderState( GFXD3D9RenderState[90], 0 );
 690   mD3DDevice->SetRenderState( GFXD3D9RenderState[91], 0 );
 691   mD3DDevice->SetRenderState( GFXD3D9RenderState[92], 0 );
 692   mD3DDevice->SetRenderState( GFXD3D9RenderState[93], 0 );
 693   mD3DDevice->SetRenderState( GFXD3D9RenderState[94], 0 );
 694   mD3DDevice->SetRenderState( GFXD3D9RenderState[95], 0 );
 695   mD3DDevice->SetRenderState( GFXD3D9RenderState[96], 0 );
 696   mD3DDevice->SetRenderState( GFXD3D9RenderState[97], 0 );
 697   mD3DDevice->SetRenderState( GFXD3D9RenderState[98], 0 );
 698   mD3DDevice->SetRenderState( GFXD3D9RenderState[99], 0 );
 699   mD3DDevice->SetRenderState( GFXD3D9RenderState[100], 2 );
 700   mD3DDevice->SetRenderState( GFXD3D9RenderState[101], 1 );
 701   mD3DDevice->SetRenderState( GFXD3D9RenderState[102], 1 );
 702
 703   // Texture Stage states
 704   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[0], 4 );
 705   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[1], 2 );
 706   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[2], 1 );
 707   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[3], 2 );
 708   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[4], 2 );
 709   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[5], 1 );
 710   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[6], 0 );
 711   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[7], 0 );
 712   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[8], 0 );
 713   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[9], 0 );
 714   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[10], 0 );
 715   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[11], 0 );
 716   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[12], 0 );
 717   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[13], 0 );
 718   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[14], 1 );
 719   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[15], 1 );
 720   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[16], 1 );
 721   mD3DDevice->SetTextureStageState( 0, GFXD3D9TextureStageState[17], 0 );
 722   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[0], 1 );
 723   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[1], 2 );
 724   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[2], 1 );
 725   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[3], 1 );
 726   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[4], 2 );
 727   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[5], 1 );
 728   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[6], 0 );
 729   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[7], 0 );
 730   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[8], 0 );
 731   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[9], 0 );
 732   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[10], 1 );
 733   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[11], 0 );
 734   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[12], 0 );
 735   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[13], 0 );
 736   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[14], 1 );
 737   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[15], 1 );
 738   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[16], 1 );
 739   mD3DDevice->SetTextureStageState( 1, GFXD3D9TextureStageState[17], 0 );
 740   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[0], 1 );
 741   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[1], 2 );
 742   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[2], 1 );
 743   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[3], 1 );
 744   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[4], 2 );
 745   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[5], 1 );
 746   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[6], 0 );
 747   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[7], 0 );
 748   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[8], 0 );
 749   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[9], 0 );
 750   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[10], 2 );
 751   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[11], 0 );
 752   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[12], 0 );
 753   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[13], 0 );
 754   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[14], 1 );
 755   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[15], 1 );
 756   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[16], 1 );
 757   mD3DDevice->SetTextureStageState( 2, GFXD3D9TextureStageState[17], 0 );
 758   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[0], 1 );
 759   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[1], 2 );
 760   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[2], 1 );
 761   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[3], 1 );
 762   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[4], 2 );
 763   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[5], 1 );
 764   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[6], 0 );
 765   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[7], 0 );
 766   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[8], 0 );
 767   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[9], 0 );
 768   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[10], 3 );
 769   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[11], 0 );
 770   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[12], 0 );
 771   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[13], 0 );
 772   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[14], 1 );
 773   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[15], 1 );
 774   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[16], 1 );
 775   mD3DDevice->SetTextureStageState( 3, GFXD3D9TextureStageState[17], 0 );
 776   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[0], 1 );
 777   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[1], 2 );
 778   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[2], 1 );
 779   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[3], 1 );
 780   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[4], 2 );
 781   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[5], 1 );
 782   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[6], 0 );
 783   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[7], 0 );
 784   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[8], 0 );
 785   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[9], 0 );
 786   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[10], 4 );
 787   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[11], 0 );
 788   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[12], 0 );
 789   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[13], 0 );
 790   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[14], 1 );
 791   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[15], 1 );
 792   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[16], 1 );
 793   mD3DDevice->SetTextureStageState( 4, GFXD3D9TextureStageState[17], 0 );
 794   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[0], 1 );
 795   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[1], 2 );
 796   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[2], 1 );
 797   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[3], 1 );
 798   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[4], 2 );
 799   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[5], 1 );
 800   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[6], 0 );
 801   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[7], 0 );
 802   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[8], 0 );
 803   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[9], 0 );
 804   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[10], 5 );
 805   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[11], 0 );
 806   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[12], 0 );
 807   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[13], 0 );
 808   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[14], 1 );
 809   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[15], 1 );
 810   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[16], 1 );
 811   mD3DDevice->SetTextureStageState( 5, GFXD3D9TextureStageState[17], 0 );
 812   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[0], 1 );
 813   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[1], 2 );
 814   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[2], 1 );
 815   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[3], 1 );
 816   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[4], 2 );
 817   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[5], 1 );
 818   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[6], 0 );
 819   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[7], 0 );
 820   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[8], 0 );
 821   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[9], 0 );
 822   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[10], 6 );
 823   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[11], 0 );
 824   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[12], 0 );
 825   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[13], 0 );
 826   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[14], 1 );
 827   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[15], 1 );
 828   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[16], 1 );
 829   mD3DDevice->SetTextureStageState( 6, GFXD3D9TextureStageState[17], 0 );
 830   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[0], 1 );
 831   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[1], 2 );
 832   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[2], 1 );
 833   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[3], 1 );
 834   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[4], 2 );
 835   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[5], 1 );
 836   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[6], 0 );
 837   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[7], 0 );
 838   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[8], 0 );
 839   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[9], 0 );
 840   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[10], 7 );
 841   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[11], 0 );
 842   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[12], 0 );
 843   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[13], 0 );
 844   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[14], 1 );
 845   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[15], 1 );
 846   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[16], 1 );
 847   mD3DDevice->SetTextureStageState( 7, GFXD3D9TextureStageState[17], 0 );
 848
 849   // Sampler states
 850   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[0], 1 );
 851   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[1], 1 );
 852   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[2], 1 );
 853   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[3], 0 );
 854   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[4], 1 );
 855   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[5], 1 );
 856   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[6], 0 );
 857   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[7], 0 );
 858   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[8], 0 );
 859   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[9], 1 );
 860   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[10], 0 );
 861   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[11], 0 );
 862   mD3DDevice->SetSamplerState( 0, GFXD3D9SamplerState[12], 0 );
 863   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[0], 1 );
 864   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[1], 1 );
 865   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[2], 1 );
 866   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[3], 0 );
 867   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[4], 1 );
 868   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[5], 1 );
 869   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[6], 0 );
 870   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[7], 0 );
 871   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[8], 0 );
 872   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[9], 1 );
 873   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[10], 0 );
 874   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[11], 0 );
 875   mD3DDevice->SetSamplerState( 1, GFXD3D9SamplerState[12], 0 );
 876   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[0], 1 );
 877   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[1], 1 );
 878   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[2], 1 );
 879   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[3], 0 );
 880   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[4], 1 );
 881   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[5], 1 );
 882   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[6], 0 );
 883   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[7], 0 );
 884   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[8], 0 );
 885   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[9], 1 );
 886   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[10], 0 );
 887   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[11], 0 );
 888   mD3DDevice->SetSamplerState( 2, GFXD3D9SamplerState[12], 0 );
 889   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[0], 1 );
 890   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[1], 1 );
 891   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[2], 1 );
 892   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[3], 0 );
 893   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[4], 1 );
 894   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[5], 1 );
 895   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[6], 0 );
 896   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[7], 0 );
 897   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[8], 0 );
 898   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[9], 1 );
 899   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[10], 0 );
 900   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[11], 0 );
 901   mD3DDevice->SetSamplerState( 3, GFXD3D9SamplerState[12], 0 );
 902   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[0], 1 );
 903   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[1], 1 );
 904   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[2], 1 );
 905   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[3], 0 );
 906   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[4], 1 );
 907   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[5], 1 );
 908   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[6], 0 );
 909   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[7], 0 );
 910   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[8], 0 );
 911   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[9], 1 );
 912   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[10], 0 );
 913   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[11], 0 );
 914   mD3DDevice->SetSamplerState( 4, GFXD3D9SamplerState[12], 0 );
 915   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[0], 1 );
 916   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[1], 1 );
 917   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[2], 1 );
 918   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[3], 0 );
 919   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[4], 1 );
 920   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[5], 1 );
 921   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[6], 0 );
 922   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[7], 0 );
 923   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[8], 0 );
 924   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[9], 1 );
 925   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[10], 0 );
 926   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[11], 0 );
 927   mD3DDevice->SetSamplerState( 5, GFXD3D9SamplerState[12], 0 );
 928   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[0], 1 );
 929   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[1], 1 );
 930   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[2], 1 );
 931   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[3], 0 );
 932   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[4], 1 );
 933   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[5], 1 );
 934   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[6], 0 );
 935   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[7], 0 );
 936   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[8], 0 );
 937   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[9], 1 );
 938   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[10], 0 );
 939   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[11], 0 );
 940   mD3DDevice->SetSamplerState( 6, GFXD3D9SamplerState[12], 0 );
 941   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[0], 1 );
 942   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[1], 1 );
 943   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[2], 1 );
 944   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[3], 0 );
 945   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[4], 1 );
 946   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[5], 1 );
 947   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[6], 0 );
 948   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[7], 0 );
 949   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[8], 0 );
 950   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[9], 1 );
 951   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[10], 0 );
 952   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[11], 0 );
 953   mD3DDevice->SetSamplerState( 7, GFXD3D9SamplerState[12], 0 );
 954}
 955
 956void GFXPCD3D9Device::_validateMultisampleParams(D3DFORMAT format, D3DMULTISAMPLE_TYPE & aatype, DWORD & aalevel) const
 957{
 958   if (aatype != D3DMULTISAMPLE_NONE)
 959   {
 960      DWORD MaxSampleQualities;      
 961      mD3D->CheckDeviceMultiSampleType(mAdapterIndex, D3DDEVTYPE_HAL, format, FALSE, D3DMULTISAMPLE_NONMASKABLE, &MaxSampleQualities);
 962      aatype = D3DMULTISAMPLE_NONMASKABLE;
 963      aalevel = getMin((U32)aalevel, (U32)MaxSampleQualities-1);
 964   }
 965}
 966
 967bool GFXPCD3D9Device::beginSceneInternal() 
 968{
 969   // Make sure we have a device
 970   HRESULT res = mD3DDevice->TestCooperativeLevel();
 971
 972   S32 attempts = 0;
 973   const S32 MaxAttempts = 40;
 974   const S32 SleepMsPerAttempt = 50;
 975   while(res == D3DERR_DEVICELOST && attempts < MaxAttempts)
 976   {
 977      // Lost device! Just keep querying
 978      res = mD3DDevice->TestCooperativeLevel();
 979
 980      Con::warnf("GFXPCD3D9Device::beginScene - Device needs to be reset, waiting on device...");
 981
 982      Sleep(SleepMsPerAttempt);
 983      attempts++;
 984   }
 985
 986   if (attempts >= MaxAttempts && res == D3DERR_DEVICELOST)
 987   {
 988      Con::errorf("GFXPCD3D9Device::beginScene - Device lost and reset wait time exceeded, skipping reset (will retry later)");
 989      mCanCurrentlyRender = false;
 990      return false;
 991   }
 992
 993   // Trigger a reset if we can't get a good result from TestCooperativeLevel.
 994   if(res == D3DERR_DEVICENOTRESET)
 995   {
 996      Con::warnf("GFXPCD3D9Device::beginScene - Device needs to be reset, resetting device...");
 997
 998      // Reset the device!
 999      GFXResource *walk = mResourceListHead;
1000      while(walk)
1001      {
1002         // Find the window target with implicit flag set and reset the device with its presentation params.
1003         if(GFXPCD3D9WindowTarget *gdwt = dynamic_cast<GFXPCD3D9WindowTarget*>(walk))
1004         {
1005            if(gdwt->mImplicit)
1006            {
1007               reset(gdwt->mPresentationParams);
1008               break;
1009            }
1010         }
1011
1012         walk = walk->getNextResource();
1013      }
1014   }
1015
1016   // Call parent
1017   return Parent::beginSceneInternal();
1018}
1019
1020GFXWindowTarget * GFXPCD3D9Device::allocWindowTarget( PlatformWindow *window )
1021{
1022   AssertFatal(window,"GFXD3D9Device::allocWindowTarget - no window provided!");
1023
1024   // Set up a new window target...
1025   GFXPCD3D9WindowTarget *gdwt = new GFXPCD3D9WindowTarget();
1026   gdwt->mWindow = window;
1027   gdwt->mSize = window->getClientExtent();
1028   gdwt->mDevice = this;
1029   gdwt->initPresentationParams();
1030
1031   // Now, we have to init & bind our device... we have basically two scenarios
1032   // of which the first is:
1033   if(mD3DDevice == NULL)
1034   {
1035      // Allocate the device.
1036      init(window->getVideoMode(), window);
1037
1038      // Cool, we have the device, grab back the depthstencil buffer as well
1039      // as the swap chain.
1040      gdwt->mImplicit = true;
1041      gdwt->setImplicitSwapChain();
1042   }
1043   else
1044   {
1045      // And the second case:
1046      // Initialized device, create an additional swap chain.
1047      gdwt->mImplicit = false;
1048      gdwt->createAdditionalSwapChain();         
1049   }
1050
1051   gdwt->registerResourceWithDevice(this);
1052
1053   return gdwt;
1054}
1055
1056GFXTextureTarget * GFXPCD3D9Device::allocRenderToTextureTarget()
1057{
1058   GFXPCD3D9TextureTarget *targ = new GFXPCD3D9TextureTarget();
1059   targ->mDevice = this;
1060
1061   targ->registerResourceWithDevice(this);
1062
1063   return targ;
1064}
1065
1066//-----------------------------------------------------------------------------
1067// Reset D3D device
1068//-----------------------------------------------------------------------------
1069void GFXPCD3D9Device::reset( D3DPRESENT_PARAMETERS &d3dpp )
1070{
1071   if(!mD3DDevice)
1072      return;
1073
1074   mInitialized = false;
1075
1076   mMultisampleType = d3dpp.MultiSampleType;
1077   mMultisampleLevel = d3dpp.MultiSampleQuality;
1078   _validateMultisampleParams(d3dpp.BackBufferFormat, mMultisampleType, mMultisampleLevel);
1079
1080   // Clean up some commonly dangling state. This helps prevents issues with
1081   // items that are destroyed by the texture manager callbacks and recreated
1082   // later, but still left bound.
1083   setVertexBuffer(NULL);
1084   setPrimitiveBuffer(NULL);
1085   for(S32 i=0; i<getNumSamplers(); i++)
1086      setTexture(i, NULL);
1087
1088   // Deal with the depth/stencil buffer.
1089   if(mDeviceDepthStencil)
1090   {
1091      Con::printf("GFXPCD3D9Device::reset - depthstencil %x has %d ref's", mDeviceDepthStencil, mDeviceDepthStencil->AddRef()-1);
1092      mDeviceDepthStencil->Release();
1093   }
1094
1095   // First release all the stuff we allocated from D3DPOOL_DEFAULT
1096   releaseDefaultPoolResources();
1097
1098   // reset device
1099   Con::printf( "--- Resetting D3D Device ---" );
1100   HRESULT hres = S_OK;
1101   hres = mD3DDevice->Reset( &d3dpp );
1102
1103   if( FAILED( hres ) )
1104   {
1105      while( mD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST )
1106      {
1107         Sleep( 100 );
1108      }
1109
1110      hres = mD3DDevice->Reset( &d3dpp );
1111   }
1112
1113   D3D9Assert( hres, "GFXD3D9Device::reset - Failed to create D3D Device!" );
1114   mInitialized = true;
1115
1116   // Setup default states
1117   initStates();
1118
1119   // Now re aquire all the resources we trashed earlier
1120   reacquireDefaultPoolResources();
1121
1122   // Mark everything dirty and flush to card, for sanity.
1123   updateStates(true);
1124}
1125
1126//
1127// Register this device with GFXInit
1128//
1129class GFXPCD3D9RegisterDevice
1130{
1131public:
1132   GFXPCD3D9RegisterDevice()
1133   {
1134      GFXInit::getRegisterDeviceSignal().notify(&GFXPCD3D9Device::enumerateAdapters);
1135   }
1136};
1137
1138static GFXPCD3D9RegisterDevice pPCD3D9RegisterDevice;
1139
1140//-----------------------------------------------------------------------------
1141/// Parse command line arguments for window creation
1142//-----------------------------------------------------------------------------
1143static void sgPCD3D9DeviceHandleCommandLine( S32 argc, const char **argv )
1144{
1145   for (U32 i = 1; i < argc; i++)
1146   {
1147      String s(argv[i]);
1148      if (s.equal("-nvperfhud", String::NoCase))
1149      {
1150         GFXPCD3D9Device::mEnableNVPerfHUD = true;
1151         break;
1152      }
1153   }   
1154}
1155
1156// Register the command line parsing hook
1157static ProcessRegisterCommandLine sgCommandLine( sgPCD3D9DeviceHandleCommandLine );
1158
1159extern "C" HRESULT WINAPI D3D_GetBackBufferNoRef(IDirect3DSurface9 **ppSurface)
1160{
1161    HRESULT hr = S_OK;
1162  
1163    GFXD3D9Device *dev = static_cast<GFXD3D9Device *>(GFX);
1164
1165    if (!dev)
1166    {
1167       *ppSurface = NULL;
1168       return S_OK;
1169    }
1170
1171    *ppSurface = dev->getBackBuffer();
1172
1173    return hr;
1174}
1175