summaryrefslogtreecommitdiff
path: root/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2013-03-29 14:54:44 +0100
committerNeoBrainX <NeoBrainX@gmail.com>2013-03-29 14:56:01 +0100
commit41c4108ce66d73b81c254165f18a23f72aabf09a (patch)
tree12800f7b3af88674c88c66a75fbcef38a5076c8a /Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
parentf2a8fbb314aabb986e9f5711278272649a78b098 (diff)
OpenGL: Reimplement shader uid debugging.
Diffstat (limited to 'Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp')
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp64
1 files changed, 62 insertions, 2 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
index 53b0210919..6ce4e1e04c 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp
@@ -23,6 +23,9 @@
#include "ImageWrite.h"
#include "Render.h"
+#include <algorithm>
+#include <type_traits>
+
namespace OGL
{
@@ -353,14 +356,71 @@ GLuint ProgramShaderCache::CompileSingleShader (GLuint type, const char* code )
return result;
}
+template<class UidT> UidT GetPartialUid(const SHADERUID& uid);
+template<> PixelShaderUid GetPartialUid(const SHADERUID& uid) { return uid.puid; }
+template<> VertexShaderUid GetPartialUid(const SHADERUID& uid) { return uid.vuid; }
+
+template<class CodeT> const std::string& GetShaderCode(const SHADER& shader);
+template<> const std::string& GetShaderCode<PixelShaderCode>(const SHADER& shader) { return shader.strpprog; }
+template<> const std::string& GetShaderCode<VertexShaderCode>(const SHADER& shader) { return shader.strvprog; }
+
+template<class UidT, class CodeT>
+void CheckForUidMismatch(const ProgramShaderCache::PCache& cache, CodeT& new_code, const UidT& new_uid)
+{
+ static std::map<UidT,std::string> s_shaders;
+ static std::vector<UidT> s_uids;
+
+ bool uid_is_indexed = std::find(s_uids.begin(), s_uids.end(), new_uid) != s_uids.end();
+ if (!uid_is_indexed)
+ {
+ s_uids.push_back(new_uid);
+ s_shaders[new_uid] = new_code.GetBuffer();
+ }
+ else
+ {
+ // uid is already in the index => check if there's a shader with the same uid but different code
+ auto& old_code = s_shaders[new_uid];
+ if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0)
+ {
+ static int num_failures = 0;
+
+ char szTemp[MAX_PATH];
+ sprintf(szTemp, "%s%ssuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(),
+ std::is_same<UidT,PixelShaderUid>::value ? "p" : std::is_same<UidT,VertexShaderUid>::value ? "v" : "o",
+ ++num_failures);
+
+ // TODO: Should also dump uids
+ std::ofstream file;
+ OpenFStream(file, szTemp, std::ios_base::out);
+ file << "Old shader code:\n" << old_code;
+ file << "\n\nNew shader code:\n" << new_code.GetBuffer();
+ file.close();
+
+ // TODO: Make this more idiot-proof
+ ERROR_LOG(VIDEO, "%s shader uid mismatch!",
+ std::is_same<UidT,PixelShaderUid>::value ? "Pixel" : std::is_same<UidT,VertexShaderUid>::value ? "Vertex" : "Other");
+ }
+ }
+}
-void ProgramShaderCache::GetShaderId ( SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components )
+void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components)
{
GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components);
GetVertexShaderUid(uid->vuid, components, API_OPENGL);
-}
+ if (g_ActiveConfig.bEnableShaderDebugging)
+ {
+ PixelShaderCode pcode;
+ VertexShaderCode vcode;
+
+ GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components);
+ GenerateVertexShaderCode(vcode, components, API_OPENGL);
+
+ CheckForUidMismatch<PixelShaderUid,PixelShaderCode>(pshaders, pcode, uid->puid);
+ CheckForUidMismatch<VertexShaderUid,VertexShaderCode>(pshaders, vcode, uid->vuid);
+ }
+}
ProgramShaderCache::PCacheEntry ProgramShaderCache::GetShaderProgram(void)