Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

410 lines
12 KiB

  1. //=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. //=============================================================================
  9. #ifdef _WIN32
  10. #include "appframework/materialsystem2app.h"
  11. #include "FileSystem.h"
  12. #include "materialsystem2/IMaterialSystem2.h"
  13. #include "tier0/dbg.h"
  14. #include "tier0/icommandline.h"
  15. #include "filesystem_init.h"
  16. #include "inputsystem/iinputsystem.h"
  17. #include "tier2/tier2.h"
  18. #include "rendersystem/irenderdevice.h"
  19. #include "rendersystem/irenderhardwareconfig.h"
  20. #include "vstdlib/jobthread.h"
  21. //#include "videocfg/videocfg.h"
  22. //-----------------------------------------------------------------------------
  23. // Constructor
  24. //-----------------------------------------------------------------------------
  25. CMaterialSystem2App::CMaterialSystem2App()
  26. {
  27. m_RenderFactory = NULL;
  28. m_hSwapChain = SWAP_CHAIN_HANDLE_INVALID;
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Creates render system
  32. //-----------------------------------------------------------------------------
  33. bool CMaterialSystem2App::AddRenderSystem()
  34. {
  35. bool bIsVistaOrHigher = IsPlatformWindowsPC() && ( Plat_GetOSVersion() >= PLAT_OS_VERSION_VISTA );
  36. const char *pShaderDLL = !IsPlatformX360() ? CommandLine()->ParmValue( "-rendersystemdll" ) : NULL;
  37. if ( !pShaderDLL )
  38. {
  39. if ( IsPlatformWindowsPC() )
  40. {
  41. pShaderDLL = "rendersystemdx11.dll";
  42. }
  43. else if ( IsPlatformX360() )
  44. {
  45. pShaderDLL = "rendersystemdx9_360.dll";
  46. }
  47. else
  48. {
  49. pShaderDLL = "rendersystemgl.dll";
  50. }
  51. }
  52. // Disallow dx11 on XP machines
  53. if ( !bIsVistaOrHigher && !Q_stricmp( pShaderDLL, "rendersystemdx11.dll" ) )
  54. {
  55. pShaderDLL = "rendersystemdx9.dll";
  56. }
  57. AppModule_t module = LoadModule( pShaderDLL );
  58. if ( module == APP_MODULE_INVALID )
  59. {
  60. if ( IsPlatformWindowsPC() )
  61. {
  62. pShaderDLL = "rendersystemdx9.dll";
  63. module = LoadModule( pShaderDLL );
  64. }
  65. if ( module == APP_MODULE_INVALID )
  66. {
  67. pShaderDLL = "rendersystemempty.dll";
  68. module = LoadModule( pShaderDLL );
  69. if ( module == APP_MODULE_INVALID )
  70. return false;
  71. }
  72. }
  73. AddSystem( module, RENDER_DEVICE_MGR_INTERFACE_VERSION );
  74. if ( IsPlatformX360() )
  75. {
  76. m_nRenderSystem = RENDER_SYSTEM_X360;
  77. }
  78. else if ( V_stristr( pShaderDLL, "rendersystemgl" ) != NULL )
  79. {
  80. m_nRenderSystem = RENDER_SYSTEM_GL;
  81. }
  82. else if ( V_stristr( pShaderDLL, "rendersystemdx11" ) != NULL )
  83. {
  84. m_nRenderSystem = RENDER_SYSTEM_DX11;
  85. }
  86. else
  87. {
  88. m_nRenderSystem = RENDER_SYSTEM_DX9;
  89. }
  90. return true;
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Create all singleton systems
  94. //-----------------------------------------------------------------------------
  95. bool CMaterialSystem2App::Create()
  96. {
  97. if ( !AddRenderSystem() )
  98. return false;
  99. AppSystemInfo_t appSystems[] =
  100. {
  101. { "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
  102. { "materialsystem2.dll", MATERIAL_SYSTEM2_INTERFACE_VERSION },
  103. // Required to terminate the list
  104. { "", "" }
  105. };
  106. if ( !AddSystems( appSystems ) )
  107. return false;
  108. const char *pNumThreadsString = CommandLine()->ParmValue( "-threads" );
  109. if ( pNumThreadsString )
  110. {
  111. m_nThreadCount = atoi( pNumThreadsString );
  112. }
  113. else
  114. {
  115. const CPUInformation &cpuInfo = GetCPUInformation();
  116. m_nThreadCount = cpuInfo.m_nLogicalProcessors - 1; // one core for main thread
  117. }
  118. if ( m_nThreadCount > 0 )
  119. {
  120. ThreadPoolStartParams_t sparms( false, m_nThreadCount );
  121. g_pThreadPool->Start( sparms );
  122. }
  123. return true;
  124. }
  125. void CMaterialSystem2App::Destroy()
  126. {
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Pump messages
  130. //-----------------------------------------------------------------------------
  131. void CMaterialSystem2App::AppPumpMessages()
  132. {
  133. g_pInputSystem->PollInputState();
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Sets up the game path
  137. //-----------------------------------------------------------------------------
  138. bool CMaterialSystem2App::SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool )
  139. {
  140. if ( !BaseClass::SetupSearchPaths( pStartingDir, bOnlyUseStartingDir, bIsTool ) )
  141. return false;
  142. g_pFullFileSystem->AddSearchPath( GetGameInfoPath(), "SKIN", PATH_ADD_TO_HEAD );
  143. return true;
  144. }
  145. //-----------------------------------------------------------------------------
  146. // Init, shutdown
  147. //-----------------------------------------------------------------------------
  148. bool CMaterialSystem2App::PreInit( )
  149. {
  150. if ( !BaseClass::PreInit() )
  151. return false;
  152. if ( !g_pFullFileSystem || !g_pMaterialSystem2 || !g_pRenderDeviceMgr || !g_pInputSystem )
  153. {
  154. Warning( "CMaterialSystem2App::PreInit: Unable to connect to necessary interface!\n" );
  155. return false;
  156. }
  157. // Needed to set up the device prior to Init() of other systems
  158. g_pRenderDeviceMgr->InstallRenderDeviceSetup( this );
  159. // Add paths...
  160. // NOTE: Not sure if I should have this here or not. For now, my test
  161. // is rendersystem test, which wants to do it itself.
  162. // if ( !SetupSearchPaths( NULL, false, true ) )
  163. // return false;
  164. return true;
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Replace first underscore (if any) with \0 and return
  168. // This handles special mods like tf_movies, l4d_movies, tf_comics
  169. // As a result, such mods will use the gpu_level settings etc from the base mod
  170. //-----------------------------------------------------------------------------
  171. static void StripModSuffix( char *pModName )
  172. {
  173. int i = 0;
  174. while ( pModName[i] != '\0' ) // Walk to the end of the string
  175. {
  176. if ( pModName[i] == '_') // If we hit an underscore
  177. {
  178. pModName[i] = '\0'; // Terminate the string here and bail out
  179. return;
  180. }
  181. i++;
  182. }
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Configures the application for the specific mod we're running
  186. //-----------------------------------------------------------------------------
  187. void CMaterialSystem2App::ApplyModSettings( )
  188. {
  189. /* PORTFIXME
  190. char pModPath[MAX_PATH];
  191. V_snprintf( pModPath, sizeof(pModPath), "" );
  192. g_pFullFileSystem->GetSearchPath( "MOD", false, pModPath, sizeof( pModPath ) );
  193. // Construct the mod name so we can use the mod-specific encrypted config files
  194. char pModName[32];
  195. V_StripTrailingSlash( pModPath );
  196. V_FileBase( pModPath, pModName, sizeof( pModName ) );
  197. StripModSuffix( pModName );
  198. // Just use the highest levels in non-game apps
  199. UpdateSystemLevel( CPU_LEVEL_HIGH, GPU_LEVEL_VERYHIGH, MEM_LEVEL_HIGH, GPU_MEM_LEVEL_HIGH, false, pModName );
  200. */
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Create our device + window
  204. //-----------------------------------------------------------------------------
  205. bool CMaterialSystem2App::CreateRenderDevice()
  206. {
  207. // Create a device for this adapter
  208. int nAdapterCount = g_pRenderDeviceMgr->GetAdapterCount();
  209. int nAdapter = CommandLine()->ParmValue( "-adapter", 0 );
  210. if ( nAdapter >= nAdapterCount )
  211. {
  212. Warning( "Specified too high an adapter number on the commandline (%d/%d)!\n", nAdapter, nAdapterCount );
  213. return false;
  214. }
  215. int nFlags = 0;
  216. bool bResizing = !IsConsoleApp() && ( CommandLine()->CheckParm( "-resizing" ) != NULL );
  217. if ( bResizing )
  218. {
  219. nFlags |= RENDER_CREATE_DEVICE_RESIZE_WINDOWS;
  220. }
  221. m_RenderFactory = g_pRenderDeviceMgr->CreateDevice( nAdapter, nFlags );
  222. if ( !m_RenderFactory )
  223. {
  224. Warning( "Unable to set mode!\n" );
  225. return false;
  226. }
  227. // Let other systems see the render device
  228. AddNonAppSystemFactory( m_RenderFactory );
  229. ReconnectSystems( RENDER_DEVICE_INTERFACE_VERSION );
  230. ReconnectSystems( RENDER_HARDWARECONFIG_INTERFACE_VERSION );
  231. g_pRenderDevice = (IRenderDevice*)m_RenderFactory( RENDER_DEVICE_INTERFACE_VERSION, NULL );
  232. g_pRenderHardwareConfig = (IRenderHardwareConfig*)m_RenderFactory( RENDER_HARDWARECONFIG_INTERFACE_VERSION, NULL );
  233. // Fixup the platform level
  234. if ( m_nRenderSystem == RENDER_SYSTEM_DX11 )
  235. {
  236. if ( g_pRenderHardwareConfig->GetDXSupportLevel() < 100 )
  237. {
  238. m_nRenderSystem = RENDER_SYSTEM_DX9;
  239. }
  240. }
  241. if ( !IsConsoleApp() )
  242. return CreateMainWindow( bResizing );
  243. return CreateMainConsoleWindow();
  244. }
  245. //-----------------------------------------------------------------------------
  246. // Create our window
  247. //-----------------------------------------------------------------------------
  248. bool CMaterialSystem2App::PostInit( )
  249. {
  250. if ( !BaseClass::PostInit() )
  251. return false;
  252. // Set up mod settings
  253. ApplyModSettings();
  254. return true;
  255. }
  256. void CMaterialSystem2App::PreShutdown()
  257. {
  258. if ( g_pInputSystem )
  259. {
  260. g_pInputSystem->DetachFromWindow( );
  261. }
  262. if ( g_pRenderDevice )
  263. {
  264. g_pRenderDevice->DestroySwapChain( m_hSwapChain );
  265. m_hSwapChain = SWAP_CHAIN_HANDLE_INVALID;
  266. }
  267. BaseClass::PreShutdown();
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Creates the main 3d window
  271. //-----------------------------------------------------------------------------
  272. bool CMaterialSystem2App::CreateMainWindow( bool bResizing )
  273. {
  274. // NOTE: This could be placed into a separate function
  275. // Create a main 3d-capable window
  276. int nWidth = 1280;
  277. int nHeight = IsPlatformX360() ? 720 : 960;
  278. bool bFullscreen = ( CommandLine()->CheckParm( "-fullscreen" ) != NULL );
  279. const char *pArg;
  280. if ( CommandLine()->CheckParm( "-width", &pArg ) )
  281. {
  282. nWidth = atoi( pArg );
  283. }
  284. if ( CommandLine()->CheckParm( "-height", &pArg ) )
  285. {
  286. nHeight = atoi( pArg );
  287. }
  288. m_hSwapChain = Create3DWindow( GetAppName(), nWidth, nHeight, bResizing, bFullscreen, true );
  289. return ( m_hSwapChain != SWAP_CHAIN_HANDLE_INVALID );
  290. }
  291. bool CMaterialSystem2App::CreateMainConsoleWindow()
  292. {
  293. RenderDeviceInfo_t mode;
  294. mode.m_DisplayMode.m_nWidth = 512;
  295. mode.m_DisplayMode.m_nHeight = 512;
  296. mode.m_DisplayMode.m_Format = IMAGE_FORMAT_RGBA8888;
  297. mode.m_DisplayMode.m_nRefreshRateNumerator = 60;
  298. mode.m_DisplayMode.m_nRefreshRateDenominator = 1;
  299. mode.m_bFullscreen = false;
  300. mode.m_nBackBufferCount = 1;
  301. mode.m_bWaitForVSync = false;
  302. #ifdef PLATFORM_WINDOWS_PC
  303. m_hSwapChain = g_pRenderDevice->CreateSwapChain( Plat_GetShellWindow(), mode );
  304. return ( m_hSwapChain != SWAP_CHAIN_HANDLE_INVALID );
  305. #endif
  306. return true;
  307. }
  308. //-----------------------------------------------------------------------------
  309. // Creates a 3d-capable window
  310. //-----------------------------------------------------------------------------
  311. SwapChainHandle_t CMaterialSystem2App::Create3DWindow( const char *pTitle, int nWidth, int nHeight, bool bResizing, bool bFullscreen, bool bAcceptsInput )
  312. {
  313. PlatWindow_t hWnd = (PlatWindow_t)CreateAppWindow( GetAppInstance(), pTitle, !bFullscreen, nWidth, nHeight, bResizing );
  314. if ( !hWnd )
  315. return SWAP_CHAIN_HANDLE_INVALID;
  316. // By default, everything will just use this one swap chain.
  317. RenderDeviceInfo_t mode;
  318. mode.m_DisplayMode.m_nWidth = nWidth;
  319. mode.m_DisplayMode.m_nHeight = nHeight;
  320. mode.m_DisplayMode.m_Format = IMAGE_FORMAT_RGBA8888;
  321. mode.m_DisplayMode.m_nRefreshRateNumerator = 60;
  322. mode.m_DisplayMode.m_nRefreshRateDenominator = 1;
  323. mode.m_bFullscreen = bFullscreen;
  324. mode.m_nBackBufferCount = bFullscreen ? 2 : 1;
  325. mode.m_bWaitForVSync = ( CommandLine()->CheckParm( "-vsync" ) != NULL );
  326. SwapChainHandle_t hSwapChain = g_pRenderDevice->CreateSwapChain( hWnd, mode );
  327. if ( bAcceptsInput )
  328. {
  329. g_pInputSystem->AttachToWindow( (void*)hWnd );
  330. }
  331. return hSwapChain;
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Returns the window associated with a swap chain
  335. //-----------------------------------------------------------------------------
  336. PlatWindow_t CMaterialSystem2App::GetAppWindow()
  337. {
  338. if ( !m_hSwapChain || !g_pRenderDevice )
  339. return PLAT_WINDOW_INVALID;
  340. return g_pRenderDevice->GetSwapChainWindow( m_hSwapChain );
  341. }
  342. #endif // _WIN32