gsdx-ogl: rework callback debug

* use DebugOutputToFile as a callback of gl error. Add a breakpoint to
  find the culprit GL call
* use string instead of char[n]

Note: CheckDebugLog is potentially useless now
This commit is contained in:
Gregory Hainaut 2014-09-27 18:57:17 +02:00
parent b7601a9add
commit 1e86e3cb08
5 changed files with 44 additions and 34 deletions

View File

@ -62,6 +62,7 @@ PFNGLGENSAMPLERSPROC gl_GenSamplers = NU
PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays = NULL; PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays = NULL;
PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv = NULL; PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv = NULL;
PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB = NULL; PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB = NULL;
PFNGLDEBUGMESSAGECALLBACKPROC gl_DebugMessageCallback = NULL;
PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog = NULL; PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog = NULL;
PFNGLGETPROGRAMIVPROC gl_GetProgramiv = NULL; PFNGLGETPROGRAMIVPROC gl_GetProgramiv = NULL;
PFNGLGETSHADERIVPROC gl_GetShaderiv = NULL; PFNGLGETSHADERIVPROC gl_GetShaderiv = NULL;

View File

@ -246,6 +246,7 @@ extern PFNGLGENSAMPLERSPROC gl_GenSamplers;
extern PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays; extern PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays;
extern PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv; extern PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv;
extern PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB; extern PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB;
extern PFNGLDEBUGMESSAGECALLBACKPROC gl_DebugMessageCallback;
extern PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog; extern PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog;
extern PFNGLGETPROGRAMIVPROC gl_GetProgramiv; extern PFNGLGETPROGRAMIVPROC gl_GetProgramiv;
extern PFNGLGETSHADERIVPROC gl_GetShaderiv; extern PFNGLGETSHADERIVPROC gl_GetShaderiv;

View File

@ -168,10 +168,18 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_window = wnd; m_window = wnd;
// ****************************************************************
// Debug helper
// ****************************************************************
#ifdef ENABLE_OGL_DEBUG
gl_DebugMessageCallback(DebugOutputToFile, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
#endif
// **************************************************************** // ****************************************************************
// Various object // Various object
// **************************************************************** // ****************************************************************
m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_ogl_shader", 1)); m_shader = new GSShaderOGL(!!theApp.GetConfig("debug_glsl_shader", 0));
gl_GenFramebuffers(1, &m_fbo); gl_GenFramebuffers(1, &m_fbo);
gl_GenFramebuffers(1, &m_fbo_read); gl_GenFramebuffers(1, &m_fbo_read);
@ -1218,8 +1226,7 @@ void GSDeviceOGL::CheckDebugLog()
unsigned int pos = 0; unsigned int pos = 0;
for(unsigned int i=0; i<retVal; i++) for(unsigned int i=0; i<retVal; i++)
{ {
DebugOutputToFile(sources[i], types[i], ids[i], severities[i], DebugOutputToFile(sources[i], types[i], ids[i], severities[i], lengths[i], &messageLog[pos], NULL);
&messageLog[pos]);
pos += lengths[i]; pos += lengths[i];
} }
} }
@ -1228,49 +1235,49 @@ void GSDeviceOGL::CheckDebugLog()
#endif #endif
} }
void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message) // Note: used as a callback of DebugMessageCallback. Don't change the signature
void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, GLenum gl_severity, GLsizei gl_length, const GLchar *gl_message, const void* userParam)
{ {
#ifndef ENABLE_GLES #ifndef ENABLE_GLES
char debType[20], debSev[6]; std::string message(gl_message, gl_length);
std::string type, severity, source;
static int sev_counter = 0; static int sev_counter = 0;
switch(gl_type) {
if(type == GL_DEBUG_TYPE_ERROR_ARB) case GL_DEBUG_TYPE_ERROR_ARB : type = "Error"; break;
strcpy(debType, "Error"); case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB : type = "Deprecated bhv"; break;
else if(type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB) case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB : type = "Undefined bhv"; break;
strcpy(debType, "Deprecated behavior"); case GL_DEBUG_TYPE_PORTABILITY_ARB : type = "Portability"; break;
else if(type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB) case GL_DEBUG_TYPE_PERFORMANCE_ARB : type = "Perf"; break;
strcpy(debType, "Undefined behavior"); case GL_DEBUG_TYPE_OTHER_ARB : type = "Others"; break;
else if(type == GL_DEBUG_TYPE_PORTABILITY_ARB) default : type = "TTT"; break;
strcpy(debType, "Portability"); }
else if(type == GL_DEBUG_TYPE_PERFORMANCE_ARB) switch(gl_severity) {
strcpy(debType, "Performance"); case GL_DEBUG_SEVERITY_HIGH_ARB : severity = "High"; sev_counter++; break;
else if(type == GL_DEBUG_TYPE_OTHER_ARB) case GL_DEBUG_SEVERITY_MEDIUM_ARB : severity = "Mid"; break;
strcpy(debType, "Other"); case GL_DEBUG_SEVERITY_LOW_ARB : severity = "Low"; break;
else default : severity = "Info"; break;
strcpy(debType, "UNKNOWN"); }
switch(gl_source) {
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) { case GL_DEBUG_SOURCE_API_ARB : source = "API"; break;
strcpy(debSev, "High"); case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB : source = "WINDOW"; break;
sev_counter++; case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB : source = "COMPILER"; break;
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB : source = "3rdparty"; break;
case GL_DEBUG_SOURCE_APPLICATION_ARB : source = "Application"; break;
case GL_DEBUG_SOURCE_OTHER_ARB : source = "Others"; break;
default : source = "???"; break;
} }
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
strcpy(debSev, "Med");
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
strcpy(debSev, "Low");
else
strcpy(debSev, "None");
#ifdef LOUD_DEBUGGING #ifdef LOUD_DEBUGGING
fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message); fprintf(stderr,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", type.c_str(), g_draw_count, severity.c_str(), message.c_str());
#endif #endif
FILE* f = fopen("Debug.txt","a"); FILE* f = fopen("Debug.txt","a");
if(f) if(f)
{ {
fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debType, g_draw_count, debSev,message); fprintf(f,"Type:%s\tID:%d\tSeverity:%s\tMessage:%s\n", type.c_str(), g_draw_count, severity.c_str(), message.c_str());
fclose(f); fclose(f);
} }
ASSERT(sev_counter < 3); ASSERT(sev_counter < 5);
#endif #endif
} }

View File

@ -559,7 +559,7 @@ class GSDeviceOGL : public GSDevice
virtual ~GSDeviceOGL(); virtual ~GSDeviceOGL();
static void CheckDebugLog(); static void CheckDebugLog();
static void DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message); static void DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, GLenum gl_severity, GLsizei gl_length, const GLchar *gl_message, const void* userParam);
bool HasStencil() { return true; } bool HasStencil() { return true; }
bool HasDepth32() { return true; } bool HasDepth32() { return true; }

View File

@ -59,6 +59,7 @@ void GSWndGL::PopulateGlFunction()
*(void**)&(gl_GenVertexArrays) = GetProcAddress("glGenVertexArrays"); *(void**)&(gl_GenVertexArrays) = GetProcAddress("glGenVertexArrays");
*(void**)&(gl_GetBufferParameteriv) = GetProcAddress("glGetBufferParameteriv"); *(void**)&(gl_GetBufferParameteriv) = GetProcAddress("glGetBufferParameteriv");
*(void**)&(gl_GetDebugMessageLogARB) = GetProcAddress("glGetDebugMessageLogARB"); *(void**)&(gl_GetDebugMessageLogARB) = GetProcAddress("glGetDebugMessageLogARB");
*(void**)&(gl_DebugMessageCallback) = GetProcAddress("glDebugMessageCallback");
*(void**)&(gl_GetProgramInfoLog) = GetProcAddress("glGetProgramInfoLog"); *(void**)&(gl_GetProgramInfoLog) = GetProcAddress("glGetProgramInfoLog");
*(void**)&(gl_GetProgramiv) = GetProcAddress("glGetProgramiv"); *(void**)&(gl_GetProgramiv) = GetProcAddress("glGetProgramiv");
*(void**)&(gl_GetShaderiv) = GetProcAddress("glGetShaderiv"); *(void**)&(gl_GetShaderiv) = GetProcAddress("glGetShaderiv");