@@ -998,11 +998,9 @@ class CWorkerAccumState
998998 m_arrSubProcessInfos.Purge ();
999999 }
10001000
1001- public :
1001+ protected :
10021002 bool OnProcess ();
1003- bool OnProcessST ();
10041003
1005- protected:
10061004 TMutexType *m_pMutex;
10071005
10081006 protected:
@@ -1236,160 +1234,56 @@ bool CWorkerAccumState<TMutexType>::OnProcess() {
12361234 return false ;
12371235}
12381236
1239- template <typename TMutexType>
1240- bool CWorkerAccumState<TMutexType>::OnProcessST() {
1241- while (m_hCombo) {
1242- ExecuteCompileCommand (m_hCombo);
1243-
1244- Combo_GetNext (m_iNextCommand, m_hCombo, m_iEndCommand);
1245- }
1246- return false ;
1247- }
1248-
12491237//
1250- // ProcessCommandRange_Singleton
1238+ // Processor
12511239//
1252- class ProcessCommandRange_Singleton {
1240+ class RangeProcessor {
12531241 public:
1254- static ProcessCommandRange_Singleton *&Instance () {
1255- static ProcessCommandRange_Singleton *s_ptr = nullptr ;
1256- return s_ptr;
1257- }
1258- static ProcessCommandRange_Singleton *GetInstance () {
1259- ProcessCommandRange_Singleton *p = Instance ();
1260- Assert (p);
1261- return p;
1262- }
1242+ explicit RangeProcessor (IThreadPool *pool)
1243+ : m_worker{nullptr }, m_thread_pool{pool} {}
1244+ ~RangeProcessor () {
1245+ delete m_worker;
12631246
1264- public:
1265- ProcessCommandRange_Singleton () {
1266- Assert (!Instance ());
1267- Instance () = this ;
1268- Startup (g_pThreadPool);
1269- }
1270- ~ProcessCommandRange_Singleton () {
1271- Assert (Instance () == this );
1272- Instance () = nullptr ;
1273- Shutdown ();
1247+ m_thread_pool->Stop ();
1248+ m_thread_pool = nullptr ;
12741249 }
12751250
1276- public:
12771251 void ProcessCommandRange (uint64_t shaderStart, uint64_t shaderEnd,
12781252 const char *temp_path, bool is_verbose,
12791253 CShaderMap &byte_code,
12801254 CompilerShaderStats &compiler_stats) const ;
12811255
1282- protected:
1283- void Startup (IThreadPool *pool);
1284- void Shutdown ();
1285-
12861256 //
12871257 // Multi-threaded section
1288- protected:
1289- struct MT {
1290- MT () : pWorkerObj(nullptr ), pThreadPool(nullptr ) {}
1291-
1292- typedef CThreadFastMutex MultiThreadMutex_t;
1293- MultiThreadMutex_t mtx;
1294-
1295- typedef CWorkerAccumState<MultiThreadMutex_t> WorkerClass_t;
1296- WorkerClass_t *pWorkerObj;
1297-
1298- IThreadPool *pThreadPool;
1299- ThreadPoolStartParams_t tpsp;
1300- } m_MT;
1301-
1302- //
1303- // Single-threaded section
1304- protected:
1305- struct ST {
1306- ST () : pWorkerObj(nullptr ) {}
1258+ private:
1259+ using MultiThreadMutex_t = CThreadFastMutex;
1260+ MultiThreadMutex_t m_mutex;
13071261
1308- typedef CThreadNullMutex NullMutex_t ;
1309- NullMutex_t mtx ;
1262+ using WorkerClass_t = CWorkerAccumState<MultiThreadMutex_t> ;
1263+ WorkerClass_t *m_worker ;
13101264
1311- typedef CWorkerAccumState<NullMutex_t> WorkerClass_t;
1312- WorkerClass_t *pWorkerObj;
1313- } m_ST;
1265+ IThreadPool *m_thread_pool;
13141266};
13151267
1316- void ProcessCommandRange_Singleton::Startup (IThreadPool *pool) {
1317- bool is_thread_pool = false ;
1318- CPUInformation const &cpu = *GetCPUInformation ();
1319-
1320- if (cpu.m_nLogicalProcessors > 1 ) {
1321- // Attempt to initialize thread pool
1322- m_MT.pThreadPool = pool;
1323- if (m_MT.pThreadPool ) {
1324- m_MT.tpsp .bIOThreads = false ;
1325- m_MT.tpsp .nThreads = cpu.m_nLogicalProcessors - 1 ;
1326-
1327- if (m_MT.pThreadPool ->Start (m_MT.tpsp )) {
1328- if (m_MT.pThreadPool ->NumThreads () >= 1 ) {
1329- // Make sure that our mutex is in multi-threaded mode
1330- threading::g_mtxGlobal.SetThreadedMode (
1331- threading::Mode::MultiThreaded);
1332-
1333- m_MT.pWorkerObj = new MT::WorkerClass_t (&m_MT.mtx , pool);
1334-
1335- is_thread_pool = true ;
1336-
1337- // Thread pools threads # + main thread.
1338- Msg (" Using %zd threads to compile shaders.\n " ,
1339- m_MT.pThreadPool ->NumThreads () + 1 );
1340- } else {
1341- m_MT.pThreadPool ->Stop ();
1342- }
1343- }
1344-
1345- if (!is_thread_pool) m_MT.pThreadPool = nullptr ;
1346- }
1347- }
1348-
1349- // Otherwise initialize single-threaded mode
1350- if (!is_thread_pool)
1351- m_ST.pWorkerObj = new ST::WorkerClass_t (&m_ST.mtx , nullptr );
1352- }
1353-
1354- void ProcessCommandRange_Singleton::Shutdown () {
1355- if (m_MT.pThreadPool ) {
1356- if (m_MT.pWorkerObj ) delete m_MT.pWorkerObj ;
1357-
1358- m_MT.pThreadPool ->Stop ();
1359- m_MT.pThreadPool = nullptr ;
1360- } else {
1361- if (m_ST.pWorkerObj ) delete m_ST.pWorkerObj ;
1362- }
1363- }
1364-
1365- void ProcessCommandRange_Singleton::ProcessCommandRange (
1268+ void RangeProcessor::ProcessCommandRange (
13661269 uint64_t shaderStart, uint64_t shaderEnd, const char *temp_path,
13671270 bool is_verbose, CShaderMap &byte_code,
13681271 CompilerShaderStats &compiler_stats) const {
1369- if (m_MT.pThreadPool ) {
1370- MT::WorkerClass_t *pWorkerObj = m_MT.pWorkerObj ;
1371-
1372- pWorkerObj->RangeBegin (shaderStart, shaderEnd, temp_path, is_verbose,
1373- byte_code, compiler_stats);
1374- pWorkerObj->Run ();
1375- pWorkerObj->RangeFinished ();
1376- } else {
1377- ST::WorkerClass_t *pWorkerObj = m_ST.pWorkerObj ;
1378-
1379- pWorkerObj->RangeBegin (shaderStart, shaderEnd, temp_path, is_verbose,
1380- byte_code, compiler_stats);
1381- pWorkerObj->OnProcessST ();
1382- pWorkerObj->RangeFinished ();
1272+ if (m_thread_pool) {
1273+ m_worker->RangeBegin (shaderStart, shaderEnd, temp_path, is_verbose,
1274+ byte_code, compiler_stats);
1275+ m_worker->Run ();
1276+ m_worker->RangeFinished ();
13831277 }
13841278}
13851279
13861280// You must process the work unit range.
1387- void ProcessCommandRange (uint64_t shaderStart , uint64_t shaderEnd ,
1388- const char *temp_path, bool is_verbose ,
1389- CShaderMap &byte_code,
1281+ void ProcessCommandRange (RangeProcessor &processor , uint64_t shaderStart ,
1282+ uint64_t shaderEnd, const char *temp_path,
1283+ bool is_verbose, CShaderMap &byte_code,
13901284 CompilerShaderStats &compiler_stats) {
1391- ProcessCommandRange_Singleton::GetInstance ()-> ProcessCommandRange (
1392- shaderStart, shaderEnd, temp_path, is_verbose, byte_code, compiler_stats);
1285+ processor. ProcessCommandRange (shaderStart, shaderEnd, temp_path, is_verbose,
1286+ byte_code, compiler_stats);
13931287}
13941288
13951289void ParseShaderInfoFromCompileCommands (
@@ -1711,13 +1605,12 @@ int SetupTempPath(int argc, char **argv, char (&temp_path)[size]) {
17111605 return 0 ;
17121606}
17131607
1714- uint64_t CompileShaders (
1715- const char *shader_path, const char *temp_path,
1608+ void CompileShaders (
1609+ IThreadPool *thread_pool, const char *shader_path, const char *temp_path,
17161610 const std::unique_ptr<
17171611 se::shader_compile::shader_combo_processor::CfgEntryInfo[]> &configs,
17181612 bool is_verbose, CompilerShaderStats &compiler_stats) {
1719- ProcessCommandRange_Singleton pcr;
1720- uint64_t completed_commands_num{0 };
1613+ RangeProcessor processor{thread_pool};
17211614
17221615 CUtlStringMap<ShaderInfo_t> shader_info_map;
17231616 char chCommands[32 ], chStaticCombos[32 ], chDynamicCombos[32 ];
@@ -1743,8 +1636,7 @@ uint64_t CompileShaders(
17431636 V_sprintf_safe (chDynamicCombos, " %s" ,
17441637 PrettyPrintNumber (pEntry->m_numDynamicCombos ));
17451638
1746- Msg (" Compiling %s commands in %s static, %s dynamic combos for "
1747- " %s...\n " ,
1639+ Msg (" Compiling %s commands in %s static, %s dynamic combos in %s...\n " ,
17481640 chCommands, chStaticCombos, chDynamicCombos, pEntry->m_szName );
17491641 }
17501642
@@ -1753,25 +1645,22 @@ uint64_t CompileShaders(
17531645 //
17541646 // Compile stuff
17551647 //
1756- ProcessCommandRange (pEntry->m_iCommandStart , pEntry->m_iCommandEnd ,
1757- temp_path, is_verbose, byte_code, compiler_stats);
1648+ ProcessCommandRange (processor, pEntry->m_iCommandStart ,
1649+ pEntry->m_iCommandEnd , temp_path, is_verbose, byte_code,
1650+ compiler_stats);
17581651
17591652 //
17601653 // Now when the whole shader is finished we can write it
17611654 //
1762- char const *szShaderToWrite = pEntry->m_szName ;
1655+ char const *shader_name = pEntry->m_szName ;
17631656
1764- WriteShaderFiles (shader_path, szShaderToWrite , configs, shader_info_map,
1657+ WriteShaderFiles (shader_path, shader_name , configs, shader_info_map,
17651658 byte_code, compiler_stats, pEntry->m_iCommandEnd ,
17661659 pEntry->m_iCommandEnd , is_verbose);
1767-
1768- completed_commands_num += pEntry->m_iCommandEnd - pEntry->m_iCommandStart ;
17691660 }
17701661
17711662 // dimhotepus: Correctly rewrite long strings.
17721663 Msg (" \r \r " );
1773-
1774- return completed_commands_num;
17751664}
17761665
17771666class ScopedConsoleCtrlHandler {
@@ -1826,6 +1715,25 @@ class ScopedThreadExecutionState {
18261715 const ThreadExecutionState old_state_, new_state_;
18271716};
18281717
1718+ IThreadPool *StartThreadPool (const CPUInformation *cpu) {
1719+ ThreadPoolStartParams_t args;
1720+ args.bIOThreads = false ;
1721+ args.nThreads = cpu->m_nLogicalProcessors - 1 ;
1722+
1723+ auto pool = g_pThreadPool;
1724+ if (pool->Start (args)) {
1725+ // Make sure that our mutex is in multi-threaded mode
1726+ threading::g_mtxGlobal.SetThreadedMode (threading::Mode::MultiThreaded);
1727+
1728+ // Thread pools threads # + main thread.
1729+ Msg (" Using %zd threads to compile shaders.\n " , pool->NumThreads () + 1 );
1730+ return pool;
1731+ }
1732+
1733+ Warning (" Unable to start thread pool with %d threads.\n " , args.nThreads );
1734+ return nullptr ;
1735+ }
1736+
18291737BOOL WINAPI OnCtrlBreak (DWORD ctrl_type) {
18301738 Warning (" Stopping compilation due to Ctrl+C.\n " );
18311739 return FALSE ;
@@ -1845,6 +1753,7 @@ int ShaderCompileMain(int argc, char *argv[]) {
18451753 const ScopedConsoleCtrlHandler scoped_ctrl_handler{OnCtrlBreak};
18461754
18471755 EnableCrashingOnCrashes ();
1756+ InstallSpewFunction ();
18481757
18491758 ThreadSetDebugName (" ShaderCompile_Main" );
18501759
@@ -1855,6 +1764,8 @@ int ShaderCompileMain(int argc, char *argv[]) {
18551764 ICommandLine *cmd_line{CommandLine ()};
18561765 cmd_line->CreateCmdLine (argc, argv);
18571766
1767+ const CPUInformation *cpu = GetCPUInformation ();
1768+
18581769 {
18591770 Msg (" \n Cmd line: " );
18601771 for (int i{0 }, args_count{cmd_line->ParmCount ()}; i < args_count; ++i) {
@@ -1865,17 +1776,16 @@ int ShaderCompileMain(int argc, char *argv[]) {
18651776 constexpr char kThreadsArg []{" -threads" };
18661777
18671778 if (!cmd_line->HasParm (kThreadsArg )) {
1868- const CPUInformation &ci = *GetCPUInformation ();
1869-
18701779 char threads_arg[12 ];
1871- V_to_chars (threads_arg, ci. m_nLogicalProcessors );
1780+ V_to_chars (threads_arg, cpu-> m_nLogicalProcessors );
18721781
18731782 // Ensure thread pool does not cap threads count to default.
18741783 cmd_line->AppendParm (kThreadsArg , threads_arg);
18751784 }
18761785 }
18771786
1878- InstallSpewFunction ();
1787+ IThreadPool *thread_pool = StartThreadPool (cpu);
1788+ if (!thread_pool) return EINVAL;
18791789
18801790 char exe_dir[MAX_PATH];
18811791 SetupExeDir (argc, argv, exe_dir);
@@ -1937,9 +1847,8 @@ int ShaderCompileMain(int argc, char *argv[]) {
19371847 }
19381848
19391849 CompilerShaderStats compiler_stats;
1940-
1941- const uint64_t completed_commands_num{CompileShaders (
1942- shader_path, temp_path, parseResult.configs , is_verbose, compiler_stats)};
1850+ CompileShaders (thread_pool, shader_path, temp_path, parseResult.configs ,
1851+ is_verbose, compiler_stats);
19431852
19441853 Msg (" \r \r " );
19451854
@@ -2041,12 +1950,14 @@ int ShaderCompileMain(int argc, char *argv[]) {
20411950 // End
20421951 const double compile_end_time{Plat_FloatTime ()};
20431952
2044- GetHourMinuteSecondsString (
2045- static_cast <int >(compile_end_time - compile_start_time), command);
1953+ if (is_verbose) {
1954+ GetHourMinuteSecondsString (
1955+ static_cast <int >(compile_end_time - compile_start_time), command);
20461956
2047- DebugOut (is_verbose, " %s elapsed\n " , command);
2048- DebugOut (is_verbose, " precise timing = %.5fs\n " ,
2049- (compile_end_time - compile_start_time));
1957+ DebugOut (is_verbose, " %s elapsed.\n " , command);
1958+ DebugOut (is_verbose, " precise timing = %.5fs\n " ,
1959+ (compile_end_time - compile_start_time));
1960+ }
20501961
20511962 return shader_had_error_map.GetNumStrings ();
20521963}
0 commit comments