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

@ -513,7 +513,7 @@ void PixelShaderCache::Init()
LoadShaderCache();
if (g_ActiveConfig.CanPrecompileUberShaders())
PrecompileUberShaders();
QueueUberShaderCompiles();
}
void PixelShaderCache::LoadShaderCache()
@ -538,7 +538,7 @@ void PixelShaderCache::Reload()
LoadShaderCache();
if (g_ActiveConfig.CanPrecompileUberShaders())
PrecompileUberShaders();
QueueUberShaderCompiles();
}
// ONLY to be used during shutdown.
@ -757,7 +757,7 @@ bool PixelShaderCache::InsertShader(const UberShader::PixelShaderUid& uid,
return (shader != nullptr);
}
void PixelShaderCache::PrecompileUberShaders()
void PixelShaderCache::QueueUberShaderCompiles()
{
UberShader::EnumeratePixelShaderUids([&](const UberShader::PixelShaderUid& uid) {
if (UberPixelShaders.find(uid) != UberPixelShaders.end())

View File

@ -28,7 +28,7 @@ public:
static bool InsertByteCode(const UberShader::PixelShaderUid& uid, const u8* data, size_t len);
static bool InsertShader(const PixelShaderUid& uid, ID3D11PixelShader* shader);
static bool InsertShader(const UberShader::PixelShaderUid& uid, ID3D11PixelShader* shader);
static void PrecompileUberShaders();
static void QueueUberShaderCompiles();
static ID3D11Buffer* GetConstantBuffer();

View File

@ -174,11 +174,12 @@ void VertexShaderCache::Init()
LoadShaderCache();
g_async_compiler = std::make_unique<VideoCommon::AsyncShaderCompiler>();
if (g_ActiveConfig.GetShaderCompilerThreads() > 0)
g_async_compiler->StartWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
g_async_compiler->ResizeWorkerThreads(g_ActiveConfig.CanPrecompileUberShaders() ?
g_ActiveConfig.GetShaderPrecompilerThreads() :
g_ActiveConfig.GetShaderCompilerThreads());
if (g_ActiveConfig.CanPrecompileUberShaders())
PrecompileUberShaders();
QueueUberShaderCompiles();
}
void VertexShaderCache::LoadShaderCache()
@ -206,7 +207,7 @@ void VertexShaderCache::Reload()
LoadShaderCache();
if (g_ActiveConfig.CanPrecompileUberShaders())
PrecompileUberShaders();
QueueUberShaderCompiles();
}
void VertexShaderCache::Clear()
@ -426,7 +427,7 @@ void VertexShaderCache::RetreiveAsyncShaders()
g_async_compiler->RetrieveWorkItems();
}
void VertexShaderCache::PrecompileUberShaders()
void VertexShaderCache::QueueUberShaderCompiles()
{
UberShader::EnumerateVertexShaderUids([&](const UberShader::VertexShaderUid& uid) {
if (ubervshaders.find(uid) != ubervshaders.end())
@ -435,13 +436,19 @@ void VertexShaderCache::PrecompileUberShaders()
g_async_compiler->QueueWorkItem(
g_async_compiler->CreateWorkItem<UberVertexShaderCompilerWorkItem>(uid));
});
}
void VertexShaderCache::WaitForBackgroundCompilesToComplete()
{
g_async_compiler->WaitUntilCompletion([](size_t completed, size_t total) {
Host_UpdateProgressDialog(GetStringT("Compiling shaders...").c_str(),
static_cast<int>(completed), static_cast<int>(total));
});
g_async_compiler->RetrieveWorkItems();
Host_UpdateProgressDialog("", -1, -1);
// Switch from precompile -> runtime compiler threads.
g_async_compiler->ResizeWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
}
VertexShaderCache::VertexShaderCompilerWorkItem::VertexShaderCompilerWorkItem(

View File

@ -27,7 +27,8 @@ public:
static bool SetShader(D3DVertexFormat* vertex_format);
static bool SetUberShader(D3DVertexFormat* vertex_format);
static void RetreiveAsyncShaders();
static void PrecompileUberShaders();
static void QueueUberShaderCompiles();
static void WaitForBackgroundCompilesToComplete();
static ID3D11Buffer*& GetConstantBuffer();

View File

@ -161,6 +161,7 @@ void VideoBackend::Video_Prepare()
VertexShaderCache::Init();
PixelShaderCache::Init();
GeometryShaderCache::Init();
VertexShaderCache::WaitForBackgroundCompilesToComplete();
D3D::InitUtils();
BBox::Init();
}

View File

@ -607,17 +607,8 @@ void ProgramShaderCache::Init()
// on the main thread the first time they are used, causing stutter. Nouveau has been
// reported to crash if draw calls are invoked on the shared context threads. For now,
// disable asynchronous compilation on Mesa.
if (!DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION) &&
g_ActiveConfig.GetShaderCompilerThreads() > 0)
{
if (!DriverDetails::HasBug(DriverDetails::BUG_SHARED_CONTEXT_SHADER_COMPILATION))
s_async_compiler = std::make_unique<SharedContextAsyncShaderCompiler>();
s_async_compiler->StartWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
if (!s_async_compiler->HasWorkerThreads())
{
// No point using the async compiler without workers.
s_async_compiler.reset();
}
}
// Read our shader cache, only if supported and enabled
if (g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache)
@ -630,7 +621,19 @@ void ProgramShaderCache::Init()
last_uber_entry = nullptr;
if (g_ActiveConfig.CanPrecompileUberShaders())
{
if (s_async_compiler)
s_async_compiler->ResizeWorkerThreads(g_ActiveConfig.GetShaderPrecompilerThreads());
PrecompileUberShaders();
}
if (s_async_compiler)
{
// No point using the async compiler without workers.
s_async_compiler->ResizeWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
if (!s_async_compiler->HasWorkerThreads())
s_async_compiler.reset();
}
}
void ProgramShaderCache::RetrieveAsyncShaders()

View File

@ -63,9 +63,9 @@ bool ShaderCache::Initialize()
return false;
m_async_shader_compiler = std::make_unique<VideoCommon::AsyncShaderCompiler>();
if (g_ActiveConfig.GetShaderCompilerThreads() > 0)
m_async_shader_compiler->StartWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
m_async_shader_compiler->ResizeWorkerThreads(g_ActiveConfig.CanPrecompileUberShaders() ?
g_ActiveConfig.GetShaderPrecompilerThreads() :
g_ActiveConfig.GetShaderCompilerThreads());
return true;
}
@ -1236,6 +1236,9 @@ void ShaderCache::PrecompileUberShaders()
});
WaitForBackgroundCompilesToComplete();
// Switch to the runtime/background thread config.
m_async_shader_compiler->ResizeWorkerThreads(g_ActiveConfig.GetShaderCompilerThreads());
}
void ShaderCache::WaitForBackgroundCompilesToComplete()