enable shader cache again

This commit is contained in:
degasus 2013-02-13 16:30:15 +01:00
parent 398b37f371
commit b3675d15dc
3 changed files with 45 additions and 70 deletions

View File

@ -34,9 +34,6 @@ u32 ProgramShaderCache::s_ubo_buffer_size;
bool ProgramShaderCache::s_ubo_dirty; bool ProgramShaderCache::s_ubo_dirty;
LinearDiskCache<SHADERUID, u8> g_program_disk_cache; LinearDiskCache<SHADERUID, u8> g_program_disk_cache;
GLenum ProgramFormat;
GLuint ProgramShaderCache::PCacheEntry::prog_format = 0;
static StreamBuffer *s_buffer; static StreamBuffer *s_buffer;
@ -216,6 +213,7 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen
// Make an entry in the table // Make an entry in the table
PCacheEntry& newentry = pshaders[uid]; PCacheEntry& newentry = pshaders[uid];
last_entry = &newentry; last_entry = &newentry;
newentry.in_cache = 0;
const char *vcode = GenerateVertexShaderCode(components, API_OPENGL); const char *vcode = GenerateVertexShaderCode(components, API_OPENGL);
const char *pcode = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components); const char *pcode = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
@ -413,8 +411,15 @@ void ProgramShaderCache::Init(void)
// Read our shader cache, only if supported // Read our shader cache, only if supported
if (g_ActiveConfig.backend_info.bSupportsGLSLCache) if (g_ActiveConfig.backend_info.bSupportsGLSLCache)
{ {
PCacheEntry::prog_format = PCacheEntry::SetProgramFormat(); 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_ActiveConfig.backend_info.bSupportsGLSLCache = false;
}
else
{
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sogl-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), sprintf(cache_filename, "%sogl-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
@ -422,6 +427,8 @@ void ProgramShaderCache::Init(void)
ProgramShaderCacheInserter inserter; ProgramShaderCacheInserter inserter;
g_program_disk_cache.OpenAndRead(cache_filename, inserter); g_program_disk_cache.OpenAndRead(cache_filename, inserter);
} }
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
}
CurrentProgram = 0; CurrentProgram = 0;
last_entry = NULL; last_entry = NULL;
@ -429,13 +436,25 @@ void ProgramShaderCache::Init(void)
void ProgramShaderCache::Shutdown(void) void ProgramShaderCache::Shutdown(void)
{ {
// store all shaders in cache on disk
if (g_ActiveConfig.backend_info.bSupportsGLSLCache) if (g_ActiveConfig.backend_info.bSupportsGLSLCache)
{ {
PCache::iterator iter = pshaders.begin(); PCache::iterator iter = pshaders.begin();
for (; iter != pshaders.end(); ++iter) for (; iter != pshaders.end(); ++iter)
{ {
g_program_disk_cache.Append(iter->first, iter->second.GetProgram(), iter->second.Size()); if(iter->second.in_cache) continue;
iter->second.FreeProgram();
GLint binary_size;
glGetProgramiv(iter->second.shader.glprogid, GL_PROGRAM_BINARY_LENGTH, &binary_size);
if(!binary_size) continue;
u8 *data = new u8[binary_size+sizeof(GLenum)];
u8 *binary = data + sizeof(GLenum);
GLenum *prog_format = (GLenum*)data;
glGetProgramBinary(iter->second.shader.glprogid, binary_size, NULL, prog_format, binary);
g_program_disk_cache.Append(iter->first, data, binary_size+sizeof(GLenum));
delete [] data;
} }
g_program_disk_cache.Sync(); g_program_disk_cache.Sync();
@ -460,11 +479,14 @@ void ProgramShaderCache::Shutdown(void)
void ProgramShaderCache::ProgramShaderCacheInserter::Read ( const SHADERUID& key, const u8* value, u32 value_size ) void ProgramShaderCache::ProgramShaderCacheInserter::Read ( const SHADERUID& key, const u8* value, u32 value_size )
{ {
// The two shaders might not even exist anymore const u8 *binary = value+sizeof(GLenum);
// But it is fine, no need to worry about that GLenum *prog_format = (GLenum*)value;
GLint binary_size = value_size-sizeof(GLenum);
PCacheEntry entry; PCacheEntry entry;
entry.in_cache = 1;
entry.shader.glprogid = glCreateProgram(); entry.shader.glprogid = glCreateProgram();
glProgramBinary(entry.shader.glprogid, entry.prog_format, value, value_size); glProgramBinary(entry.shader.glprogid, *prog_format, binary, binary_size);
GLint success; GLint success;
glGetProgramiv(entry.shader.glprogid, GL_LINK_STATUS, &success); glGetProgramiv(entry.shader.glprogid, GL_LINK_STATUS, &success);
@ -474,6 +496,8 @@ void ProgramShaderCache::ProgramShaderCacheInserter::Read ( const SHADERUID& key
pshaders[key] = entry; pshaders[key] = entry;
entry.shader.SetProgramVariables(); entry.shader.SetProgramVariables();
} }
else
glDeleteProgram(entry.shader.glprogid);
} }

View File

@ -86,60 +86,11 @@ public:
{ {
SHADER shader; SHADER shader;
SHADERUIDSAFE safe_uid; SHADERUIDSAFE safe_uid;
bool in_cache;
static GLenum prog_format;
u8 *binary;
GLint binary_size;
PCacheEntry() :binary(NULL), binary_size(0) { }
~PCacheEntry() {}
void Destroy() void Destroy()
{ {
shader.Destroy(); shader.Destroy();
FreeProgram();
}
void UpdateSize()
{
if (binary_size == 0)
glGetProgramiv(shader.glprogid, GL_PROGRAM_BINARY_LENGTH, &binary_size);
}
// No idea how necessary this is
static GLenum SetProgramFormat()
{
GLint Supported;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &Supported);
GLint *Formats = new GLint[Supported];
glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, Formats);
// We don't really care about format
GLenum prog_format = (GLenum)Formats[0];
delete[] Formats;
return prog_format;
}
u8 *GetProgram()
{
UpdateSize();
FreeProgram();
binary = new u8[binary_size];
glGetProgramBinary(shader.glprogid, binary_size, NULL, &prog_format, binary);
return binary;
}
void FreeProgram()
{
delete [] binary;
binary = NULL;
}
GLint Size()
{
UpdateSize();
return binary_size;
} }
}; };

View File

@ -308,14 +308,14 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsGLSync = GLEW_ARB_sync; g_Config.backend_info.bSupportsGLSync = GLEW_ARB_sync;
//TODO: revert this after cache is fixed itself g_Config.backend_info.bSupportsGLSLCache = GLEW_ARB_get_program_binary;
g_Config.backend_info.bSupportsGLSLCache = false; // GLEW_ARB_get_program_binary
UpdateActiveConfig(); UpdateActiveConfig();
OSD::AddMessage(StringFromFormat("Supports Blending: %s UBOs: %s PinnedMem: %s", OSD::AddMessage(StringFromFormat("Supports Blending: %s UBOs: %s PinnedMem: %s Cache: %s",
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "True" : "False", g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "True" : "False",
g_ActiveConfig.backend_info.bSupportsGLSLUBO ? "True" : "False", g_ActiveConfig.backend_info.bSupportsGLSLUBO ? "True" : "False",
g_ActiveConfig.backend_info.bSupportsGLPinnedMemory ? "True" : "False").c_str(), 5000); g_ActiveConfig.backend_info.bSupportsGLPinnedMemory ? "True" : "False",
g_ActiveConfig.backend_info.bSupportsGLSLCache ? "True" : "False").c_str(), 5000);
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode); s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);