summaryrefslogtreecommitdiff
path: root/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2013-06-17 13:27:22 +0200
committerNeoBrainX <NeoBrainX@gmail.com>2013-06-17 13:27:22 +0200
commit88bc8255b8cc2287fa92134a3dd948801b3a107d (patch)
tree21cd00c5354439673958e9ee5fdc9797984bff93 /Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
parent868c627876a202e1675c62ad23f9642e05d9af69 (diff)
parent88163691443af7032b55e83ad78fe946f124b25f (diff)
Merge branch 'shader-uids-awesome'.
Replaces the old, hardcoded shader ID generator with a semi-automatic mechanism that generates IDs from hints in the code generator. Also introduces a flexible framework to do all kinds of funky stuff with the shader code generation logic. As an example, a uniform usage profile generation class is added (unused for now, though). Functionality can still be tested by setting the EnableShaderDebugging field in the gfx config to True. Any two shaders which are identified with the same ID will be written to a file and an error message will be written to the Dolphin log.
Diffstat (limited to 'Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp')
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp67
1 files changed, 33 insertions, 34 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
index 90cf401687..07ba589469 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
@@ -31,6 +31,8 @@ static GLuint CurrentProgram = 0;
ProgramShaderCache::PCache ProgramShaderCache::pshaders;
ProgramShaderCache::PCacheEntry* ProgramShaderCache::last_entry;
SHADERUID ProgramShaderCache::last_uid;
+UidChecker<PixelShaderUid,PixelShaderCode> ProgramShaderCache::pixel_uid_checker;
+UidChecker<VertexShaderUid,VertexShaderCode> ProgramShaderCache::vertex_uid_checker;
static char s_glsl_header[1024] = "";
@@ -186,21 +188,20 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen
{
SHADERUID uid;
GetShaderId(&uid, dstAlphaMode, components);
-
+
// Check if the shader is already set
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- ValidateShaderIDs(last_entry, dstAlphaMode, components);
last_entry->shader.Bind();
return &last_entry->shader;
}
}
-
+
last_uid = uid;
-
+
// Check if shader is already in cache
PCache::iterator iter = pshaders.find(uid);
if (iter != pshaders.end())
@@ -209,24 +210,24 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen
last_entry = entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- ValidateShaderIDs(entry, dstAlphaMode, components);
last_entry->shader.Bind();
return &last_entry->shader;
}
-
+
// Make an entry in the table
PCacheEntry& newentry = pshaders[uid];
last_entry = &newentry;
newentry.in_cache = 0;
-
- const char *vcode = GenerateVertexShaderCode(components, API_OPENGL);
- const char *pcode = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
-
+
+ VertexShaderCode vcode;
+ PixelShaderCode pcode;
+ GenerateVertexShaderCode(vcode, components, API_OPENGL);
+ GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components);
+
if (g_ActiveConfig.bEnableShaderDebugging)
{
- GetSafeShaderId(&newentry.safe_uid, dstAlphaMode, components);
- newentry.shader.strvprog = vcode;
- newentry.shader.strpprog = pcode;
+ newentry.shader.strvprog = vcode.GetBuffer();
+ newentry.shader.strpprog = pcode.GetBuffer();
}
#if defined(_DEBUG) || defined(DEBUGFAST)
@@ -234,13 +235,13 @@ SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 componen
static int counter = 0;
char szTemp[MAX_PATH];
sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
- SaveData(szTemp, vcode);
+ SaveData(szTemp, vcode.GetBuffer());
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
- SaveData(szTemp, pcode);
+ SaveData(szTemp, pcode.GetBuffer());
}
#endif
- if (!CompileShader(newentry.shader, vcode, pcode)) {
+ if (!CompileShader(newentry.shader, vcode.GetBuffer(), pcode.GetBuffer())) {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return NULL;
}
@@ -257,7 +258,7 @@ bool ProgramShaderCache::CompileShader ( SHADER& shader, const char* vcode, cons
{
GLuint vsid = CompileSingleShader(GL_VERTEX_SHADER, vcode);
GLuint psid = CompileSingleShader(GL_FRAGMENT_SHADER, pcode);
-
+
if(!vsid || !psid)
{
glDeleteShader(vsid);
@@ -380,28 +381,23 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code )
return result;
}
-
-
-void ProgramShaderCache::GetShaderId ( SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components )
+void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components)
{
- GetPixelShaderId(&uid->puid, dstAlphaMode, components);
- GetVertexShaderId(&uid->vuid, components);
-}
+ GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components);
+ GetVertexShaderUid(uid->vuid, components, API_OPENGL);
-void ProgramShaderCache::GetSafeShaderId ( SHADERUIDSAFE* uid, DSTALPHA_MODE dstAlphaMode, u32 components )
-{
- GetSafePixelShaderId(&uid->puid, dstAlphaMode, components);
- GetSafeVertexShaderId(&uid->vuid, components);
-}
+ if (g_ActiveConfig.bEnableShaderDebugging)
+ {
+ PixelShaderCode pcode;
+ GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components);
+ pixel_uid_checker.AddToIndexAndCheck(pcode, uid->puid, "Pixel", "p");
-void ProgramShaderCache::ValidateShaderIDs ( PCacheEntry *entry, DSTALPHA_MODE dstAlphaMode, u32 components )
-{
- ValidateVertexShaderIDs(API_OPENGL, entry->safe_uid.vuid, entry->shader.strvprog, components);
- ValidatePixelShaderIDs(API_OPENGL, entry->safe_uid.puid, entry->shader.strpprog, dstAlphaMode, components);
+ VertexShaderCode vcode;
+ GenerateVertexShaderCode(vcode, components, API_OPENGL);
+ vertex_uid_checker.AddToIndexAndCheck(vcode, uid->vuid, "Vertex", "v");
+ }
}
-
-
ProgramShaderCache::PCacheEntry ProgramShaderCache::GetShaderProgram(void)
{
return *last_entry;
@@ -497,6 +493,9 @@ void ProgramShaderCache::Shutdown(void)
iter->second.Destroy();
pshaders.clear();
+ pixel_uid_checker.Invalidate();
+ vertex_uid_checker.Invalidate();
+
if (g_ActiveConfig.backend_info.bSupportsGLSLUBO)
{
delete s_buffer;