Skip to content

Commit f26f1d4

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

File tree

1 file changed

+69
-158
lines changed

1 file changed

+69
-158
lines changed

utils/shadercompile/shadercompile.cpp

Lines changed: 69 additions & 158 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,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

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

17771666
class 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+
18291737
BOOL 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("\nCmd 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

Comments
 (0)