GL_KHR_debug#

Supported Hardware#

Series5, Series5XT, Series6, Series6XE, Series6XT

Valid APIs#

OpenGL ES 2.0, 3.x

Description#

KHR_debug combines a number of debug features into a single package that is made consistent across OpenGL and OpenGL ES. There are three main features provided by this extension:

  • Message Logging: While running in Debug mode, if the driver detects any errors, performance problems or any sort of problem, it can raise a human readable message to a log. An application is also free to add its own messages to this log. A callback API is also provided, so that the user can be notified when a message is generated. This is similar to the GL_ARB_debug_output extension.

  • Group Markers: Push and Pop functions are provided to encapsulate a block of functionality with a label. This is primarily to aid tracing and other debug tools when examining a recorded call stream. This functionality is similar to that provided by EXT_debug_marker.

  • Object Labels: Finally, this extension also adds the ability to tag objects with a name. Again, this is primarily for tracing tools when examining a recorded call stream, to allow users to quickly identify specific objects, rather than looking them up by their assigned identifier.

In conjunction with debug tools, this is a very useful extension as it allows users to get a better idea of how their application’s GL calls are laid out. Typical usage includes things like putting group markers around the start and end of application functions or labelling key textures or vertex buffers to match the assets they contain.

Example#

// Debug callback function
void (APIENTRY) debugMessageCallback(GLenum source,
                                     GLenum type,
                                     GLuint id,
                                     GLenum severity,
                                     GLsizei length,
                                     const GLchar* message,
                                     const void* userParam)
{
    /*
        Handle the message based on severity and such. Here we're using printf to
        output a message.
        This example only handles the type, severity and message. Useful information
        can be gleaned
        from the other parameters as well but would unnecessarily clutter this
        example.
    */
    // Output the message type
    switch (type)
    {
    case GL_DEBUG_TYPE_ERROR:
        {
            printf("%s", "Error ");
            break;
        }
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOUR:
        {
            printf("%s", "Deprecated Behaviour ");
            break;
        }
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOUR:
        {
            printf("%s", "Undefined Behaviour ");
            break;
        }
    case GL_DEBUG_TYPE_PORTABILITY:
        {
            printf("%s", "Portability Issue ");
            break;
        }
    case GL_DEBUG_TYPE_PERFORMANCE:
        {
            printf("%s", "Performance Issue ");
            break;
        }
    case GL_DEBUG_TYPE_OTHER:
        {
            printf("%s", "Misc Message ");
            break;
        }
    case GL_DEBUG_TYPE_MARKER:
        {
            printf("%s", "Marker Hit ");
            break;
        }
    case default:
        {
            printf("%s", "Unknown Message Type ");
            break;
        }
    }
    // Output the message severity
    switch (severity)
    {
    case GL_DEBUG_SEVERITY_NOTIFICATION:
        {
            printf("%s", "(Notification): ");
            break;
        }
    case GL_DEBUG_SEVERITY_LOW:
        {
            printf("%s", "(Low Severity): ");
            break;
        }
    case GL_DEBUG_SEVERITY_MEDIUM:
        {
            printf("%s", "(Medium Severity): ");
            break;
        }
    case GL_DEBUG_SEVERITY_HIGH:
        {
            printf("%s", "(High Severity): ");
            break;
        }
    case default:
        {
            printf("%s", "(Unknown Severity): ");
            break;
        }
    }
    // Append the message and a newline.
    if (length==0)
    {
        // NULL terminated strings are easy enough
        printf("%s\n", message);
    }
    else
    {
        // Strings with a specified length are not NULL terminated
        printf("%.*s", length, message);
    }
}
void initialise()
{
    /*
        Use a debug marker to encapsulate the initialise function, to mark this group
        in a tracing tool like PVRTrace.
    */
    glPushDebugMarker(GL_DEBUG_SOURCE_APPLICATION, 0, 0, "Function 'initialise'");
    ...
    // Create and label a texture object
    GLuint importantTexture;
    glGenTextures(1, &importantTexture);
    glObjectLabel(GL_TEXTURE, importantTexture, 0, "importantTexture");
    ...
    // Pop the debug marker
    glPopDebugMarker();
}