Skip to content

Commit f1bcca7

Browse files
committed
shadercompile: Drop single threaded compilation
1 parent d93677d commit f1bcca7

File tree

1 file changed

+73
-157
lines changed

1 file changed

+73
-157
lines changed

utils/shadercompile/shadercompile.cpp

Lines changed: 73 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -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

13951294
void 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

17771671
class 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+
18291742
BOOL 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("\nCmd 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

Comments
 (0)