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 guard(pipelineprogramlock); + auto iter = pipelineprograms.find(key); + if (iter != pipelineprograms.end()) + { + iter->second->reference_count++; + return iter->second.get(); + } } std::unique_ptr prog = std::make_unique(); @@ -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 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(); } diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h index 635c1d3097..6db44460a1 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -242,6 +243,7 @@ private: static PCache pshaders; static UberPCache ubershaders; static PipelineProgramMap pipelineprograms; + static std::mutex pipelineprogramlock; static PCacheEntry* last_entry; static PCacheEntry* last_uber_entry; static SHADERUID last_uid;