summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-02-24 22:14:31 +1000
committerStenzek <stenzek@gmail.com>2018-03-10 15:55:56 +1000
commit00204dc98866c180aecc8bbfac583af63fbe9676 (patch)
tree9aa1db3be57910016cf19cb1ee9c08e754d8c136 /Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
parent63838c013bde06ed13bfc1b5e24c53594934f641 (diff)
OGL: Make ProgramShaderCache thread safe
Diffstat (limited to 'Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
index c2f9ddf468..5a3a09281f 100644
--- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
+++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
@@ -60,6 +60,7 @@ static GLuint CurrentProgram = 0;
ProgramShaderCache::PCache ProgramShaderCache::pshaders;
ProgramShaderCache::UberPCache ProgramShaderCache::ubershaders;
ProgramShaderCache::PipelineProgramMap ProgramShaderCache::pipelineprograms;
+std::mutex ProgramShaderCache::pipelineprogramlock;
ProgramShaderCache::PCacheEntry* ProgramShaderCache::last_entry;
ProgramShaderCache::PCacheEntry* ProgramShaderCache::last_uber_entry;
SHADERUID ProgramShaderCache::last_uid;
@@ -910,11 +911,14 @@ const PipelineProgram* ProgramShaderCache::GetPipelineProgram(const OGLShader* v
const OGLShader* pixel_shader)
{
PipelineProgramKey key = {vertex_shader, geometry_shader, pixel_shader};
- auto iter = pipelineprograms.find(key);
- if (iter != pipelineprograms.end())
{
- iter->second->reference_count++;
- return iter->second.get();
+ std::lock_guard<std::mutex> guard(pipelineprogramlock);
+ auto iter = pipelineprograms.find(key);
+ if (iter != pipelineprograms.end())
+ {
+ iter->second->reference_count++;
+ return iter->second.get();
+ }
}
std::unique_ptr<PipelineProgram> prog = std::make_unique<PipelineProgram>();
@@ -941,6 +945,17 @@ const PipelineProgram* ProgramShaderCache::GetPipelineProgram(const OGLShader* v
return nullptr;
}
+ // Lock to insert. A duplicate program may have been created in the meantime.
+ std::lock_guard<std::mutex> guard(pipelineprogramlock);
+ auto iter = pipelineprograms.find(key);
+ if (iter != pipelineprograms.end())
+ {
+ // Destroy this program, and use the one which was created first.
+ prog->shader.Destroy();
+ iter->second->reference_count++;
+ return iter->second.get();
+ }
+
auto ip = pipelineprograms.emplace(key, std::move(prog));
return ip.first->second.get();
}