gfxPCD3D9Device.cpp 50 KB

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