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
|
// Read our shader cache, only if supported and enabled
|
||||||
if (g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache)
|
if (g_ogl_config.bSupportsGLSLCache && g_ActiveConfig.bShaderCache)
|
||||||
{
|
LoadProgramBinaries();
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateHeader();
|
CreateHeader();
|
||||||
|
|
||||||
|
@ -534,47 +512,99 @@ void ProgramShaderCache::Init()
|
||||||
last_entry = nullptr;
|
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()
|
void ProgramShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
// store all shaders in cache on disk
|
// 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
|
continue;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_program_disk_cache.Sync();
|
GLint link_status = GL_FALSE, delete_status = GL_TRUE, binary_size = 0;
|
||||||
g_program_disk_cache.Close();
|
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);
|
glUseProgram(0);
|
||||||
|
|
||||||
for (auto& entry : pshaders)
|
for (auto& entry : pshaders)
|
||||||
|
@ -582,8 +612,6 @@ void ProgramShaderCache::Shutdown()
|
||||||
entry.second.Destroy();
|
entry.second.Destroy();
|
||||||
}
|
}
|
||||||
pshaders.clear();
|
pshaders.clear();
|
||||||
|
|
||||||
s_buffer.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramShaderCache::CreateHeader()
|
void ProgramShaderCache::CreateHeader()
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
static void UploadConstants();
|
static void UploadConstants();
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
|
static void Reload();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void CreateHeader();
|
static void CreateHeader();
|
||||||
|
|
||||||
|
@ -82,6 +83,10 @@ private:
|
||||||
void Read(const SHADERUID& key, const u8* value, u32 value_size) override;
|
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;
|
typedef std::map<SHADERUID, PCacheEntry> PCache;
|
||||||
static PCache pshaders;
|
static PCache pshaders;
|
||||||
static PCacheEntry* last_entry;
|
static PCacheEntry* last_entry;
|
||||||
|
|
|
@ -688,6 +688,7 @@ Renderer::Renderer()
|
||||||
|
|
||||||
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
|
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
|
||||||
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
|
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
|
||||||
|
m_last_host_config_bits = g_ActiveConfig.GetHostConfigBits();
|
||||||
|
|
||||||
// Handle VSync on/off
|
// Handle VSync on/off
|
||||||
s_vsync = g_ActiveConfig.IsVSync();
|
s_vsync = g_ActiveConfig.IsVSync();
|
||||||
|
@ -1469,6 +1470,15 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
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.
|
// For testing zbuffer targets.
|
||||||
// Renderer::SetZBufferRender();
|
// Renderer::SetZBufferRender();
|
||||||
// SaveTexture("tex.png", GL_TEXTURE_2D, s_FakeZTarget,
|
// SaveTexture("tex.png", GL_TEXTURE_2D, s_FakeZTarget,
|
||||||
|
|
|
@ -148,5 +148,8 @@ private:
|
||||||
std::array<int, 2> m_last_frame_height = {};
|
std::array<int, 2> m_last_frame_height = {};
|
||||||
bool m_last_frame_exported = false;
|
bool m_last_frame_exported = false;
|
||||||
AVIDump::Frame m_last_frame_state;
|
AVIDump::Frame m_last_frame_state;
|
||||||
|
|
||||||
|
// last host config state
|
||||||
|
u32 m_last_host_config_bits = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue