OGL: Reload shader cache when relevant video config changes
This commit is contained in:
parent
d1381f5021
commit
62a901508b
|
@ -504,29 +504,7 @@ void ProgramShaderCache::Init()
|
|||
|
||||
// Read our shader cache, only if supported and enabled
|
||||
if (g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache)
|
||||
{
|
||||
GLint Supported;
|
||||
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &Supported);
|
||||
if (!Supported)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "GL_ARB_get_program_binary is supported, but no binary format is known. So "
|
||||
"disable shader cache.");
|
||||
g_ogl_config.bSupportsGLSLCache = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||
|
||||
std::string cache_filename =
|
||||
StringFromFormat("%sogl-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||
SConfig::GetInstance().GetGameID().c_str());
|
||||
|
||||
ProgramShaderCacheInserter inserter;
|
||||
g_program_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
}
|
||||
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
|
||||
}
|
||||
LoadProgramBinaries();
|
||||
|
||||
CreateHeader();
|
||||
|
||||
|
@ -534,47 +512,99 @@ void ProgramShaderCache::Init()
|
|||
last_entry = nullptr;
|
||||
}
|
||||
|
||||
void ProgramShaderCache::Reload()
|
||||
{
|
||||
const bool use_cache = g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache;
|
||||
if (use_cache)
|
||||
SaveProgramBinaries();
|
||||
|
||||
g_program_disk_cache.Close();
|
||||
DestroyShaders();
|
||||
|
||||
if (use_cache)
|
||||
LoadProgramBinaries();
|
||||
|
||||
CurrentProgram = 0;
|
||||
last_entry = nullptr;
|
||||
last_uid = {};
|
||||
}
|
||||
|
||||
void ProgramShaderCache::Shutdown()
|
||||
{
|
||||
// store all shaders in cache on disk
|
||||
if (g_ogl_config.bSupportsGLSLCache)
|
||||
if (g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache)
|
||||
SaveProgramBinaries();
|
||||
g_program_disk_cache.Close();
|
||||
|
||||
DestroyShaders();
|
||||
s_buffer.reset();
|
||||
}
|
||||
|
||||
void ProgramShaderCache::LoadProgramBinaries()
|
||||
{
|
||||
GLint Supported;
|
||||
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &Supported);
|
||||
if (!Supported)
|
||||
{
|
||||
for (auto& entry : pshaders)
|
||||
ERROR_LOG(VIDEO, "GL_ARB_get_program_binary is supported, but no binary format is known. So "
|
||||
"disable shader cache.");
|
||||
g_ogl_config.bSupportsGLSLCache = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||
|
||||
std::string host_part = g_ActiveConfig.GetHostConfigFilename();
|
||||
std::string cache_filename =
|
||||
StringFromFormat("%sogl-%s-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
|
||||
SConfig::GetInstance().GetGameID().c_str(), host_part.c_str());
|
||||
|
||||
ProgramShaderCacheInserter inserter;
|
||||
g_program_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
}
|
||||
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
|
||||
}
|
||||
|
||||
void ProgramShaderCache::SaveProgramBinaries()
|
||||
{
|
||||
for (auto& entry : pshaders)
|
||||
{
|
||||
// Clear any prior error code
|
||||
glGetError();
|
||||
|
||||
if (entry.second.in_cache)
|
||||
{
|
||||
// Clear any prior error code
|
||||
glGetError();
|
||||
|
||||
if (entry.second.in_cache)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GLint link_status = GL_FALSE, delete_status = GL_TRUE, binary_size = 0;
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_LINK_STATUS, &link_status);
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_DELETE_STATUS, &delete_status);
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_PROGRAM_BINARY_LENGTH, &binary_size);
|
||||
if (glGetError() != GL_NO_ERROR || link_status == GL_FALSE || delete_status == GL_TRUE ||
|
||||
!binary_size)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<u8> data(binary_size + sizeof(GLenum));
|
||||
u8* binary = &data[sizeof(GLenum)];
|
||||
GLenum* prog_format = (GLenum*)&data[0];
|
||||
glGetProgramBinary(entry.second.shader.glprogid, binary_size, nullptr, prog_format, binary);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
g_program_disk_cache.Append(entry.first, &data[0], binary_size + sizeof(GLenum));
|
||||
continue;
|
||||
}
|
||||
|
||||
g_program_disk_cache.Sync();
|
||||
g_program_disk_cache.Close();
|
||||
GLint link_status = GL_FALSE, delete_status = GL_TRUE, binary_size = 0;
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_LINK_STATUS, &link_status);
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_DELETE_STATUS, &delete_status);
|
||||
glGetProgramiv(entry.second.shader.glprogid, GL_PROGRAM_BINARY_LENGTH, &binary_size);
|
||||
if (glGetError() != GL_NO_ERROR || link_status == GL_FALSE || delete_status == GL_TRUE ||
|
||||
!binary_size)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<u8> data(binary_size + sizeof(GLenum));
|
||||
u8* binary = &data[sizeof(GLenum)];
|
||||
GLenum* prog_format = (GLenum*)&data[0];
|
||||
glGetProgramBinary(entry.second.shader.glprogid, binary_size, nullptr, prog_format, binary);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
g_program_disk_cache.Append(entry.first, &data[0], binary_size + sizeof(GLenum));
|
||||
}
|
||||
|
||||
g_program_disk_cache.Sync();
|
||||
}
|
||||
|
||||
void ProgramShaderCache::DestroyShaders()
|
||||
{
|
||||
glUseProgram(0);
|
||||
|
||||
for (auto& entry : pshaders)
|
||||
|
@ -582,8 +612,6 @@ void ProgramShaderCache::Shutdown()
|
|||
entry.second.Destroy();
|
||||
}
|
||||
pshaders.clear();
|
||||
|
||||
s_buffer.reset();
|
||||
}
|
||||
|
||||
void ProgramShaderCache::CreateHeader()
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
static void UploadConstants();
|
||||
|
||||
static void Init();
|
||||
static void Reload();
|
||||
static void Shutdown();
|
||||
static void CreateHeader();
|
||||
|
||||
|
@ -82,6 +83,10 @@ private:
|
|||
void Read(const SHADERUID& key, const u8* value, u32 value_size) override;
|
||||
};
|
||||
|
||||
static void LoadProgramBinaries();
|
||||
static void SaveProgramBinaries();
|
||||
static void DestroyShaders();
|
||||
|
||||
typedef std::map<SHADERUID, PCacheEntry> PCache;
|
||||
static PCache pshaders;
|
||||
static PCacheEntry* last_entry;
|
||||
|
|
|
@ -688,6 +688,7 @@ Renderer::Renderer()
|
|||
|
||||
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
|
||||
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
|
||||
m_last_host_config_bits = g_ActiveConfig.GetHostConfigBits();
|
||||
|
||||
// Handle VSync on/off
|
||||
s_vsync = g_ActiveConfig.IsVSync();
|
||||
|
@ -1469,6 +1470,15 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
|||
UpdateActiveConfig();
|
||||
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
||||
|
||||
// Invalidate shader cache when the host config changes.
|
||||
u32 new_host_config_bits = g_ActiveConfig.GetHostConfigBits();
|
||||
if (new_host_config_bits != m_last_host_config_bits)
|
||||
{
|
||||
OSD::AddMessage("Video config changed, reloading shaders.", OSD::Duration::NORMAL);
|
||||
ProgramShaderCache::Reload();
|
||||
m_last_host_config_bits = new_host_config_bits;
|
||||
}
|
||||
|
||||
// For testing zbuffer targets.
|
||||
// Renderer::SetZBufferRender();
|
||||
// SaveTexture("tex.png", GL_TEXTURE_2D, s_FakeZTarget,
|
||||
|
|
|
@ -148,5 +148,8 @@ private:
|
|||
std::array<int, 2> m_last_frame_height = {};
|
||||
bool m_last_frame_exported = false;
|
||||
AVIDump::Frame m_last_frame_state;
|
||||
|
||||
// last host config state
|
||||
u32 m_last_host_config_bits = 0;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue