]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
GL: improve debugging
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 31 Aug 2024 10:17:46 +0000 (20:17 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Thu, 12 Sep 2024 13:53:35 +0000 (23:53 +1000)
Makes gl_debug work in standard builds (it has no cost when disabled).

Removes registration of gl_printcheckerror in standard builds where it
does nothing (still declared because it might be set by -developer3).

Makes various GL errors red, warnings yellow.

GL_TABLE_TOO_LARGE was removed in GL 3, GLES doesn't have it either.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
gl_backend.c
glquake.h
model_shared.c

index d85e0c3030e86f6ba1fbe0c89b2eae46ca5ce3f5..ba2adf73c994bc4b4f53d1447aa8741093dcfd0d 100644 (file)
@@ -4,7 +4,7 @@
 
 #define MAX_RENDERTARGETS 4
 
-cvar_t gl_debug = {CF_CLIENT, "gl_debug", "0", "enables OpenGL debug output, 0 = off, 1 = HIGH severity only, 2 = also MEDIUM severity, 3 = also LOW severity messages.  (note: enabling may not take effect until vid_restart on some drivers)"};
+cvar_t gl_debug = {CF_CLIENT, "gl_debug", "0", "enables OpenGL 4.3 debug output, 0 = off, 1 = HIGH severity only, 2 = also MEDIUM severity, 3 = also LOW severity messages.  (note: enabling may not take effect until vid_restart on some drivers, and only X11 and Windows are known to support the debug context)"};
 cvar_t gl_paranoid = {CF_CLIENT, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
 cvar_t gl_printcheckerror = {CF_CLIENT, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
 
@@ -37,62 +37,58 @@ void GL_PrintError(GLenum errornumber, const char *filename, unsigned int linenu
        {
 #ifdef GL_INVALID_ENUM
        case GL_INVALID_ENUM:
-               Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_INVALID_ENUM at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_INVALID_VALUE
        case GL_INVALID_VALUE:
-               Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_INVALID_VALUE at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_INVALID_OPERATION
        case GL_INVALID_OPERATION:
-               Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_INVALID_OPERATION at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_STACK_OVERFLOW
        case GL_STACK_OVERFLOW:
-               Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_STACK_UNDERFLOW
        case GL_STACK_UNDERFLOW:
-               Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_OUT_OF_MEMORY
        case GL_OUT_OF_MEMORY:
-               Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
-               break;
-#endif
-#ifdef GL_TABLE_TOO_LARGE
-       case GL_TABLE_TOO_LARGE:
-               Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber);
                break;
 #endif
 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION
        case GL_INVALID_FRAMEBUFFER_OPERATION:
-               Con_Printf("GL_INVALID_FRAMEBUFFER_OPERATION at %s:%i\n", filename, linenumber);
+               Con_Printf(CON_ERROR "GL_INVALID_FRAMEBUFFER_OPERATION at %s:%i\n", filename, linenumber);
                break;
 #endif
        default:
-               Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
+               Con_Printf(CON_ERROR "GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber);
                break;
        }
 }
+#endif // DEBUGGL
 
 static void GLAPIENTRY GL_DebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const GLvoid* userParam)
 {
-       const char *sev = "ENUM?", *typ = "ENUM?", *src = "ENUM?";
+       const char *sev = "ENUM?", *typ = "ENUM?", *src = "ENUM?", *col = "";
        switch (severity)
        {
        case GL_DEBUG_SEVERITY_LOW_ARB: sev = "LOW"; break;
-       case GL_DEBUG_SEVERITY_MEDIUM_ARB: sev = "MED"; break;
-       case GL_DEBUG_SEVERITY_HIGH_ARB: sev = "HIGH"; break;
+       case GL_DEBUG_SEVERITY_MEDIUM_ARB: sev = "MED"; col = CON_WARN; break;
+       case GL_DEBUG_SEVERITY_HIGH_ARB: sev = "HIGH"; col = CON_ERROR; break;
        }
        switch (type)
        {
-       case GL_DEBUG_TYPE_ERROR_ARB: typ = "ERROR"; break;
+       case GL_DEBUG_TYPE_ERROR_ARB: typ = "ERROR"; col = CON_ERROR; break;
        case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typ = "DEPRECATED"; break;
        case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typ = "UNDEFINED"; break;
        case GL_DEBUG_TYPE_PORTABILITY_ARB: typ = "PORTABILITY"; break;
@@ -108,9 +104,8 @@ static void GLAPIENTRY GL_DebugOutputCallback(GLenum source, GLenum type, GLuint
        case GL_DEBUG_SOURCE_APPLICATION_ARB: src = "APP"; break;
        case GL_DEBUG_SOURCE_OTHER_ARB: src = "OTHER"; break;
        }
-       Con_Printf("GLDEBUG: %s %s %s: %u: %s\n", sev, typ, src, (unsigned int)id, message);
+       Con_Printf("gl_debug: %s%s %s %s: %u: %s\n", col, sev, typ, src, (unsigned int)id, message);
 }
-#endif
 
 #define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
 
@@ -374,7 +369,9 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&v_flipped);
        Cvar_RegisterVariable(&gl_debug);
        Cvar_RegisterVariable(&gl_paranoid);
+#ifdef DEBUGGL // gl_printcheckerror does nothing in normal builds
        Cvar_RegisterVariable(&gl_printcheckerror);
+#endif
 
        Cmd_AddCommand(CF_CLIENT, "gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
 
@@ -1111,11 +1108,11 @@ static void GL_Backend_ResetState(void)
        case RENDERPATH_GL32:
        case RENDERPATH_GLES2:
                // set up debug output early
-#ifdef DEBUGGL
-               if (vid.support.arb_debug_output)
+               if (gl_debug.integer > 0 && vid.support.arb_debug_output)
                {
                        GLuint unused = 0;
                        CHECKGLERROR
+                       Con_Print("gl_debug: GL_ARB_debug_output is supported, enabling callback\n");
                        if (gl_debug.integer >= 1)
                                qglEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
                        if (gl_debug.integer >= 3)
@@ -1130,7 +1127,6 @@ static void GL_Backend_ResetState(void)
                                qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unused, GL_FALSE);
                        qglDebugMessageCallbackARB(GL_DebugOutputCallback, NULL);
                }
-#endif //DEBUGGL
                CHECKGLERROR
                qglColorMask(1, 1, 1, 1);CHECKGLERROR
                qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
@@ -1663,11 +1659,13 @@ void R_Mesh_Start(void)
 {
        BACKENDACTIVECHECK
        R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
+#ifdef DEBUGGL // gl_printcheckerror isn't registered in normal builds
        if (gl_printcheckerror.integer && !gl_paranoid.integer)
        {
                Con_Printf(CON_WARN "WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
                Cvar_SetValueQuick(&gl_paranoid, 1);
        }
+#endif
 }
 
 static qbool GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
@@ -1824,7 +1822,7 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
                        {
                                if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
                                {
-                                       Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
+                                       Con_Printf(CON_WARN "R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
                                        return;
                                }
                        }
@@ -1835,7 +1833,7 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri
                        {
                                if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
                                {
-                                       Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
+                                       Con_Printf(CON_WARN "R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
                                        return;
                                }
                        }
@@ -2021,7 +2019,7 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void
                {
                        int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
                        if (!bufferobject && gl_paranoid.integer)
-                               Con_DPrintf("Warning: no bufferobject in R_Mesh_VertexPointer(%i, %i, %i, %p, %p, %08x)", components, gltype, (int)stride, pointer, (void *)vertexbuffer, (unsigned int)bufferoffset);
+                               Con_DPrintf(CON_WARN "Warning: no bufferobject in R_Mesh_VertexPointer(%i, %i, %i, %p, %p, %08x)", components, gltype, (int)stride, pointer, (void *)vertexbuffer, (unsigned int)bufferoffset);
                        gl_state.pointer_vertex_components = components;
                        gl_state.pointer_vertex_gltype = gltype;
                        gl_state.pointer_vertex_stride = stride;
index 6c9d514296db786de615ac9f652b44df1bb664bd..8d603ad6df5dcc0b7fc7b6bcb970fd19d2204a12 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -140,13 +140,14 @@ typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id,
 #define GL_VERSION                             0x1F02
 #define GL_EXTENSIONS                          0x1F03
 
-#define GL_NO_ERROR                            0x0
-#define GL_INVALID_VALUE                       0x0501
-#define GL_INVALID_ENUM                                0x0500
-#define GL_INVALID_OPERATION                   0x0502
-#define GL_STACK_OVERFLOW                      0x0503
-#define GL_STACK_UNDERFLOW                     0x0504
-#define GL_OUT_OF_MEMORY                       0x0505
+#define GL_NO_ERROR                        0x0
+#define GL_INVALID_VALUE                   0x0501
+#define GL_INVALID_ENUM                    0x0500
+#define GL_INVALID_OPERATION               0x0502
+#define GL_STACK_OVERFLOW                  0x0503
+#define GL_STACK_UNDERFLOW                 0x0504
+#define GL_OUT_OF_MEMORY                   0x0505
+#define GL_INVALID_FRAMEBUFFER_OPERATION   0x0506
 
 #define GL_DITHER                              0x0BD0
 #define GL_ALPHA                               0x1906
@@ -368,7 +369,6 @@ typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id,
 #define GL_RENDERBUFFER_BINDING            0x8CA7
 #define GL_MAX_COLOR_ATTACHMENTS           0x8CDF
 #define GL_MAX_RENDERBUFFER_SIZE           0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION   0x0506
 #define GL_DEPTH_STENCIL                              0x84F9
 #define GL_UNSIGNED_INT_24_8                          0x84FA
 #define GL_DEPTH24_STENCIL8                           0x88F0
@@ -1051,7 +1051,7 @@ void GL_PrintError(GLenum errornumber, const char *filename, unsigned int linenu
                GLenum gl_errornumber; \
                if (gl_printcheckerror.integer) \
                        Con_Printf("CHECKGLERROR at %s:%d\n", __FILE__, __LINE__); \
-               if (qglGetError) /* bones_was_here: is this pointer check still necessary? */ \
+               if (qglGetError) /* bones_was_here: TODO ensure this is always available, GLES does support it */ \
                        while ((gl_errornumber = qglGetError())) \
                                GL_PrintError(gl_errornumber, __FILE__, __LINE__); \
        }}
index adf8a867cb77b8b769536aab1529f137832124ef..988ab7c8851b7aec7527d5bcc09c118b8ac033ef 100644 (file)
@@ -2976,7 +2976,7 @@ void Mod_BuildVBOs(void)
                {
                        if (loadmodel->surfmesh.data_element3s[i] != loadmodel->surfmesh.data_element3i[i])
                        {
-                               Con_Printf("Mod_BuildVBOs: element %u is incorrect (%u should be %u)\n", i, loadmodel->surfmesh.data_element3s[i], loadmodel->surfmesh.data_element3i[i]);
+                               Con_Printf(CON_WARN "Mod_BuildVBOs: element %u is incorrect (%u should be %u)\n", i, loadmodel->surfmesh.data_element3s[i], loadmodel->surfmesh.data_element3i[i]);
                                loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
                        }
                }
@@ -4749,7 +4749,7 @@ void Mod_Mesh_Validate(model_t *mod)
                        if (e[j] < first || e[j] >= end)
                        {
                                if (!warned)
-                                       Con_DPrintf("Mod_Mesh_Validate: detected corrupt surface - debug me!\n");
+                                       Con_DPrintf(CON_WARN "Mod_Mesh_Validate: detected corrupt surface - debug me!\n");
                                warned = true;
                                e[j] = first;
                        }