OGL: Make ProgramShaderCache thread safe

This commit is contained in:
Stenzek 2018-02-24 22:14:31 +10:00
parent 63838c013b
commit 00204dc988
2 changed files with 21 additions and 4 deletions

View File

@ -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();
}

View File

@ -6,6 +6,7 @@
#include <atomic>
#include <memory>
#include <mutex>
#include <tuple>
#include <unordered_map>
@ -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;