commit e849bfea91b8068998880e7b9fddd4fe95ab47a8
parent 8e2826b1d978341ddec1b4431ba2027e92a2353b
Author: Brian Swetland <swetland@frotz.net>
Date: Thu, 29 Aug 2013 16:38:56 -0700
common: use GL debug extension to report errors via callback
Install debug callback if extension is present.
Get rid of the clunky CHECK() macro and calls to glError()
Diffstat:
2 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/common/buffers.cc b/common/buffers.cc
@@ -19,31 +19,6 @@
#include "app.h"
#include "util.h"
-#if 1
-#define CHECK() do {} while (0)
-#else
-const char *__gl_error_string(unsigned e) {
- static char buf[16];
- switch (e) {
- case GL_INVALID_ENUM: return "INVALID ENUM";
- case GL_INVALID_VALUE: return "INVALID VALUE";
- case GL_INVALID_OPERATION: return "INVALID OPERATION";
- case GL_INVALID_FRAMEBUFFER_OPERATION: return "INVALID FRAMEBUFFER OPERATION";
- case GL_OUT_OF_MEMORY: return "OUT OF MEMORY";
- default:
- sprintf(buf,"0x%08x", e);
- return buf;
- }
-}
-
-void __check_gl_error(const char *fn, int line) {
- unsigned e;
- while ((e = glGetError()) != GL_NO_ERROR)
- printx("%s:%d: GL ERROR %s\n", fn, line, __gl_error_string(e));
-}
-#define CHECK() __check_gl_error(__func__, __LINE__)
-#endif
-
static unsigned vattr_type(unsigned type) {
switch (type) {
case SRC_INT8: return GL_BYTE;
@@ -62,39 +37,31 @@ static unsigned vattr_type(unsigned type) {
void VertexAttributes::init(VertexAttrDesc *desc, VertexBuffer **data, unsigned count) {
unsigned id = 0, n;
glGenVertexArrays(1, &vao);
- CHECK();
glBindVertexArray(vao);
- CHECK();
for (n = 0; n < count; n++) {
if (data && (data[n]->id != id)) {
id = data[n]->id;
glBindBuffer(GL_ARRAY_BUFFER, id);
- CHECK();
}
switch (desc->dst_type) {
case DST_FLOAT:
glVertexAttribPointer(desc->index, desc->count,
vattr_type(desc->src_type), GL_FALSE, desc->stride,
OFF2PTR(desc->offset));
- CHECK();
break;
case DST_NORMALIZED:
glVertexAttribPointer(desc->index, desc->count,
vattr_type(desc->src_type), GL_TRUE, desc->stride,
OFF2PTR(desc->offset));
- CHECK();
break;
case DST_INTEGER:
glVertexAttribIPointer(desc->index, desc->count,
vattr_type(desc->src_type), desc->stride,
OFF2PTR(desc->offset));
- CHECK();
break;
}
glVertexAttribDivisor(desc->index, desc->divisor);
- CHECK();
glEnableVertexAttribArray(desc->index);
- CHECK();
desc++;
}
}
diff --git a/common/glapp.cc b/common/glapp.cc
@@ -91,6 +91,46 @@ void App::setOptions(int argc, char **argv) {
}
#endif
+static const char *dbg_source(GLenum n) {
+ switch (n) {
+ case GL_DEBUG_SOURCE_API_ARB: return "api";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "compiler";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "winsys";
+ case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "3rdpty";
+ case GL_DEBUG_SOURCE_APPLICATION_ARB: return "app";
+ case GL_DEBUG_SOURCE_OTHER_ARB: return "other";
+ default: return "unknown";
+ }
+}
+static const char *dbg_type(GLenum n) {
+ switch (n) {
+ case GL_DEBUG_TYPE_ERROR_ARB: return "error";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "undef";
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "perf";
+ case GL_DEBUG_TYPE_PORTABILITY_ARB: return "portability";
+ case GL_DEBUG_TYPE_OTHER_ARB: return "other";
+ default: return "unknown";
+ }
+}
+static const char *dbg_severity(GLenum n) {
+ switch (n) {
+ case GL_DEBUG_SEVERITY_HIGH_ARB: return "high";
+ case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "medium";
+ case GL_DEBUG_SEVERITY_LOW_ARB: return "low";
+ default: return "unknown";
+ }
+}
+static void dbg_error_callback(GLenum source, GLenum type, GLenum id, GLenum severity,
+ GLsizei length, const char *message, void *cookie) {
+#if VERBOSE
+ error("%s: %s: %x: %s: %s",
+ dbg_source(source), dbg_type(type), id,
+ dbg_severity(severity), message);
+#else
+ error("GL: %s", message);
+#endif
+}
+
int App::start(void) {
memset(keystate, 0, sizeof(keystate));
@@ -133,6 +173,19 @@ int App::start(void) {
/* todo: verify extension availability */
}
+ { // TODO: filter or disable in release mode
+ PFNGLDEBUGMESSAGECALLBACKPROC fn;
+ fn = (PFNGLDEBUGMESSAGECALLBACKPROC)
+ SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
+ if (fn) {
+ fn(dbg_error_callback, NULL);
+ glEnable(GL_DEBUG_OUTPUT);
+ // glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ } else {
+ fprintf(stderr,"warning: no glDebugMessageCallbackARB()\n");
+ }
+ }
+
SDL_GL_SetSwapInterval(_vsync);
gl_map_functions();