@@ -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,61 @@ 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+ // Make sure that our mutex is in multi-threaded mode
1245+ threading::g_mtxGlobal.SetThreadedMode (threading::Mode::MultiThreaded);
12631246
1264- public:
1265- ProcessCommandRange_Singleton () {
1266- Assert (!Instance ());
1267- Instance () = this ;
1268- Startup (g_pThreadPool);
1247+ m_worker = new WorkerClass_t (&m_mutex, pool);
12691248 }
1270- ~ProcessCommandRange_Singleton () {
1271- Assert (Instance () == this );
1272- Instance () = nullptr ;
1273- Shutdown ();
1249+ ~RangeProcessor () {
1250+ delete m_worker;
1251+
1252+ m_thread_pool->Stop ();
1253+ m_thread_pool = nullptr ;
12741254 }
12751255
1276- public:
12771256 void ProcessCommandRange (uint64_t shaderStart, uint64_t shaderEnd,
12781257 const char *temp_path, bool is_verbose,
12791258 CShaderMap &byte_code,
12801259 CompilerShaderStats &compiler_stats) const ;
12811260
1282- protected:
1283- void Startup (IThreadPool *pool);
1284- void Shutdown ();
1285-
12861261 //
12871262 // 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 ) {}
1263+ private:
1264+ using MultiThreadMutex_t = CThreadFastMutex;
1265+ MultiThreadMutex_t m_mutex;
13071266
1308- typedef CThreadNullMutex NullMutex_t ;
1309- NullMutex_t mtx ;
1267+ using WorkerClass_t = CWorkerAccumState<MultiThreadMutex_t> ;
1268+ WorkerClass_t *m_worker ;
13101269
1311- typedef CWorkerAccumState<NullMutex_t> WorkerClass_t;
1312- WorkerClass_t *pWorkerObj;
1313- } m_ST;
1270+ IThreadPool *m_thread_pool;
13141271};
13151272
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 (
1273+ void RangeProcessor::ProcessCommandRange (
13661274 uint64_t shaderStart, uint64_t shaderEnd, const char *temp_path,
13671275 bool is_verbose, CShaderMap &byte_code,
13681276 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 ();
1277+ if (m_thread_pool) {
1278+ m_worker->RangeBegin (shaderStart, shaderEnd, temp_path, is_verbose,
1279+ byte_code, compiler_stats);
1280+ m_worker->Run ();
1281+ m_worker->RangeFinished ();
13831282 }
13841283}
13851284
13861285// 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,
1286+ void ProcessCommandRange (RangeProcessor &processor , uint64_t shaderStart ,
1287+ uint64_t shaderEnd, const char *temp_path,
1288+ bool is_verbose, CShaderMap &byte_code,
13901289 CompilerShaderStats &compiler_stats) {
1391- ProcessCommandRange_Singleton::GetInstance ()-> ProcessCommandRange (
1392- shaderStart, shaderEnd, temp_path, is_verbose, byte_code, compiler_stats);
1290+ processor. ProcessCommandRange (shaderStart, shaderEnd, temp_path, is_verbose,
1291+ byte_code, compiler_stats);
13931292}
13941293
13951294void ParseShaderInfoFromCompileCommands (
@@ -1711,13 +1610,12 @@ int SetupTempPath(int argc, char **argv, char (&temp_path)[size]) {
17111610 return 0 ;
17121611}
17131612
1714- uint64_t CompileShaders (
1715- const char *shader_path, const char *temp_path,
1613+ void CompileShaders (
1614+ IThreadPool *thread_pool, const char *shader_path, const char *temp_path,
17161615 const std::unique_ptr<
17171616 se::shader_compile::shader_combo_processor::CfgEntryInfo[]> &configs,
17181617 bool is_verbose, CompilerShaderStats &compiler_stats) {
1719- ProcessCommandRange_Singleton pcr;
1720- uint64_t completed_commands_num{0 };
1618+ RangeProcessor processor{thread_pool};
17211619
17221620 CUtlStringMap<ShaderInfo_t> shader_info_map;
17231621 char chCommands[32 ], chStaticCombos[32 ], chDynamicCombos[32 ];
@@ -1743,8 +1641,7 @@ uint64_t CompileShaders(
17431641 V_sprintf_safe (chDynamicCombos, " %s" ,
17441642 PrettyPrintNumber (pEntry->m_numDynamicCombos ));
17451643
1746- Msg (" Compiling %s commands in %s static, %s dynamic combos for "
1747- " %s...\n " ,
1644+ Msg (" Compiling %s commands in %s static, %s dynamic combos in %s...\n " ,
17481645 chCommands, chStaticCombos, chDynamicCombos, pEntry->m_szName );
17491646 }
17501647
@@ -1753,25 +1650,22 @@ uint64_t CompileShaders(
17531650 //
17541651 // Compile stuff
17551652 //
1756- ProcessCommandRange (pEntry->m_iCommandStart , pEntry->m_iCommandEnd ,
1757- temp_path, is_verbose, byte_code, compiler_stats);
1653+ ProcessCommandRange (processor, pEntry->m_iCommandStart ,
1654+ pEntry->m_iCommandEnd , temp_path, is_verbose, byte_code,
1655+ compiler_stats);
17581656
17591657 //
17601658 // Now when the whole shader is finished we can write it
17611659 //
1762- char const *szShaderToWrite = pEntry->m_szName ;
1660+ char const *shader_name = pEntry->m_szName ;
17631661
1764- WriteShaderFiles (shader_path, szShaderToWrite , configs, shader_info_map,
1662+ WriteShaderFiles (shader_path, shader_name , configs, shader_info_map,
17651663 byte_code, compiler_stats, pEntry->m_iCommandEnd ,
17661664 pEntry->m_iCommandEnd , is_verbose);
1767-
1768- completed_commands_num += pEntry->m_iCommandEnd - pEntry->m_iCommandStart ;
17691665 }
17701666
17711667 // dimhotepus: Correctly rewrite long strings.
17721668 Msg (" \r \r " );
1773-
1774- return completed_commands_num;
17751669}
17761670
17771671class ScopedConsoleCtrlHandler {
@@ -1826,6 +1720,25 @@ class ScopedThreadExecutionState {
18261720 const ThreadExecutionState old_state_, new_state_;
18271721};
18281722
1723+ IThreadPool *StartThreadPool (const CPUInformation *cpu) {
1724+ ThreadPoolStartParams_t args;
1725+ args.bIOThreads = false ;
1726+ args.nThreads = cpu->m_nLogicalProcessors - 1 ;
1727+
1728+ auto pool = g_pThreadPool;
1729+ if (pool->Start (args)) {
1730+ // Make sure that our mutex is in multi-threaded mode
1731+ threading::g_mtxGlobal.SetThreadedMode (threading::Mode::MultiThreaded);
1732+
1733+ // Thread pools threads # + main thread.
1734+ Msg (" Using %zd threads to compile shaders.\n " , pool->NumThreads () + 1 );
1735+ return pool;
1736+ }
1737+
1738+ Warning (" Unable to start thread pool with %d threads.\n " , args.nThreads );
1739+ return nullptr ;
1740+ }
1741+
18291742BOOL WINAPI OnCtrlBreak (DWORD ctrl_type) {
18301743 Warning (" Stopping compilation due to Ctrl+C.\n " );
18311744 return FALSE ;
@@ -1845,6 +1758,7 @@ int ShaderCompileMain(int argc, char *argv[]) {
18451758 const ScopedConsoleCtrlHandler scoped_ctrl_handler{OnCtrlBreak};
18461759
18471760 EnableCrashingOnCrashes ();
1761+ InstallSpewFunction ();
18481762
18491763 ThreadSetDebugName (" ShaderCompile_Main" );
18501764
@@ -1855,6 +1769,8 @@ int ShaderCompileMain(int argc, char *argv[]) {
18551769 ICommandLine *cmd_line{CommandLine ()};
18561770 cmd_line->CreateCmdLine (argc, argv);
18571771
1772+ const CPUInformation *cpu = GetCPUInformation ();
1773+
18581774 {
18591775 Msg (" \n Cmd line: " );
18601776 for (int i{0 }, args_count{cmd_line->ParmCount ()}; i < args_count; ++i) {
@@ -1865,17 +1781,16 @@ int ShaderCompileMain(int argc, char *argv[]) {
18651781 constexpr char kThreadsArg []{" -threads" };
18661782
18671783 if (!cmd_line->HasParm (kThreadsArg )) {
1868- const CPUInformation &ci = *GetCPUInformation ();
1869-
18701784 char threads_arg[12 ];
1871- V_to_chars (threads_arg, ci. m_nLogicalProcessors );
1785+ V_to_chars (threads_arg, cpu-> m_nLogicalProcessors );
18721786
18731787 // Ensure thread pool does not cap threads count to default.
18741788 cmd_line->AppendParm (kThreadsArg , threads_arg);
18751789 }
18761790 }
18771791
1878- InstallSpewFunction ();
1792+ IThreadPool *thread_pool = StartThreadPool (cpu);
1793+ if (!thread_pool) return EINVAL;
18791794
18801795 char exe_dir[MAX_PATH];
18811796 SetupExeDir (argc, argv, exe_dir);
@@ -1937,9 +1852,8 @@ int ShaderCompileMain(int argc, char *argv[]) {
19371852 }
19381853
19391854 CompilerShaderStats compiler_stats;
1940-
1941- const uint64_t completed_commands_num{CompileShaders (
1942- shader_path, temp_path, parseResult.configs , is_verbose, compiler_stats)};
1855+ CompileShaders (thread_pool, shader_path, temp_path, parseResult.configs ,
1856+ is_verbose, compiler_stats);
19431857
19441858 Msg (" \r \r " );
19451859
@@ -2041,12 +1955,14 @@ int ShaderCompileMain(int argc, char *argv[]) {
20411955 // End
20421956 const double compile_end_time{Plat_FloatTime ()};
20431957
2044- GetHourMinuteSecondsString (
2045- static_cast <int >(compile_end_time - compile_start_time), command);
1958+ if (is_verbose) {
1959+ GetHourMinuteSecondsString (
1960+ static_cast <int >(compile_end_time - compile_start_time), command);
20461961
2047- DebugOut (is_verbose, " %s elapsed\n " , command);
2048- DebugOut (is_verbose, " precise timing = %.5fs\n " ,
2049- (compile_end_time - compile_start_time));
1962+ DebugOut (is_verbose, " %s elapsed.\n " , command);
1963+ DebugOut (is_verbose, " precise timing = %.5fs\n " ,
1964+ (compile_end_time - compile_start_time));
1965+ }
20501966
20511967 return shader_had_error_map.GetNumStrings ();
20521968}
0 commit comments