1.1 --- a/include/SDL_test_common.h Sat May 18 23:32:53 2013 -0700
1.2 +++ b/include/SDL_test_common.h Sun May 19 22:28:10 2013 -0700
1.3 @@ -104,6 +104,7 @@
1.4 int gl_accelerated;
1.5 int gl_major_version;
1.6 int gl_minor_version;
1.7 + int gl_debug;
1.8 } SDLTest_CommonState;
1.9
1.10 #include "begin_code.h"
2.1 --- a/src/render/opengl/SDL_glfuncs.h Sat May 18 23:32:53 2013 -0700
2.2 +++ b/src/render/opengl/SDL_glfuncs.h Sun May 19 22:28:10 2013 -0700
2.3 @@ -152,7 +152,7 @@
2.4 SDL_PROC_UNUSED(void, glGetPixelMapfv, (GLenum map, GLfloat * values))
2.5 SDL_PROC_UNUSED(void, glGetPixelMapuiv, (GLenum map, GLuint * values))
2.6 SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort * values))
2.7 -SDL_PROC_UNUSED(void, glGetPointerv, (GLenum pname, GLvoid * *params))
2.8 +SDL_PROC(void, glGetPointerv, (GLenum pname, GLvoid * *params))
2.9 SDL_PROC_UNUSED(void, glGetPolygonStipple, (GLubyte * mask))
2.10 SDL_PROC(const GLubyte *, glGetString, (GLenum name))
2.11 SDL_PROC_UNUSED(void, glGetTexEnvfv,
3.1 --- a/src/render/opengl/SDL_render_gl.c Sat May 18 23:32:53 2013 -0700
3.2 +++ b/src/render/opengl/SDL_render_gl.c Sun May 19 22:28:10 2013 -0700
3.3 @@ -100,6 +100,13 @@
3.4 typedef struct
3.5 {
3.6 SDL_GLContext context;
3.7 +
3.8 + SDL_bool GL_ARB_debug_output_supported;
3.9 + int errors;
3.10 + char **error_messages;
3.11 + GLDEBUGPROCARB next_error_callback;
3.12 + GLvoid *next_error_userparam;
3.13 +
3.14 SDL_bool GL_ARB_texture_rectangle_supported;
3.15 struct {
3.16 GL_Shader shader;
3.17 @@ -151,7 +158,7 @@
3.18 GL_FBOList *fbo;
3.19 } GL_TextureData;
3.20
3.21 -static __inline__ const char*
3.22 +SDL_FORCE_INLINE const char*
3.23 GL_TranslateError (GLenum error)
3.24 {
3.25 #define GL_ERROR_TRANSLATE(e) case e: return #e;
3.26 @@ -170,22 +177,57 @@
3.27 #undef GL_ERROR_TRANSLATE
3.28 }
3.29
3.30 -static __inline__ int
3.31 -GL_CheckAllErrors (const char *prefix, SDL_Renderer * renderer, const char *file, int line, const char *function)
3.32 +SDL_FORCE_INLINE void
3.33 +GL_ClearErrors(SDL_Renderer *renderer)
3.34 +{
3.35 + GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.36 +
3.37 + if (data->GL_ARB_debug_output_supported) {
3.38 + if (data->errors) {
3.39 + int i;
3.40 + for (i = 0; i < data->errors; ++i) {
3.41 + SDL_free(data->error_messages[i]);
3.42 + }
3.43 + SDL_free(data->error_messages);
3.44 +
3.45 + data->errors = 0;
3.46 + data->error_messages = NULL;
3.47 + }
3.48 + } else {
3.49 + while (data->glGetError() != GL_NO_ERROR) {
3.50 + continue;
3.51 + }
3.52 + }
3.53 +}
3.54 +
3.55 +SDL_FORCE_INLINE int
3.56 +GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function)
3.57 {
3.58 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.59 int ret = 0;
3.60 - /* check gl errors (can return multiple errors) */
3.61 - for (;;) {
3.62 - GLenum error = data->glGetError();
3.63 - if (error != GL_NO_ERROR) {
3.64 - if (prefix == NULL || prefix[0] == '\0') {
3.65 - prefix = "generic";
3.66 +
3.67 + if (data->GL_ARB_debug_output_supported) {
3.68 + if (data->errors) {
3.69 + int i;
3.70 + for (i = 0; i < data->errors; ++i) {
3.71 + SDL_SetError("%s: %s (%d): %s %s", prefix, file, line, function, data->error_messages[i]);
3.72 + ret = -1;
3.73 }
3.74 - SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
3.75 - ret++;
3.76 - } else {
3.77 - break;
3.78 + GL_ClearErrors(renderer);
3.79 + }
3.80 + } else {
3.81 + /* check gl errors (can return multiple errors) */
3.82 + for (;;) {
3.83 + GLenum error = data->glGetError();
3.84 + if (error != GL_NO_ERROR) {
3.85 + if (prefix == NULL || prefix[0] == '\0') {
3.86 + prefix = "generic";
3.87 + }
3.88 + SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
3.89 + ret = -1;
3.90 + } else {
3.91 + break;
3.92 + }
3.93 }
3.94 }
3.95 return ret;
3.96 @@ -226,6 +268,7 @@
3.97 {
3.98 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.99
3.100 + GL_ClearErrors(renderer);
3.101 if (SDL_CurrentContext != data->context) {
3.102 if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
3.103 return -1;
3.104 @@ -264,8 +307,35 @@
3.105 GL_CheckError("", renderer);
3.106 }
3.107
3.108 +static void
3.109 +GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, void *userParam)
3.110 +{
3.111 + SDL_Renderer *renderer = (SDL_Renderer *) userParam;
3.112 + GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.113
3.114 -GL_FBOList *
3.115 + if (type == GL_DEBUG_TYPE_ERROR_ARB) {
3.116 + /* Record this error */
3.117 + ++data->errors;
3.118 + data->error_messages = SDL_realloc(data->error_messages, data->errors * sizeof(*data->error_messages));
3.119 + if (data->error_messages) {
3.120 + data->error_messages[data->errors-1] = SDL_strdup(message);
3.121 + }
3.122 + }
3.123 + printf("%s\n", message);
3.124 +
3.125 + /* If there's another error callback, pass it along, otherwise log it */
3.126 + if (data->next_error_callback) {
3.127 + data->next_error_callback(source, type, id, severity, length, message, data->next_error_userparam);
3.128 + } else {
3.129 + if (type == GL_DEBUG_TYPE_ERROR_ARB) {
3.130 + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", message);
3.131 + } else {
3.132 + SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", message);
3.133 + }
3.134 + }
3.135 +}
3.136 +
3.137 +static GL_FBOList *
3.138 GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
3.139 {
3.140 GL_FBOList *result = data->framebuffers;
3.141 @@ -374,6 +444,16 @@
3.142 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
3.143 }
3.144
3.145 + /* Check for debug output support */
3.146 + if (SDL_GL_ExtensionSupported("GL_ARB_debug_output")) {
3.147 + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
3.148 +
3.149 + data->GL_ARB_debug_output_supported = SDL_TRUE;
3.150 + data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)&data->next_error_callback);
3.151 + data->glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM_ARB, &data->next_error_userparam);
3.152 + glDebugMessageCallbackARBFunc(GL_HandleDebugMessage, renderer);
3.153 + }
3.154 +
3.155 if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
3.156 || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
3.157 data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
3.158 @@ -442,7 +522,7 @@
3.159 }
3.160 }
3.161
3.162 -static __inline__ int
3.163 +SDL_FORCE_INLINE int
3.164 power_of_2(int input)
3.165 {
3.166 int value = 1;
3.167 @@ -453,7 +533,7 @@
3.168 return value;
3.169 }
3.170
3.171 -static __inline__ SDL_bool
3.172 +SDL_FORCE_INLINE SDL_bool
3.173 convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
3.174 GLint* internalFormat, GLenum* format, GLenum* type)
3.175 {
3.176 @@ -602,7 +682,7 @@
3.177 texture_h, 0, format, type, NULL);
3.178 }
3.179 renderdata->glDisable(data->type);
3.180 - if (GL_CheckError("glTexImage2D()", renderer) > 0) {
3.181 + if (GL_CheckError("glTexImage2D()", renderer) < 0) {
3.182 return -1;
3.183 }
3.184
3.185 @@ -641,8 +721,7 @@
3.186 renderdata->glDisable(data->type);
3.187 }
3.188
3.189 - GL_CheckError("", renderer);
3.190 - return 0;
3.191 + return GL_CheckError("", renderer);
3.192 }
3.193
3.194 static int
3.195 @@ -654,7 +733,6 @@
3.196
3.197 GL_ActivateRenderer(renderer);
3.198
3.199 - GL_CheckError("", renderer);
3.200 renderdata->glEnable(data->type);
3.201 renderdata->glBindTexture(data->type, data->texture);
3.202 renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3.203 @@ -689,10 +767,7 @@
3.204 data->format, data->formattype, pixels);
3.205 }
3.206 renderdata->glDisable(data->type);
3.207 - if (GL_CheckError("glTexSubImage2D()", renderer) > 0) {
3.208 - return -1;
3.209 - }
3.210 - return 0;
3.211 + return GL_CheckError("glTexSubImage2D()", renderer);
3.212 }
3.213
3.214 static int
3.215 @@ -782,8 +857,7 @@
3.216 (GLdouble) 0,
3.217 0.0, 1.0);
3.218 }
3.219 - GL_CheckError("", renderer);
3.220 - return 0;
3.221 + return GL_CheckError("", renderer);
3.222 }
3.223
3.224 static int
3.225 @@ -965,9 +1039,7 @@
3.226 #endif
3.227 data->glEnd();
3.228 }
3.229 - GL_CheckError("", renderer);
3.230 -
3.231 - return 0;
3.232 + return GL_CheckError("", renderer);
3.233 }
3.234
3.235 static int
3.236 @@ -983,9 +1055,7 @@
3.237
3.238 data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
3.239 }
3.240 - GL_CheckError("", renderer);
3.241 -
3.242 - return 0;
3.243 + return GL_CheckError("", renderer);
3.244 }
3.245
3.246 static int
3.247 @@ -1052,9 +1122,7 @@
3.248
3.249 data->glDisable(texturedata->type);
3.250
3.251 - GL_CheckError("", renderer);
3.252 -
3.253 - return 0;
3.254 + return GL_CheckError("", renderer);
3.255 }
3.256
3.257 static int
3.258 @@ -1067,6 +1135,7 @@
3.259 GLfloat minx, miny, maxx, maxy;
3.260 GLfloat centerx, centery;
3.261 GLfloat minu, maxu, minv, maxv;
3.262 +
3.263 GL_ActivateRenderer(renderer);
3.264
3.265 data->glEnable(texturedata->type);
3.266 @@ -1144,9 +1213,7 @@
3.267
3.268 data->glDisable(texturedata->type);
3.269
3.270 - GL_CheckError("", renderer);
3.271 -
3.272 - return 0;
3.273 + return GL_CheckError("", renderer);
3.274 }
3.275
3.276 static int
3.277 @@ -1247,6 +1314,14 @@
3.278 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.279
3.280 if (data) {
3.281 + GL_ClearErrors(renderer);
3.282 + if (data->GL_ARB_debug_output_supported) {
3.283 + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
3.284 +
3.285 + /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */
3.286 + /* For now, just always replace the callback with the original one */
3.287 + glDebugMessageCallbackARBFunc(data->next_error_callback, data->next_error_userparam);
3.288 + }
3.289 if (data->shaders) {
3.290 GL_DestroyShaderContext(data->shaders);
3.291 }
3.292 @@ -1266,7 +1341,9 @@
3.293 SDL_free(renderer);
3.294 }
3.295
3.296 -static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) {
3.297 +static int
3.298 +GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
3.299 +{
3.300 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.301 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
3.302 GL_ActivateRenderer(renderer);
3.303 @@ -1289,7 +1366,9 @@
3.304 return 0;
3.305 }
3.306
3.307 -static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) {
3.308 +static int
3.309 +GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
3.310 +{
3.311 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
3.312 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
3.313 GL_ActivateRenderer(renderer);
4.1 --- a/src/test/SDL_test_common.c Sat May 18 23:32:53 2013 -0700
4.2 +++ b/src/test/SDL_test_common.c Sun May 19 22:28:10 2013 -0700
4.3 @@ -27,7 +27,7 @@
4.4 #include <stdio.h>
4.5
4.6 #define VIDEO_USAGE \
4.7 -"[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
4.8 +"[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
4.9
4.10 #define AUDIO_USAGE \
4.11 "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
4.12 @@ -74,6 +74,7 @@
4.13 state->gl_multisamplesamples = 0;
4.14 state->gl_retained_backing = 1;
4.15 state->gl_accelerated = -1;
4.16 + state->gl_debug = 0;
4.17
4.18 return state;
4.19 }
4.20 @@ -99,6 +100,10 @@
4.21 state->renderdriver = argv[index];
4.22 return 2;
4.23 }
4.24 + if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
4.25 + state->gl_debug = 1;
4.26 + return 1;
4.27 + }
4.28 if (SDL_strcasecmp(argv[index], "--info") == 0) {
4.29 ++index;
4.30 if (!argv[index]) {
4.31 @@ -656,6 +661,9 @@
4.32 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
4.33 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
4.34 }
4.35 + if (state->gl_debug) {
4.36 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
4.37 + }
4.38
4.39 if (state->verbose & VERBOSE_MODES) {
4.40 SDL_Rect bounds;
5.1 --- a/test/testgl2.c Sat May 18 23:32:53 2013 -0700
5.2 +++ b/test/testgl2.c Sun May 19 22:28:10 2013 -0700
5.3 @@ -255,6 +255,7 @@
5.4 printf("Vendor : %s\n", glGetString(GL_VENDOR));
5.5 printf("Renderer : %s\n", glGetString(GL_RENDERER));
5.6 printf("Version : %s\n", glGetString(GL_VERSION));
5.7 + printf("Extensions : %s\n", glGetString(GL_EXTENSIONS));
5.8 printf("\n");
5.9
5.10 status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);