gfxPCD3D9Device.cpp 50 KB

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