Skip to content

Instantly share code, notes, and snippets.

@PixelClear
Created February 15, 2017 12:09
Show Gist options
  • Save PixelClear/5f4427af03fadefe7badf486facff2cf to your computer and use it in GitHub Desktop.
Save PixelClear/5f4427af03fadefe7badf486facff2cf to your computer and use it in GitHub Desktop.
#include<dbghelp.h>
#include<direct.h>
#include <GL/gl.h>
#include<stdio.h>
void getStackTrace(char *funcName,int *lineNumber)
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
char name[256];
char fname[256];
IMAGEHLP_LINE64 line;
DWORD64 displace_local;
DWORD64 displace;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
strcpy(name,__FUNCTION__);
//To get Address and stack trace of user function which called gl c
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ),&displace, symbol );
//this is to skip current function driver function and dll function calls in between
if(strcmp( symbol->Name,name)!=0
&& strstr(symbol->Name , "Drv")==NULL
&& strstr(symbol->Name , "Dll")==NULL
&& strstr(symbol->Name , "__tmainCRTStartup")==NULL
&& strstr(symbol->Name , "MainThread_do_task")==NULL
&& strstr(symbol->Name , "_ui_krn_process_command")==NULL
&& strstr(symbol->Name , "_uicmd_cmd_execute")==NULL
&& strstr(symbol->Name , "openglCallbackFunction")==NULL
&& ((strstr(symbol->Name , "Pgl")!=NULL)
||
(strstr(symbol->Name , "pgl")!=NULL)
||
(strstr(symbol->Name , "iPgl")!=NULL)
||
(strstr(symbol->Name , "ipgl")!=NULL)))
{
if (SymGetLineFromAddr64(process,
symbol->Address+displace,
&displace_local,
&line))
{
*lineNumber=line.LineNumber;
strcpy(funcName,symbol->Name);
break;
}
}
}
free( symbol );
}
void writeLog(int lineno,char*funcName,char* message)
{
fprintf(stderr,"%d : %s : %s \n",lineno,funcName,message);
}
void APIENTRY openglCallbackFunction(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar* message,void* userParam)
{
char sourceString[256];
char typeString[256];
char severityString[256];
char funcName[256];
int lineno;
switch (source) {
case GL_DEBUG_SOURCE_API_ARB: {
*sourceString = "Source : API";
break;
}
case GL_DEBUG_SOURCE_APPLICATION_ARB: {
*sourceString = "Source : Application";
break;
}
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: {
*sourceString = "Source : Window System";
break;
}
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: {
*sourceString = "Source : Shader Compiler";
break;
}
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: {
*sourceString = "Source : Third Party";
break;
}
case GL_DEBUG_SOURCE_OTHER_ARB: {
*sourceString = "Source : Other";
break;
}
default: {
*sourceString = "Source : Unknown";
break;
}
}
switch (type) {
case GL_DEBUG_TYPE_ERROR_ARB: {
*typeString = "Type : Error";
break;
}
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: {
*typeString = "Type : Deprecated Behavior";
break;
}
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: {
*typeString = "Type : Undefined Behavior";
break;
}
case GL_DEBUG_TYPE_PERFORMANCE_ARB: {
*typeString = "Type : Performance";
break;
}
case GL_DEBUG_TYPE_PORTABILITY_ARB: {
*typeString = "Type : Portability Issue";
break;
}
case GL_DEBUG_TYPE_MARKER_ARB: {
*typeString = "Type : Maker Issue";
}
case GL_DEBUG_TYPE_OTHER_ARB: {
*typeString = "Type : Other";
break;
}
default: {
*typeString = "Type : Unknown";
break;
}
}
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH_ARB: {
*severityString = "Severity : High";
break;
}
case GL_DEBUG_SEVERITY_MEDIUM_ARB: {
*severityString = "Severity : Medium";
break;
}
case GL_DEBUG_SEVERITY_LOW_ARB: {
*severityString = "Severity : Low";
break;
}
default: {
*severityString = "Severity : Unknown";
break;
}
}
getStackTrace(&funcName,&lineno);
writeLog(lineno,funcName,message);
}
int ipglOpenglStartDebugging()
{
GLuint unusedIds = 0;
int NumberOfExtensions;
int i=0;
int iExtSupported=0;
//Function Pointer To register callback
void (*glDebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
//Function Pointer to setup Debug Context
void (*glDebugMessageControlARB)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, int enabled);
const GLubyte* (*glGetStringi)(GLenum, GLuint);
glGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi");
if(glGetStringi)
return -1;
glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
for(i=0; i<NumberOfExtensions; i++)
{
const GLubyte *ccc=glGetStringi(GL_EXTENSIONS, i);
if ( strcmp(ccc, (const GLubyte *)"GL_ARB_debug_output") == 0 )
{
//Enable Debug Context
glEnable(GL_DEBUG_OUTPUT_ARB);
//Enabled so that Driver synchronously calls callback
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) wglGetProcAddress("glDebugMessageCallbackARB");
if(glDebugMessageCallbackARB)
return -1;
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) wglGetProcAddress("glDebugMessageControlARB");
if(glDebugMessageControlARB)
return -1;
iExtSupported=1;
}
}
if(iExtSupported==0)
{
fprintf(stderr,"\nDEBUG ERROR : GL_ARB_debug_output is not supported by your card.\n");
glDisable(GL_DEBUG_OUTPUT_ARB);
glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
return -1;
}
//Register Callback
glDebugMessageCallbackARB(openglCallbackFunction, NULL);
glDebugMessageControlARB(GL_DONT_CARE,
GL_DONT_CARE,
GL_DONT_CARE,
0,
&unusedIds,
1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment