From 00204dc98866c180aecc8bbfac583af63fbe9676 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 24 Feb 2018 22:14:31 +1000 Subject: OGL: Make ProgramShaderCache thread safe --- .../Core/VideoBackends/OGL/ProgramShaderCache.cpp | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp') 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(); } -- cgit v1.2.3