From 55eb8ce87361e968b153a3e728e6842e3069d093 Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Tue, 9 Aug 2016 01:29:58 -0400 Subject: OpenGL: enhance debug output When running blender --debug-gpu Display which debug facilities are available. One of these, in order of preference: - OpenGL 4.3 - KHR_debug - ARB_debug_output - AMD_debug_output All messages are logged now, not just errors. Will probably turn some of these off later. GL_DEBUG_OUTPUT_SYNCHRONOUS lets us break on errors and backtrace to the exact trouble spot. Callers of GPU_string_marker no longer pass in a message length, just the message itself (null terminated). Apple provides no GL debug logging features. --- source/blender/gpu/GPU_debug.h | 2 +- source/blender/gpu/intern/gpu_debug.c | 101 ++++++++++++++++++++++++++-------- 2 files changed, 79 insertions(+), 24 deletions(-) (limited to 'source') diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h index 2c1728bfff1..ec0db43c38c 100644 --- a/source/blender/gpu/GPU_debug.h +++ b/source/blender/gpu/GPU_debug.h @@ -62,7 +62,7 @@ void GPU_assert_no_gl_errors(const char *file, int line, const char *str); /* inserts a debug marker message for the debug context messaging system */ -void GPU_string_marker(size_t size, const char *str); +void GPU_string_marker(const char *str); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.c index be9285727fe..555af8b087a 100644 --- a/source/blender/gpu/intern/gpu_debug.c +++ b/source/blender/gpu/intern/gpu_debug.c @@ -159,29 +159,78 @@ const char *gpuErrorString(GLenum err) #endif +static const char* source_name(GLenum source) +{ + switch (source) { + case GL_DEBUG_SOURCE_API: return "API"; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "window system"; + case GL_DEBUG_SOURCE_SHADER_COMPILER: return "shader compiler"; + case GL_DEBUG_SOURCE_THIRD_PARTY: return "3rd party"; + case GL_DEBUG_SOURCE_APPLICATION: return "application"; + case GL_DEBUG_SOURCE_OTHER: return "other"; + default: return "???"; + } +} + +static const char* message_type_name(GLenum message) +{ + switch (message) { + case GL_DEBUG_TYPE_ERROR: return "error"; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "deprecated behavior"; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "undefined behavior"; + case GL_DEBUG_TYPE_PORTABILITY: return "portability"; + case GL_DEBUG_TYPE_PERFORMANCE: return "performance"; + case GL_DEBUG_TYPE_OTHER: return "other"; + case GL_DEBUG_TYPE_MARKER: return "marker"; /* KHR has this, ARB does not */ + default: return "???"; + } +} + +static const char* category_name_amd(GLenum category) +{ + switch (category) { + case GL_DEBUG_CATEGORY_API_ERROR_AMD: return "API error"; + case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: return "window system"; + case GL_DEBUG_CATEGORY_DEPRECATION_AMD: return "deprecated behavior"; + case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: return "undefined behavior"; + case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: return "performance"; + case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: return "shader compiler"; + case GL_DEBUG_CATEGORY_APPLICATION_AMD: return "application"; + case GL_DEBUG_CATEGORY_OTHER_AMD: return "other"; + default: return "???"; + } +} + + static void APIENTRY gpu_debug_proc( GLenum source, GLenum type, GLuint UNUSED(id), - GLenum UNUSED(severity), GLsizei UNUSED(length), + GLenum severity, GLsizei UNUSED(length), const GLchar *message, const GLvoid *UNUSED(userParm)) { - if (source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) { - fprintf(stderr, "GL: %s\n", message); - fflush(stderr); - } - else if (G.debug_value == 20) { - fprintf(stderr, "GL: %s\n", message); - fflush(stderr); + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: + case GL_DEBUG_SEVERITY_MEDIUM: + case GL_DEBUG_SEVERITY_LOW: + case GL_DEBUG_SEVERITY_NOTIFICATION: /* KHR has this, ARB does not */ + fprintf(stderr, "GL %s %s: %s\n", source_name(source), message_type_name(type), message); + fflush(stderr); } } #ifndef GLEW_ES_ONLY static void APIENTRY gpu_debug_proc_amd( - GLuint UNUSED(id), GLenum UNUSED(category), - GLenum UNUSED(severity), GLsizei UNUSED(length), + GLuint UNUSED(id), GLenum category, + GLenum severity, GLsizei UNUSED(length), const GLchar *message, GLvoid *UNUSED(userParm)) { - fprintf(stderr, "GL: %s\n", message); + switch (severity) { + case GL_DEBUG_SEVERITY_HIGH: + case GL_DEBUG_SEVERITY_MEDIUM: + case GL_DEBUG_SEVERITY_LOW: + fprintf(stderr, "GL %s: %s\n", category_name_amd(category), message); + fflush(stderr); + } } #endif @@ -194,36 +243,44 @@ void gpu_debug_init(void) #if !defined(WITH_GLEW_ES) && !defined(GLEW_ES_ONLY) if (GLEW_VERSION_4_3) { + fprintf(stderr, "Using OpenGL 4.3 debug facilities\n"); glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback((GLDEBUGPROC)gpu_debug_proc, mxGetCurrentContext()); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); - GPU_string_marker(sizeof(success), success); + GPU_string_marker(success); return; } #endif if (GLEW_KHR_debug) { #ifndef GLEW_ES_ONLY + fprintf(stderr, "Using KHR_debug extension\n"); + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback((GLDEBUGPROC)gpu_debug_proc, mxGetCurrentContext()); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); - GPU_string_marker(sizeof(success), success); + GPU_string_marker(success); #endif return; } #ifndef GLEW_ES_ONLY if (GLEW_ARB_debug_output) { + fprintf(stderr, "Using ARB_debug_output extension\n"); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallbackARB((GLDEBUGPROCARB)gpu_debug_proc, mxGetCurrentContext()); glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); - GPU_string_marker(sizeof(success), success); + GPU_string_marker(success); return; } if (GLEW_AMD_debug_output) { + fprintf(stderr, "Using AMD_debug_output extension\n"); glDebugMessageCallbackAMD(gpu_debug_proc_amd, mxGetCurrentContext()); glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); - GPU_string_marker(sizeof(success), success); + GPU_string_marker(success); return; } @@ -271,14 +328,14 @@ void gpu_debug_exit(void) return; } -void GPU_string_marker(size_t length, const char *buf) +void GPU_string_marker(const char *buf) { #ifndef WITH_GLEW_ES #ifndef GLEW_ES_ONLY if (GLEW_VERSION_4_3) { glDebugMessageInsert( GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, - GL_DEBUG_SEVERITY_NOTIFICATION, length, buf); + GL_DEBUG_SEVERITY_NOTIFICATION, -1, buf); return; } @@ -289,7 +346,7 @@ void GPU_string_marker(size_t length, const char *buf) #ifndef GLEW_ES_ONLY glDebugMessageInsert( GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, - GL_DEBUG_SEVERITY_NOTIFICATION, length, buf); + GL_DEBUG_SEVERITY_NOTIFICATION, -1, buf); #endif return; } @@ -298,7 +355,7 @@ void GPU_string_marker(size_t length, const char *buf) if (GLEW_ARB_debug_output) { glDebugMessageInsertARB( GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, - GL_DEBUG_SEVERITY_LOW_ARB, length, buf); + GL_DEBUG_SEVERITY_LOW_ARB, -1, buf); return; } @@ -306,19 +363,17 @@ void GPU_string_marker(size_t length, const char *buf) if (GLEW_AMD_debug_output) { glDebugMessageInsertAMD( GL_DEBUG_CATEGORY_APPLICATION_AMD, GL_DEBUG_SEVERITY_LOW_AMD, 0, - length, buf); + 0, buf); return; } if (GLEW_GREMEDY_string_marker) { - glStringMarkerGREMEDY(length, buf); + glStringMarkerGREMEDY(0, buf); return; } #endif - - return; } void GPU_print_error_debug(const char *str) -- cgit v1.2.3