VideoBackends: Support a different number of threads for precompiling

At runtime, we only really want a single shader compiler thread.
However, for initial boots, we can use a higher number to speed things
up.
This commit is contained in:
Stenzek
2017-07-27 13:15:38 +10:00
parent e17efb1d8d
commit c8f31656cb
14 changed files with 81 additions and 27 deletions

View File

@ -106,8 +106,11 @@ void AsyncShaderCompiler::WaitUntilCompletion(
}
}
void AsyncShaderCompiler::StartWorkerThreads(u32 num_worker_threads)
bool AsyncShaderCompiler::StartWorkerThreads(u32 num_worker_threads)
{
if (num_worker_threads == 0)
return true;
for (u32 i = 0; i < num_worker_threads; i++)
{
void* thread_param = nullptr;
@ -131,6 +134,17 @@ void AsyncShaderCompiler::StartWorkerThreads(u32 num_worker_threads)
m_worker_threads.push_back(std::move(thr));
}
return HasWorkerThreads();
}
bool AsyncShaderCompiler::ResizeWorkerThreads(u32 num_worker_threads)
{
if (m_worker_threads.size() == num_worker_threads)
return true;
StopWorkerThreads();
return StartWorkerThreads(num_worker_threads);
}
bool AsyncShaderCompiler::HasWorkerThreads() const
@ -140,6 +154,9 @@ bool AsyncShaderCompiler::HasWorkerThreads() const
void AsyncShaderCompiler::StopWorkerThreads()
{
if (!HasWorkerThreads())
return;
// Signal worker threads to stop, and wake all of them.
{
std::lock_guard<std::mutex> guard(m_pending_work_lock);
@ -151,6 +168,7 @@ void AsyncShaderCompiler::StopWorkerThreads()
for (std::thread& thr : m_worker_threads)
thr.join();
m_worker_threads.clear();
m_exit_flag.Clear();
}
bool AsyncShaderCompiler::WorkerThreadInitMainThread(void** param)

View File

@ -52,7 +52,8 @@ public:
void WaitUntilCompletion(const std::function<void(size_t, size_t)>& progress_callback);
// Needed because of calling virtual methods in shutdown procedure.
void StartWorkerThreads(u32 num_worker_threads);
bool StartWorkerThreads(u32 num_worker_threads);
bool ResizeWorkerThreads(u32 num_worker_threads);
bool HasWorkerThreads() const;
void StopWorkerThreads();

View File

@ -98,6 +98,7 @@ void VideoConfig::Refresh()
bDisableSpecializedShaders = Config::Get(Config::GFX_DISABLE_SPECIALIZED_SHADERS);
bPrecompileUberShaders = Config::Get(Config::GFX_PRECOMPILE_UBER_SHADERS);
iShaderCompilerThreads = Config::Get(Config::GFX_SHADER_COMPILER_THREADS);
iShaderPrecompilerThreads = Config::Get(Config::GFX_SHADER_PRECOMPILER_THREADS);
bForceVertexUberShaders = Config::Get(Config::GFX_FORCE_VERTEX_UBER_SHADERS);
bForcePixelUberShaders = Config::Get(Config::GFX_FORCE_PIXEL_UBER_SHADERS);
@ -196,13 +197,26 @@ bool VideoConfig::IsVSync()
return bVSync && !Core::GetIsThrottlerTempDisabled();
}
static u32 GetNumAutoShaderCompilerThreads()
{
// Automatic number. We use clamp(cpus - 3, 1, 4).
return static_cast<u32>(std::min(std::max(cpu_info.num_cores - 3, 1), 4));
}
u32 VideoConfig::GetShaderCompilerThreads() const
{
if (iShaderCompilerThreads >= 0)
return static_cast<u32>(iShaderCompilerThreads);
else
return GetNumAutoShaderCompilerThreads();
}
// Automatic number. We use clamp(cpus - 3, 1, 4).
return static_cast<u32>(std::min(std::max(cpu_info.num_cores - 3, 1), 4));
u32 VideoConfig::GetShaderPrecompilerThreads() const
{
if (iShaderPrecompilerThreads >= 0)
return static_cast<u32>(iShaderPrecompilerThreads);
else
return GetNumAutoShaderCompilerThreads();
}
bool VideoConfig::CanUseUberShaders() const

View File

@ -192,6 +192,7 @@ struct VideoConfig final
// 0 disables background compilation.
// -1 uses an automatic number based on the CPU threads.
int iShaderCompilerThreads;
int iShaderPrecompilerThreads;
// Temporary toggling of ubershaders, for debugging
bool bForceVertexUberShaders;
@ -256,6 +257,7 @@ struct VideoConfig final
}
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != SCALE_1X; }
u32 GetShaderCompilerThreads() const;
u32 GetShaderPrecompilerThreads() const;
bool CanUseUberShaders() const;
bool CanPrecompileUberShaders() const;
bool CanBackgroundCompileShaders() const;