Name

    KHR_debug
        
Name Strings

    GL_KHR_debug

Contact

    Christophe Riccio (christophe.riccio 'at' amd.com)

Contributors

    Jaakko Konttinen, AMD
    Graham Sellers, AMD
    Mark Young, AMD
    Ahmet Oguz Akyuz, AMD
    Bruce Merry, ARM
    Daniel Koch, TransGaming
    Jon Leech, Independent
    Pat Brown, NVIDIA
    Greg Roth, NVIDIA
    Yaki Tebeka, Graphic Remedy
    Piers Daniell, NVIDIA
    Seth Sowerby, Apple
    Benj Lipchak, Apple
    Jean-François Roy, Apple
    Daniel Rakos, AMD
    Mark Callow, HI
    
Notice

    Copyright (c) 2012-2014 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Status
    
    Complete.
    Approved by the ARB on 2012/06/18.
    Approved by the OpenGL ES WG on 2012/06/15.
    Ratified by the Khronos Board of Promoters on 2012/07/27.
        
Version
    
    Last Modified Date: July 2, 2015
    Author Revision: 17

Number

    ARB Extension #119
    OpenGL ES Extension #118

Dependencies

    OpenGL 1.1 is required.
    
    The extension is written against the OpenGL 4.2 Compatibility Profile 
    specification (April 27, 2012).
    
Overview

    This extension allows the GL to notify applications when various events 
    occur that may be useful during application development, debugging and 
    profiling.
    
    These events are represented in the form of enumerable messages with a 
    human-readable string representation. Examples of debug events include 
    incorrect use of the GL, warnings of undefined behavior, and performance 
    warnings.
    
    A message is uniquely identified by a source, a type and an 
    implementation-dependent ID within the source and type pair.
    
    A message's source identifies the origin of the message and can either 
    describe components of the GL, the window system, third-party external 
    sources such as external debuggers, or even the application itself.
    
    The type of the message roughly identifies the nature of the event that 
    caused the message. Examples include errors, performance warnings, 
    warnings about undefined behavior or notifications identifying that the 
    application is within a specific section of the application code.
    
    A message's ID for a given source and type further distinguishes messages 
    within namespaces. For example, an error caused by a negative parameter 
    value or an invalid internal texture format are both errors generated by 
    the API, but would likely have different message IDs.
    
    Each message is also assigned to a severity level that denotes roughly how 
    "important" that message is in comparison to other messages across all 
    sources and types. For example, notification of a GL error would likely 
    have a higher severity than a performance warning due to redundant state 
    changes.
    
    Furthermore, every message contains an implementation-dependent string
    representation that provides a useful description of the event.
    
    Messages are communicated to the application through an application-
    defined callback function that is called by the GL implementation on each 
    debug message. The motivation for the callback routine is to free 
    application developers from actively having to query whether a GL error, 
    or any other debuggable event has happened after each call to a GL 
    function. With a callback, developers can keep their code free of debug 
    checks, set breakpoints in the callback function, and only have to react 
    to messages as they occur. In situations where using a callback is not 
    possible, a message log is also provided that stores only copies of recent 
    messages until they are actively queried. 
    
    To control the volume of debug output, messages can be disabled either 
    individually by ID, or entire sets of messages can be turned off based on 
    combination of source and type, through the entire application code or 
    only section of the code encapsulated in debug groups. A debug group may 
    also be used to annotate the command stream using descriptive texts. 

    This extension also defines debug markers, a mechanism for the OpenGL 
    application to annotate the command stream with markers for discrete 
    events.
    
    When profiling or debugging an OpenGL application with a built-in or an 
    external debugger or profiler, it is difficult to relate the commands 
    within the command stream to the elements of the scene or parts of the 
    program code to which they correspond. Debug markers and debug groups help 
    obviate this by allowing applications to specify this link. For example, a 
    debug marker can be used to identify the beginning of a frame in the 
    command stream and a debug group can encapsulate a specific command stream 
    to identify a rendering pass. Debug groups also allow control of the debug 
    outputs volume per section of an application code providing an effective 
    way to handle the massive amount of debug outputs that drivers can 
    generate.
    
    Some existing implementations of ARB_debug_output only expose the
    ARB_debug_output extension string if the context was created with the
    debug flag {GLX|WGL}_CONTEXT_DEBUG_BIT_ARB as specified in 
    {GLX|WGL}_ARB_create_context. The behavior is not obvious when the
    functionality is brought into the OpenGL core specification because the
    extension string and function entry points must always exist.

    This extension modifies the existing ARB_debug_output extension to allow 
    implementations to always have an empty message log. The specific messages 
    written to the message log or callback routines are already implementation 
    defined, so this specification simply makes it explicit that it's fine for 
    there to be zero messages generated, even when a GL error occurs, which is 
    useful if the context is non-debug.

    Debug output can be enabled and disabled by changing the DEBUG_OUTPUT 
    state. It is implementation defined how much debug output is generated if 
    the context was created without the CONTEXT_DEBUG_BIT set. This is a new 
    query bit added to the existing GL_CONTEXT_FLAGS state to specify whether 
    the context was created with debug enabled.

    Finally, this extension defines a mechanism for OpenGL applications to 
    label their objects (textures, buffers, shaders, etc.) with a descriptive 
    string. 
    
    When profiling or debugging an OpenGL application within an external or 
    built-in (debut output API) debugger or profiler it is difficult to 
    identify objects from their object names (integers). 
    
    Even when the object itself is viewed it can be problematic to 
    differentiate between similar objects. Attaching a descriptive string, a 
    label, to an object obviates this difficulty.
    
    The intended purpose of this extension is purely to improve the user 
    experience within OpenGL development tools and application built-in 
    profilers and debuggers. This extension typically improves OpenGL 
    programmers efficiency by allowing them to instantly detect issues and the 
    reason for these issues giving him more time to focus on adding new 
    features to an OpenGL application.

IP Status
    
    No known IP claims.
    
New Procedures and Functions
    
    NOTE: when implemented in an OpenGL ES context, all entry points defined
    by this extension must have a "KHR" suffix. When implemented in an
    OpenGL context, all entry points must have NO suffix, as shown below.

    void DebugMessageControl(enum source,
                             enum type,
                             enum severity,
                             sizei count,
                             const uint* ids,
                             boolean enabled);

    void DebugMessageInsert(enum source,
                            enum type,
                            uint id,
                            enum severity,
                            sizei length, 
                            const char* buf);

    void DebugMessageCallback(DEBUGPROC callback,
                              const void* userParam);
    
    uint GetDebugMessageLog(uint count,
                            sizei bufSize,
                            enum* sources,
                            enum* types,
                            uint* ids,
                            enum* severities,
                            sizei* lengths, 
                            char* messageLog);
    
    void GetPointerv(enum pname,
                     void** params);

    void PushDebugGroup(enum source, uint id, sizei length, 
        const char * message);

    void PopDebugGroup(void);

    void ObjectLabel(enum identifier, uint name, sizei length, 
        const char *label);

    void GetObjectLabel(enum identifier, uint name, sizei bufSize, 
        sizei *length, char *label);

    void ObjectPtrLabel(void* ptr, sizei length, 
        const char *label);

    void GetObjectPtrLabel(void* ptr, sizei bufSize, 
        sizei *length, char *label);
                   

New Types
    
    NOTE: when implemented in an OpenGL ES context, this typedef must have a
    "KHR" suffix (GLDEBUGPROCKHR). When implemented in an OpenGL context,
    thie typedef must have NO suffix, as shown below.

    The callback function that applications can define, and
    is accepted by DebugMessageCallback, is defined as:
    
        typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,
                                             GLenum type,
                                             GLuint id,
                                             GLenum severity,
                                             GLsizei length,
                                             const GLchar* message,
                                             const void* userParam);

    Note that this function pointer is defined as having the same calling 
    convention as the GL functions.
    
New Tokens
    
    NOTE: when implemented in an OpenGL ES context, all tokens defined by
    this extension must have a "_KHR" suffix. When implemented in an OpenGL
    context, all tokens must have NO suffix, as described below.

    Tokens accepted by the <target> parameters of Enable, Disable, and 
    IsEnabled:
    
        DEBUG_OUTPUT                                     0x92E0
        DEBUG_OUTPUT_SYNCHRONOUS                         0x8242

    Returned by GetIntegerv when <pname> is CONTEXT_FLAGS:

        CONTEXT_FLAG_DEBUG_BIT                           0x00000002

    Tokens accepted by the <value> parameters of GetBooleanv, GetIntegerv, 
    GetFloatv, GetDoublev and GetInteger64v:
    
        MAX_DEBUG_MESSAGE_LENGTH                         0x9143
        MAX_DEBUG_LOGGED_MESSAGES                        0x9144
        DEBUG_LOGGED_MESSAGES                            0x9145
        DEBUG_NEXT_LOGGED_MESSAGE_LENGTH                 0x8243
        MAX_DEBUG_GROUP_STACK_DEPTH                      0x826C  
        DEBUG_GROUP_STACK_DEPTH                          0x826D  
        MAX_LABEL_LENGTH                                 0x82E8
    
    Tokens accepted by the <pname> parameter of GetPointerv:
        
        DEBUG_CALLBACK_FUNCTION                          0x8244
        DEBUG_CALLBACK_USER_PARAM                        0x8245

    Tokens accepted or provided by the <source> parameters of
    DebugMessageControl, DebugMessageInsert and DEBUGPROC, and the <sources>
    parameter of GetDebugMessageLog (some commands restrict <source> to a
    subset of these parameters; see the specification body for details):
        
        DEBUG_SOURCE_API                                 0x8246
        DEBUG_SOURCE_WINDOW_SYSTEM                       0x8247
        DEBUG_SOURCE_SHADER_COMPILER                     0x8248
        DEBUG_SOURCE_THIRD_PARTY                         0x8249
        DEBUG_SOURCE_APPLICATION                         0x824A
        DEBUG_SOURCE_OTHER                               0x824B

    Tokens accepted or provided by the <type> parameters of
    DebugMessageControl, DebugMessageInsert and DEBUGPROC, and the <types> 
    parameter of GetDebugMessageLog:

        DEBUG_TYPE_ERROR                                 0x824C
        DEBUG_TYPE_DEPRECATED_BEHAVIOR                   0x824D
        DEBUG_TYPE_UNDEFINED_BEHAVIOR                    0x824E
        DEBUG_TYPE_PORTABILITY                           0x824F
        DEBUG_TYPE_PERFORMANCE                           0x8250
        DEBUG_TYPE_OTHER                                 0x8251
        DEBUG_TYPE_MARKER                                0x8268 

    Tokens accepted or provided by the <type> parameters of
    DebugMessageControl and DEBUGPROC, and the <types> parameter of 
    GetDebugMessageLog:

        DEBUG_TYPE_PUSH_GROUP                            0x8269  
        DEBUG_TYPE_POP_GROUP                             0x826A  
            
    Tokens accepted or provided by the <severity> parameters of
    DebugMessageControl, DebugMessageInsert and DEBUGPROC callback functions, 
    and the <severities> parameter of GetDebugMessageLog:

        DEBUG_SEVERITY_HIGH                              0x9146
        DEBUG_SEVERITY_MEDIUM                            0x9147
        DEBUG_SEVERITY_LOW                               0x9148
        DEBUG_SEVERITY_NOTIFICATION                      0x826B 

    Returned by GetError:

        STACK_UNDERFLOW                                  0x0504
        STACK_OVERFLOW                                   0x0503

    Tokens accepted or provided by the <identifier> parameters of
    ObjectLabel and GetObjectLabel:

        BUFFER                                           0x82E0
        SHADER                                           0x82E1
        PROGRAM                                          0x82E2
        VERTEX_ARRAY
        QUERY                                            0x82E3
        PROGRAM_PIPELINE                                 0x82E4
        TRANSFORM_FEEDBACK
        SAMPLER                                          0x82E6
        TEXTURE
        RENDERBUFFER
        FRAMEBUFFER
      [[ Compatibility Profile ]] 
        DISPLAY_LIST                                     0x82E7
      [[ End Profile-Specific Language ]]

    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
    GetFloatv, GetDoublev, and GetInteger64v:

        MAX_LABEL_LENGTH                                 

Additions to Chapter 2 of the OpenGL 4.2 Specification
(OpenGL Operation)

    In section 2.5 - GL Errors:
    Add to the end of the section (pg 19):
    
    "When an error is generated, the GL will also generate a debug output 
    message describing its cause (see section 5.5).  The message has the 
    source DEBUG_SOURCE_API and the type DEBUG_TYPE_ERROR, and an 
    implementation-dependent ID."
    
Additions to Chapter 3 of the OpenGL 4.2 Specification
(Rasterization)
    
    None.

Additions to Chapter 4 of the OpenGL 4.2 Specification
(Per-Fragment Operations and the Frame Buffer)
    
    None.
    
Additions to Chapter 5 of the OpenGL 4.2 Specification
(Special Functions)
    
    After section 5.4 - Hints (pg. 300) (section 5.3, p 217 in OpenGL ES 3.0), 
    add new section:
    
    "5.5 - Debug Output
    
    Application developers can obtain more information from the GL runtime in 
    the form of debug output.  This information can include details about GL 
    errors, undefined behavior, implementation-dependent performance warnings, 
    or other useful hints.
    
    This information is communicated through a stream of debug messages that 
    are generated as GL commands are executed.  The application can choose to 
    receive these messages either through a callback routine, or by querying 
    for them from a message log.
    
    Controls are provided for disabling messages that the application does not 
    care about, and for inserting application-generated messages into the 
    stream.
    
    The GL may provide different levels of debug output depending on how the 
    context was created. If the context was created without the
    CONTEXT_FLAG_DEBUG_BIT in the CONTEXT_FLAGS state, as described in Section
    6.1.12, then the GL may optionally not generate any debug messages, but
    the functions described below will otherwise operate without error.
    
    Debug output functionality is controlled with the DEBUG_OUTPUT enable
    state. If the context is created with the CONTEXT_FLAG_DEBUG_BIT set then 
    the initial state of DEBUG_OUTPUT is TRUE, otherwise the initial state of 
    DEBUG_OUTPUT is FALSE. In a debug context, if DEBUG_OUTPUT is disabled the 
    GL will not generate any debug output logs or callbacks. Enabling 
    DEBUG_OUTPUT again will enable full debug output functionality. If the 
    context was created without the CONTEXT_FLAG_DEBUG_BIT and the 
    DEBUG_OUTPUT is later enabled, the level of debug output logging is 
    defined by the GL implementation, which may have zero debug output. To 
    guarantee the full debug output support of the GL implementation the 
    context should be created with CONTEXT_FLAG_DEBUG_BIT context flag bit 
    set. 

    5.5.1 - Debug Messages
    
    A debug message is uniquely identified by the source that generated it, a 
    type within that source, and an unsigned integer ID identifying the 
    message within that type. The message source is one of the symbolic 
    constants listed in Table 5.3. The message type is one of the symbolic 
    constants listed in Table 5.4.
    
    Debug Output Message Source           Messages Generated by
    ---------------------------           ---------------------
    DEBUG_SOURCE_API                      The GL

    DEBUG_SOURCE_SHADER_COMPILER          The GLSL shader compiler or compilers for
                                          other extension-provided languages
                                          
    DEBUG_SOURCE_WINDOW_SYSTEM            The window system, such as WGL or GLX
                                          
    DEBUG_SOURCE_THIRD_PARTY              External debuggers or third-party middleware
                                          libraries
                                          
    DEBUG_SOURCE_APPLICATION              The application
    
    DEBUG_SOURCE_OTHER                    Sources that do not fit to any of the ones listed above
    ----------------------------------------------------------------------------
    Table 5.3: Sources of debug output messages.  Each message must originate
    from a source listed in this table.
    
    
    Debug Output Message Type               Informs about
    -------------------------               -------------
    DEBUG_TYPE_ERROR                        Events that generated an error

    DEBUG_TYPE_DEPRECATED_BEHAVIOR          Behavior that has been marked for
                                            deprecation
                                            
    DEBUG_TYPE_UNDEFINED_BEHAVIOR           Behavior that is undefined according to
                                            the specification
    
    DEBUG_TYPE_PERFORMANCE                  Implementation-dependent performance
                                            warnings
    
    DEBUG_TYPE_PORTABILITY                  Use of extensions or shaders in a way that
                                            is highly vendor-specific
    
    DEBUG_TYPE_OTHER                        Types of events that do not fit any of
                                            the ones listed above

    DEBUG_TYPE_MARKER                       Annotation of the command stream 

    DEBUG_TYPE_PUSH_GROUP                   Entering a debug group

    DEBUG_TYPE_POP_GROUP                    Leaving a debug group
    
    ----------------------------------------------------------------------------
    Table 5.4: Types of debug output messages. Each message is associated with
    one of these types that describes the nature of the message.
    
    Each message source and type pair contains its own namespace of messages 
    with every message being associated with an ID. The assignment of IDs to 
    messages within a namespace is implementation-dependent. There can 
    potentially be overlap between the namespaces of two different pairs of 
    source and type, so messages can only be uniquely distinguished from each 
    other by the full combination of source, type and ID.
    
    Each message is also assigned a severity level that roughly describes its 
    importance across all sources and types along a single global axis. The 
    severity of a message is one of the symbolic constants defined in 
    Table 5.5. Because messages can be disabled by their severity, this allows 
    for quick control the global volume of debug output.

    Severity Level Token                  Suggested examples of messages
    --------------------                  ------------------------------
    
    DEBUG_SEVERITY_HIGH                   Any GL error; dangerous undefined behavior;
                                          any GLSL or ARB shader compiler and
                                          linker errors;
                                          
    DEBUG_SEVERITY_MEDIUM                 Severe performance warnings; GLSL
                                          or other shader compiler and linker
                                          warnings; use of currently deprecated
                                          behavior

    DEBUG_SEVERITY_LOW                    Performance warnings from redundant
                                          state changes; trivial undefined behavior

    DEBUG_SEVERITY_NOTIFICATION           Any message which is not an 
                                          error or performance concern 

    ----------------------------------------------------------------------------
    Table 5.5: Severity levels of messages.  Each debug output message is
    associated with one of these severity levels.
    
    
    Every message also has a null-terminated string representation that is 
    used to describe the message.  The contents of the string can change 
    slightly between different instances of the same message (e.g. which 
    parameter value caused a specific GL error to occur). The format of a 
    message string is left as implementation-dependent, although it should at 
    least represent a concise description of the event that caused the message 
    to be generated.  Messages with different IDs should also have 
    sufficiently distinguishable string representations to warrant their 
    separation.
    
    The lengths of all messages, including their null terminators, must be
    guaranteed to be less or equal to the value of the
    implementation-dependent constant MAX_DEBUG_MESSAGE_LENGTH.
    
    Messages can be either enabled or disabled.  Messages that are disabled 
    will not be generated. All messages are initially enabled unless their 
    assigned severity is DEBUG_SEVERITY_LOW. The enabled state of messages can 
    be changed using the command DebugMessageControl.
    
    5.5.2 - Debug Message Callback
    
    Applications can provide a callback function for receiving debug messages 
    using the command
    
        void DebugMessageCallback(DEBUGPROC callback,
                                  const void* userParam);
        
    with <callback> storing the address of the callback function. This
    function's prototype must follow the type definition of DEBUGPROC 
    including its platform-dependent calling convention. Anything else will 
    result in undefined behavior. Only one debug callback can be specified 
    for the current context, and further calls overwrite the previous 
    callback. Specifying NULL as the value of <callback> clears the current 
    callback and disables message output through callbacks. Applications can 
    provide user-specified data through the pointer <userParam>. The context 
    will store this pointer and will include it as one of the parameters in 
    each call to the callback function.
    
    If the application has specified a callback function for receiving debug 
    output, the implementation will call that function whenever any enabled 
    message is generated.  The source, type, ID, and severity of the message 
    are specified by the DEBUGPROC parameters <source>, <type>, <id>, and 
    <severity>, respectively. The string representation of the message is 
    stored in <message> and its length (excluding the null-terminator) is 
    stored in <length>. The parameter <userParam> is the user-specified 
    parameter that was given when calling DebugMessageCallback.
    
    Applications can query the current callback function and the current 
    user-specified parameter by obtaining the values of
    DEBUG_CALLBACK_FUNCTION and DEBUG_CALLBACK_USER_PARAM, respectively.
    
    Applications that specify a callback function must be aware of certain 
    special conditions when executing code inside a callback when it is 
    called by the GL, regardless of the debug source.
    
    The memory for <message> is owned and managed by the GL, and should
    only be considered valid for the duration of the function call.
    
    The behavior of calling any GL or window system function from within the 
    callback function is undefined and may lead to program termination.
    
    Care must also be taken in securing debug callbacks for use with
    asynchronous debug output by multi-threaded GL implementations.
    Section 5.5.6 describes this in further detail.

    If the DEBUG_OUTPUT state is disabled then the GL will not call the
    callback function.        

    5.5.3 - Debug Message Log

    If DEBUG_CALLBACK_FUNCTION is NULL, then debug messages are instead 
    stored in an internal message log up to some maximum number of messages 
    as defined by the value of MAX_DEBUG_LOGGED_MESSAGES.
    
    Each context stores its own message log and will only store messages 
    generated by commands operating in that context.  If the message log
    fills up, then any subsequently generated messages will not be
    placed in the log until the message log is cleared, and will instead
    be discarded.
    
    Applications can query the number of messages currently in the log by 
    obtaining the value of DEBUG_LOGGED_MESSAGES, and the string length 
    (including its null terminator) of the oldest message in the log through 
    the value of DEBUG_NEXT_LOGGED_MESSAGE_LENGTH.
    
    To fetch message data stored in the log, the command GetDebugMessageLog 
    can be used as described in section 6.1.15.
    
    If DEBUG_CALLBACK_FUNCTION is not NULL, no generated messages will be 
    stored in the log but will instead be passed to the debug callback routine 
    as described in section 5.5.2.
    
    If the DEBUG_OUTPUT state is disabled then no messages are added to the 
    message log.

    5.5.4 - Controlling Debug Messages
    
    Applications can control the volume of debug output in the active debug 
    group, by disabling specific or groups of messages with the command:

        void DebugMessageControl(enum source,
                                 enum type,
                                 enum severity,
                                 sizei count,
                                 const uint* ids,
                                 boolean enabled);

    If <enabled> is TRUE, the referenced subset of messages will be enabled. 
    If FALSE, then those messages will be disabled.
    
    This command can reference different subsets of messages by first
    considering the set of all messages, and filtering out messages based on 
    the following ways:
    
        - If <source>, <type>, or <severity> is DONT_CARE, the messages from
          all sources, of all types, or of all severities are referenced
          respectively.

        - When values other than DONT_CARE are specified, all messages whose
          source, type, or severity match the specified <source>, <type>, or
          <severity> respectively will be referenced.

        - If <count> is greater than zero, then <ids> is an array of <count> 
          message IDs for the specified combination of <source> and <type>. In 
          this case, if <source> or <type> is DONT_CARE, or <severity> is not 
          DONT_CARE, the error INVALID_OPERATION is generated. 

          Unrecognized message IDs in <ids> are ignored. If <count> is zero,
          the value if <ids> is ignored.

    In addition, if any of <source>, <type>, and <severity> is not DONT_CARE 
    and is not one of the symbols from, respectively, Table 5.3, Table 5.4, 
    and Table 5.5, the error INVALID_ENUM is generated. If <count> is 
    negative, the error INVALID_VALUE is generated.

    Although messages are grouped into an implicit hierarchy by their
    sources and types, there is no explicit per-source, per-type or
    per-severity enabled state. Instead, the enabled state is stored
    individually for each message. There is no difference between disabling 
    all messages from one source in a single call, and individually 
    disabling all messages from that source using their types and IDs.

    If the DEBUG_OUTPUT state is disabled the GL operates the same as 
    if messages of every <source>, <type> or <severity> are disabled.
    
    5.5.5 - Externally Generated Messages
    
    To support applications and third-party libraries generating their own 
    messages, such as ones containing timestamp information or signals about 
    specific render system events, the following function can be called
    
        void DebugMessageInsert(enum source,
                                enum type,
                                uint id,
                                enum severity,
                                int length, 
                                const char* buf);

    The value of <id> specifies the ID for the message and <severity>
    indicates its severity level as defined by the caller. If <severity> is 
    not one of the severity levels listed in Table 5.5, the error 
    INVALID_ENUM will be generated. The value of <type> must be one of the 
    values from Table 5.4 and the value of <source> must be either 
    DEBUG_SOURCE_APPLICATION or DEBUG_SOURCE_THIRD_PARTY, or the error 
    INVALID_ENUM will be generated. The string <buf> contains the string 
    representation of the message. The parameter <length> contains the number 
    of characters in <buf>. If <length> is negative, it is implied that <buf> 
    contains a null terminated string. The error INVALID_VALUE will be 
    generated if the number of characters in <buf>, excluding the null
    terminator when <length> is negative, is not less than the value of
    MAX_DEBUG_MESSAGE_LENGTH.

    If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are 
    discarded and do not generate an error.

    5.5.6 - Debug Groups
    
    Debug groups provide a method for annotating a command stream with 
    discrete groups of commands using a descriptive text. Debug output 
    messages, either generated by the implementation or inserted by the 
    application with DebugMessageInsert are written to the active debug group, 
    the top of the debug group stack. Debug groups are strictly hierarchical. 
    Their sequences may be nested within other debug groups but can not 
    overlap. If no debug group has been pushed by the application then the 
    active debug group is the default debug group. 
    
    The command
    
        void PushDebugGroup(enum source, uint id, sizei length, 
            const char *message);
        
    pushes a debug group described by the string <message> into the command 
    stream. The value of <id> specifies the ID of messages generated. The 
    parameter <length> contains the number of characters in <message>. If 
    <length> is negative, it is implied that <message> contains a null 
    terminated string. The message has the specified <source> and <id>, <type> 
    DEBUG_TYPE_PUSH_GROUP, and <severity> DEBUG_SEVERITY_NOTIFICATION. The GL 
    will put a new debug group on top of the debug group stack which inherits 
    the control of the volume of debug output of the debug group previously 
    residing on the top of the debug group stack. Because debug groups are 
    strictly hierarchical, any additional control of the debug output volume 
    will only apply within the active debug group and the debug groups pushed 
    on top of the active debug group.

    An INVALID_ENUM error is generated if the value of <source> is neither 
    DEBUG_SOURCE_APPLICATION nor DEBUG_SOURCE_THIRD_PARTY. An INVALID_VALUE 
    error is generated if <length> is negative and the number of characters in 
    <message>, excluding the null-terminator, is not less than the value of
    MAX_DEBUG_MESSAGE_LENGTH.
        
    The command
    
        void PopDebugGroup();
        
    pops the active debug group. When a debug group is popped, the GL 
    will also generate a debug output message describing its cause based 
    on the <message> string, the source <source>, and an ID <id> submitted 
    to the associated PushDebugGroup command. DEBUG_TYPE_PUSH_GROUP
    and DEBUG_TYPE_POP_GROUP share a single namespace for message <id>.
    <severity> has the value DEBUG_SEVERITY_NOTIFICATION. The <type> 
    has the value DEBUG_TYPE_POP_GROUP. Popping a debug group restores 
    the debug output volume control of the parent debug group.

    Attempting to pop the default debug group off the stack generates a
    STACK_UNDERFLOW error; pushing a debug group onto a stack containing
    MAX_DEBUG_GROUP_STACK_DEPTH minus one elements will generate a 
    STACK_OVERFLOW error.

    5.5.7 - Asynchronous and Synchronous Debug Output
    
    The behavior of how and when the GL driver is allowed to generate debug 
    messages, and subsequently either call back to the application or place 
    the message in the debug message log, is affected by the state 
    DEBUG_OUTPUT_SYNCHRONOUS. This state can be modified by the Enable and 
    Disable commands. Its initial value is FALSE.
    
    When DEBUG_OUTPUT_SYNCHRONOUS is disabled, the driver is optionally 
    allowed to concurrently call the debug callback routine from 
    potentially multiple threads, including threads that the context that 
    generated the message is not currently bound to. The implementation may 
    also call the callback routine asynchronously after the GL command that 
    generated the message has already returned. The application is fully 
    responsible for ensuring thread safety due to debug callbacks under 
    these circumstances. In this situation the <userParam> value may be 
    helpful in identifying which application thread's command originally 
    generated the debug callback.
    
    When DEBUG_OUTPUT_SYNCHRONOUS is enabled, the driver guarantees 
    synchronous calls to the callback routine by the context. When synchronous 
    callbacks are enabled, all calls to the callback routine will be made by 
    the thread that owns the current context; all such calls will be made 
    serially by the current context; and each call will be made before the GL 
    command that generated the debug message is allowed to return.
    
    When no callback is specified and DEBUG_OUTPUT_SYNCHRONOUS is disabled, 
    the driver can still asynchronously place messages in the debug message 
    log, even after the context thread has returned from the GL function that 
    generated those messages. When DEBUG_OUTPUT_SYNCHRONOUS is enabled, the 
    driver guarantees that all messages are added to the log before the GL 
    function returns.
    
    Enabling synchronous debug output greatly simplifies the responsibilities 
    of the application for making its callback functions thread-safe, but may 
    potentially result in drastically reduced driver performance.
    
    DEBUG_OUTPUT_SYNCHRONOUS only guarantees intra-context synchronization for 
    the callbacks of messages generated by that context, and does not 
    guarantee synchronization across multiple contexts. If multiple contexts 
    are concurrently used by the application, it is allowed for those contexts 
    to also concurrently call their designated callbacks, and the application 
    is responsible for handling thread safety in that situation even if 
    DEBUG_OUTPUT_SYNCHRONOUS is enabled in all contexts."

    5.5.8 Debug Labels:

    Debug labels provide a method for annotating any object (texture, buffer, 
    shader, etc.) with a descriptive text label. These labels may then be used 
    by the debug output (see section 5.5) or an external tool such as a 
    debugger or profiler to describe labelled objects.
    
    The command
    
        void ObjectLabel(enum identifier, uint name, sizei length, const char *label);
        
    labels the object identified by <name> and its namespace <identifier>.
    <identifier> must be one of the tokens in table 5.1, indicating the type 
    of the object corresponding to <name>.


        Identifier           Object Type
        ---------------------------------------
        BUFFER            |  buffer
        SHADER            |  shader 
        PROGRAM           |  program
        VERTEX_ARRAY      |  vertex array 
        QUERY             |  query
        PROGRAM_PIPELINE  |  program pipeline
        TRANSFORM_FEEDBACK|  transform feedback
        SAMPLER           |  sampler
        TEXTURE           |  texture 
        RENDERBUFFER      |  render buffer
        FRAMEBUFFER       |  frame buffer
[[ Compatibility Profile Only]] 
        DISPLAY_LIST      |  display list 
[[ End Profile-Specific Language ]]
        ---------------------------------------
        Table 5.1. Valid object namespace identifiers and the corresponding
        object type.

    The command
    
        void ObjectPtrLabel(void* ptr, sizei length, const char *label);
        
    labels a sync object identified by <ptr>.

    <label> contains a string used to label an object. <length> contains the
    number of characters in <label>. If <length> is negative, it is implied that
    <label> contains a null-terminated string. If <label> is NULL, any debug
    label is effectively removed from the object.

    An INVALID_ENUM error is generated by ObjectLabel if <identifier> is not 
    one of the object types listed in table 5.1.

    An INVALID_VALUE error is generated by ObjectLabel if <name> is not 
    the name of a valid object of the type specified by <identifier>.

    An INVALID_VALUE is generated if the <ptr> parameter of ObjectPtrLabel
    is not the name of a sync object.

    An INVALID_VALUE error is generated if the number of characters in
    <label>, excluding the null terminator when <length> is negative, is not
    less than the value of MAX_LABEL_LENGTH.

    A label is part of the state of the object to which it is associated. 
    The initial state of an object's label is the empty string. Labels need
    not be unique.


Additions to Chapter 6 of the OpenGL 4.2 Specification
(State and State Requests)
    
    Modify the title of Section 6.1.6 - String Queries to read
    "Section 6.1.6 - Pointer and String Queries", and insert to the
    beginning of the section:
    
    The command
        
        void GetPointerv(enum pname, void** params);
        
    obtains the pointer or pointers named <pname> in the array <params>.
    The possible values for <pname> are DEBUG_CALLBACK_FUNCTION and
    DEBUG_CALLBACK_USER_PARAM, which respectively return the current
    debug output callback function pointer and its application-specified
    user parameter.  Each <pname> returns a single pointer value.
    
    Modify Section 6.1.12 "Pointer and String Queries"

    Add to the paragraph describing the context profile mask and flags
    (preceding the description of GetStringi) on page 485:

    "If CONTEXT_FLAG_DEBUG_BIT is set in CONTEXT_FLAGS, then the DEBUG_OUTPUT
    state, as described in section 5.5, will be enabled by default."

    After Section 6.1.14 - Renderbuffer Object Queries (pg 324):
    Add new Section 6.1.15 - Debug Object Queries:
    
    6.1.15 - Debug Output Queries

    When no debug callback is set, debug messages are stored in
    a debug message log as described in section 5.5.3.  Messages can
    be queried from the log by calling
    
        uint GetDebugMessageLog(uint count,
                                sizei bufSize,
                                enum* sources,
                                enum* types,
                                uint* ids,
                                enum* severities,
                                sizei* lengths,
                                char* messageLog);

    This function fetches a maximum of <count> messages from the message
    log, and will return the number of messages successfully fetched.
    
    Messages will be fetched from the log in order of oldest to
    newest.  Those messages that were fetched will be removed from the
    log.
    
    The sources, types, severities, IDs, and string lengths of
    fetched messages will be stored in the application-provided arrays
    <sources>, <types>, <severities>, <ids>, and <lengths>,
    respectively.  The application is responsible for allocating enough
    space for each array to hold up to <count> elements.  The string
    representations of all fetched messages are stored in the
    <messageLog> array.  If multiple messages are fetched, their strings
    are concatenated into the same <messageLog> array and will be
    separated by single null terminators.  The last string in the array
    will also be null-terminated.  The maximum size of <messageLog>,
    including the space used by all null terminators, is given by
    <bufSize>. If <bufSize> is less than zero and <messageLog> is not
    NULL, an INVALID_VALUE error will be generated. If a message's
    string, including its null terminator, can not fully fit within the
    <messageLog> array's remaining space, then that message and any
    subsequent messages will not be fetched and will remain in the log.
    The string lengths stored in the array <lengths> include the space
    for the null terminator of each string.
    
    Any or all of the arrays <sources>, <types>, <ids>, <severities>, 
    <lengths> and <messageLog> can also be null pointers, which causes
    the attributes for such arrays to be discarded when messages
    are fetched, however those messages will still be removed from the
    log.  Thus to simply delete up to <count> messages from the message
    log while ignoring their attributes, the application can call the
    function with null pointers for all attribute arrays.  

    If the context was created without the CONTEXT_FLAG_DEBUG_BIT in the
    CONTEXT_FLAGS state, as described in Section 6.1.12, then the GL can opt
    to never add messages to the message log so GetDebugMessageLog will
    always return zero.

    Add new Section 6.1.16 - Debug Label Queries:

    6.1.16 - Debug Label Queries

    The command
    
        void GetObjectLabel(enum identifier, uint name, sizei bufSize, 
            sizei *length, char *label);
        void GetObjectPtrLabel(void* ptr, sizei bufSize, 
            sizei *length, char *label);

    returns in <label> the string labelling an object. <label> will be
    null-terminated. The actual number of characters written into <label>,
    excluding the null terminator, is returned in <length>. If <length> is 
    NULL, no length is returned. The maximum number of characters that may
    be written into <label>, including the null terminator, is specified by
    <bufSize>. If no debug label was specified for the object then <label> 
    will contain a null-terminated empty string, and zero will be returned
    in <length>. If <label> is NULL and <length> is non-NULL then no string 
    will be returned and the length of the label will be returned in
    <length>.
    
    An INVALID_ENUM error is generated by GetObjectLabel if identifier is not 
    one of the object types listed in table 5.1 except SYNC. 

    An INVALID_VALUE error is generated by GetObjectLabel if <name> is not 
    the name of a valid object of the type specified by <identifier>.

Additions to the OpenGL / GLX / GLX Protocol Specifications

    None.

Additions to the WGL Specification

    None.


Interactions with OpenGL ES

    This extension specification uses non-suffixed names for new entry
    points, types, and tokens. This is correct for implementations against
    OpenGL. However, when implemented in an OpenGL ES context, all new entry
    points, types, and tokens are given KHR suffixes.

    In OpenGL ES versions prior to and including ES 3.1 there is no
    CONTEXT_FLAGS state and therefore the CONTEXT_FLAG_DEBUG_BIT cannot be
    queried. GLES contexts must act as if this state existed as described
    in this specification even if the state itself is not visible to
    applications. For example, DEBUG_OUTPUT must still be enabled by default
    if the context was created with debug enabled.

Interactions with GLX_ARB_create_context_robustness

    If the GLX window-system binding API is used to create a context,
    the GLX_ARB_create_context extension is supported, and the bit
    GLX_CONTEXT_DEBUG_BIT_ARB is set in GLX_CONTEXT_FLAGS when
    glXCreateContextAttribsARB is called, the resulting context will
    have debug enabled, and the CONTEXT_FLAG_DEBUG_BIT bit will be set
    in CONTEXT_FLAGS as described above in section 6.1.12.

Interactions with WGL_ARB_create_context_robustness

    If the WGL window-system binding API is used to create a context,
    the WGL_ARB_create_context extension is supported, and the bit
    WGL_CONTEXT_DEBUG_BIT_ARB is set in WGL_CONTEXT_FLAGS when
    wglCreateContextAttribsARB is called, the resulting context will
    have debug enabled, and the CONTEXT_FLAG_DEBUG_BIT bit will be set
    in CONTEXT_FLAGS as described above in section 6.1.12.

Dependencies on GL and ES profiles, versions, and other extensions
    
    Dependencies on OpenGL 4.2 Compatibility specification and any other
    versions or extensions that already provide the GetPointerv entry
    point as provided by the OpenGL 4.2 Compatibility specification

        - Remove the modifications to Section 6.1.6 from this
          specification with the exception that GetPointerv will still
          accept DEBUG_CALLBACK_FUNCTION and
          DEBUG_CALLBACK_USER_PARAM as valid values for <pname>,
          and will return the same values as described in Chapter 6.
          
    Dependencies on OpenGL 4.2 Compatibility specification and any other
    versions that support display lists
    
        - DebugMessageControl, DebugMessageInsert,
          DebugMessageCallback, and GetDebugMessageLog are
          not compiled into display lists.
          
          Add the following to section 5.5.1 of the OpenGL 4.0
          Compatibility specification, after the paragraph beginning
          with "GL command stream management" (pg 414):
          
            "Debug output: DebugMessageControl,
             DebugMessageInsert, DebugMessageCallback, and
             GetDebugMessageLog"
             
          Add the same language to corresponding sections of other
          specifications.

Dependencies on program pipeline objects

    If program pipeline objects are not supported, remove PROGRAM_PIPELINE
    from table 5.1. 

    Program pipeline objects are supported starting with OpenGL 4.2 and
    OpenGL ES 3.1. They are also supported if the OpenGL
    GL_ARB_separate_shader_objects or OpenGL ES
    GL_EXT_separate_shader_objects extensions are supported.
      
Errors
    
    The error INVALID_ENUM will be generated by DebugMessageControl
    if <source> is not DONT_CARE or one of the debug output sources
    listed in Table 5.3.

    The error INVALID_ENUM will be generated by DebugMessageControl
    if <type> is not DONT_CARE or one of the debug output types listed
    in Table 5.4.

    The error INVALID_ENUM will be generated by DebugMessageControl
    if <severity> is not DONT_CARE or one of the severity levels listed
    in Table 5.5.

    The error INVALID_VALUE will be generated by DebugMessageControl
    if <count> is less than zero.

    The error INVALID_OPERATION will be generated by
    DebugMessageControl when <count> is greater than zero and
    <source> is DONT_CARE.

    The error INVALID_OPERATION will be generated by
    DebugMessageControl when <count> is greater than zero and
    <type> is DONT_CARE.

    The error INVALID_OPERATION will be generated by
    DebugMessageControl when <count> is greater than zero and
    and <severity> is not DONT_CARE.
 
    The error INVALID_VALUE will be generated by GetDebugMessageLog
    if the value of <count> is less than zero.

    The error INVALID_VALUE will be generated by GetDebugMessageLog
    if <bufSize> is less than zero.
    
    The error INVALID_ENUM will be generated by DebugMessageInsert if
    the value of <source> is not DEBUG_SOURCE_APPLICATION or
    DEBUG_SOURCE_THIRD_PARTY.
    
    The error INVALID_ENUM will be generated by DebugMessageInsert if
    the value of <type> is not one of the values from Table 5.4.

    The error INVALID_ENUM will be generated by DebugMessageInsert if
    <severity> is not a valid debug severity level listed in Table 5.5.

    The error INVALID_VALUE will be generated by DebugMessageInsert
    if the number of characters in <buf>, excluding the null terminator
    when <length> is negative, is not less than
    MAX_DEBUG_MESSAGE_LENGTH.
    
    The error INVALID_ENUM will be generated by PushDebugGroup 
    if <source> is not DEBUG_SOURCE_APPLICATION or 
    DEBUG_SOURCE_THIRD_PARTY. 

    The error INVALID_VALUE will be generated by PushDebugGroup
    if <length> is negative and the number of characters in <message>,
    excluding the null-terminator, is not less than the value of
    MAX_DEBUG_MESSAGE_LENGTH.

    The <source> value of PushDebugGroup must be either 
    DEBUG_SOURCE_APPLICATION or DEBUG_SOURCE_THIRD_PARTY, or the
    error INVALID_ENUM will be generated.

    Popping a group off the stack with no entry generates the error 
    STACK_UNDERFLOW; pushing a debug group onto a full stack generates 
    the error STACK_OVERFLOW.

    An INVALID_VALUE error is generated by ObjectLabel and
    GetObjectLabel if <name> is not the name of a valid object of the type
    specified by <identifier>.

    An INVALID_VALUE error is generated by ObjectPtrLabel and
    GetObjectPtrLabel if <ptr> is not the name of a sync object.

    An INVALID_VALUE error is generated by ObjectLabel if the number of
    characters in <label>, excluding the null terminator when <length> is
    negative, is not less than MAX_LABEL_LENGTH.

    An INVALID_ENUM error is generated by ObjectLabel and GetObjectLabel if
    <identifier> is not one of the object namespace tokens in table 5.1.


New State
         
    Add new table 6.55 after p.376 (Debug Output):
    
                                                                       Initial
    Get Value                             Type  Get Command            Value         Description                Sec     Attribute
    --------------------------            ----  -----------            -------       -------------------------  ------  ---------
    DEBUG_CALLBACK_FUNCTION               Y     GetPointerv            NULL          The current debug output  5.5.2     -
                                                                                     callback function pointer

    DEBUG_CALLBACK_USER_PARAM             Y     GetPointerv            NULL          The current debug output  5.5.2     -
                                                                                     callback user parameter

    DEBUG_LOGGED_MESSAGES                 Z+    GetIntegerv            0             The number of messages    5.5.3     -
                                                                                     currently in the debug
                                                                                     message log

    DEBUG_NEXT_LOGGED_MESSAGE_LENGTH      Z+    GetIntegerv            0             The string length of the  5.5.3     -
                                                                                     oldest debug message in
                                                                                     the debug message log
                                                                                
    DEBUG_GROUP_STACK_DEPTH               Z+    GetIntegerv            1             Debug group stack         5.5.6     -
                                                                                     pointer    

    DEBUG_OUTPUT_SYNCHRONOUS              B     IsEnabled              FALSE         The enabled state for     5.5.7     -
                                                                                     synchronous debug message
                                                                                     callbacks

    DEBUG_OUTPUT                          B     IsEnabled              Depends on    The enabled state for     5.5       -
                                                                       the context*  debug output 
                                                                                     functionality

    * Contexts created with the CONTEXT_DEBUG_BIT bit set, as defined in
    GLX_ARB_create_context and WGL_ARB_create_context control the initial
    value of this state. If CONTEXT_DEBUG_BIT is set then the initial
    value of DEBUG_OUTPUT is TRUE otherwise its FALSE.  


    Add the following to Table 6.14 Buffer Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.24 Textures (state per texture object):
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.44 Shader Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.46 Program Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.36 Renderbuffer  (state per renderbuffer object):
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.33 Framebuffer (state per framebuffer object):
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.9 Vertex Array Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.54 Query Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.45 Program Pipeline Object State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.26 Textures (state per sampler object):
     
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.56 Transform Feedback State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  --------------    -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2

    Add the following to Table 6.57 Sync (state per sync object):
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  ----------------- -------  -----------  ---
    -          S     GetObjectPtrLabel empty    Debug label  6.2

      [[ Compatibility Profile ]] 
    Add Table 6.60 Display List State:
    
                                       Initial
    Get Value  Type  Get Command       Value    Description  Sec
    ---------  ----  ----------------- -------  -----------  ---
    -          S     GetObjectLabel    empty    Debug label  6.2
      [[ End Profile-Specific Language ]]


New Implementation Dependent State

    Add new table 6.56 after table 6.55 (Implementation Dependent Debug Output Values):
                                                            Minimum
    Get Value                            Type  Get Command  Value    Description                  Sec      Attribute
    --------------------------------     --    -----------  -----    -------------------------    ------   ---------
    MAX_DEBUG_MESSAGE_LENGTH             Z+    GetIntegerv   1        The maximum length of a     5.5.1      -
                                                                      debug message string,
                                                                      including its null
                                                                      terminator

    MAX_DEBUG_LOGGED_MESSAGES            Z+    GetIntegerv   1        The maximum number of       5.5.3      -
                                                                      messages stored in the
                                                                      debug message log

    MAX_DEBUG_GROUP_STACK_DEPTH          Z+    GetIntegerv  64        Maximum group               5.5.6      -
                                                                      stack depth 

    MAX_LABEL_LENGTH                     Z+    GetIntegerv  256       Max length of a label       5.5.8      -
                                                                      string


Usage Examples

    Scenario 1: skip a section of the code
    // Setup of the default active debug group: Filter everything in
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);

    // Generate a debug marker debug output message
    glDebugMessageInsert(
        GL_DEBUG_SOURCE_APPLICATION, 
        GL_DEBUG_TYPE_MARKER, 100,
        GL_DEBUG_SEVERITY_NOTIFICATION, 
        -1, "Message 1");
    
    // Push debug group 1
    glPushDebugGroup(
        GL_DEBUG_SOURCE_APPLICATION, 
        1, 
        -1, "Message 2");
 
    // Setup of the debug group 1: Filter everything out
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);

    // This message won't appear in the debug output log of 
    glDebugMessageInsert(
        GL_DEBUG_SOURCE_APPLICATION, 
        GL_DEBUG_TYPE_MARKER, 100,
        GL_DEBUG_SEVERITY_NOTIFICATION, 
        -1, "Message 3"); 
 
    // Pop debug group 1, restore the volume control of the default debug group.
    glPopDebugGroup();
 
    // Generate a debug marker debug output message
    glDebugMessageInsert(
        GL_DEBUG_SOURCE_APPLICATION,
        GL_DEBUG_TYPE_MARKER, 100,
        GL_DEBUG_SEVERITY_NOTIFICATION, 
        -1, "Message 5");

    // Expected debug output from the GL implementation
    // Message 1 
    // Message 2
    // Message 2
    // Message 5

    Scenario 2: Only output a subsection of the code 
    and disable some messages for the entire application

    // Setup the control of de debug output for the default debug group 
    glDebugMessageControl(
        GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
    glDebugMessageControl(
        GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
    std::vector<GLuint> Messages = {1234, 2345, 3456, 4567};
    glDebugMessageControl(
        GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 
        GLuint(Messages,size()), &Messages[0], GL_FALSE);
    glDebugMessageControl(
        GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, GL_DONT_CARE, 
        GLuint(Messages,size()), &Messages[0], GL_FALSE);

    // Push debug group 1
    // Inheritate of the default debug group debug output volume control
    // Filtered out by glDebugMessageControl
    glPushDebugGroup(
        GL_DEBUG_SOURCE_APPLICATION, 
        1,
        -1, "Message 1"); 
    
    // In this section of the code, we are interested in performances.
    glDebugMessageControl(
        GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE, 0, NULL, GL_TRUE);
    // But we already identify that some messages are not really useful for us.
    std::vector<GLuint> Messages = {5678, 6789};
    glDebugMessageControl(
        GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 
        GLuint(Messages,size()), &Messages[0], GL_FALSE);

    glDebugMessageInsert(
        GL_DEBUG_SOURCE_APPLICATION, 
        GL_DEBUG_TYPE_PERFORMANCE, 1357,
        GL_DEBUG_SEVERITY_MEDIUM, 
        -1, "Message 2"); 
    glDebugMessageInsert(
        GL_DEBUG_SOURCE_THIRD_PARTY, // We still filter out these messages.
        GL_DEBUG_TYPE_OTHER, 3579,
        GL_DEBUG_SEVERITY_MEDIUM, 
        -1, "Message 3"); 
    
    glPopDebugGroup(); 

    // Expected debug output from the GL implementation
    // Message 2


Issues

    (1) Should the extension provides a method for querying markers?

    RESOLVED: No.


    (2) Is the concept of <severity> meaningful for most profiling use cases?
    
    DISCUSSION: The debug output API was originally designed for debugging 
                but its design has led implementation and application to use 
                it for profiling. Furthermore, markers are not strictly 
                speaking low, medium or high severity messages.
    
    RESOLVED: Added DEBUG_SEVERITY_NOTIFICATION


    (3) How should an implementation behave when the application doesn't push 
        and pop group markers evenly?
    
    DISCUSSION: Extra "pop" may be ignored as it is done in OpenGL ES 
                EXT_debug_marker but what to do if the user push too many 
                time? In any case, if a software doesn't push and pop evenly, 
                its design is pretty ill. Hence it is better to notify the 
                application as soon as possible by generating an error.

                OpenGL legacy handles this problem by limiting the size of the 
                stacks and generating STACK_UNDERFLOW and STACK_OVERFLOW 
                errors. 

                The size of the marker group stack need to be big enough so 
                that the application won't be limited but small enough so that 
                an error is generated soon when pushes and pops are not even.
    
                Another option is to let the drivers workaround this issue by
                ignoring push commands for a full stack and pop commands for 
                an empty stack. In such case, an application doesn't have an 
                immediate feedback for this behavior. 

    RESOLVED: Generates STACK_UNDERFLOW or STACK_UNDERFLOW errors 


    (4) Do we need a maximum length for a marker string?

    RESOLVED: No, reuse MAX_DEBUG_MESSAGE_LENGTH

    
    (5) Can we use this new extension to allow applications to request the 
        info logs from compiling, linking and validating to be automatically 
        submitted to the debug output log and debug output call-back function? 

    DISCUSSION: The API may need a new <type> value DEBUG_TYPE_INFO_LOG 
                for every kind of info logs. glLinkProgram, glCompileShader, 
                glCreateShaderProgram, glValidateProgram and 
                glValidateProgramPipeline,  which execution generate the info 
                logs, could also automatically submit this logs the the debug
                output API.

                Such strategy can already be apply by querying the info log 
                manually and submitting it to the debug output API with 
                DebugMessageInsert but on some implementations querying the 
                log immediately after the operation may significantly slow 
                down the general compilation of shaders process. 

                The mechanism could be enable with glEnable with a dedicated 
                value (DEBUG_OUTPUT_INFO_LOG). When enable, an option is 
                that shader, program and program pipeline would not have to 
                maintain this log.

                This perspective emphasis the centralised nature of OpenGL
                debugging to the debug output API. 

    RESOLVED: Nothing prevent an implementation implementing ARB_debug_output
              to do it already.  


    (6) Should we use dedicated functions for pushing and popping the group 
        marker stack or use DebugMessageInsert with a dedicated types?

    DISCUSSION: These functions have side effects (causing underflow errors, 
                causing other messages to become disabled) rather than purely 
                injecting messages into the debug log.

    RESOLVED: Use separated functions.


    (7) Should we generate an error when we pop the last entry or when the 
        stack is empty?

    DISCUSSION: For the deprecated stacks, at the beginning of the program the 
                stack depth was 1 which implies a default debug group (id 0?) 
                in the present case. 

    RESOLVED: Let's follow the deprecated stacks precedent.
    

    (8) Should we be able to query the current debug group?

    DISCUSSION: ARB_debug_output doesn't provide a query API for debug output 
                control states, should we follow this precedent or are there 
                use cases where is could be especially useful?

    RESOLVED: No, it doesn't seem very useful.


    (9) Should we provide within which debug group a message is generated?

    DISCUSSION: Such information might be useful but we would need to add a 
                parameter to the callback function. Also, the application can 
                take the responsibility of saving the current active debug
                group. Such option avoid API disruption.

    RESOLVED: (8) could resolve this issue as well if this is actually at 
              desired feature. Also nothing prevents an implementation to use 
              a debug group id to form the debug output message. Finally an 
              application can always store the current debug group each time 
              a DEBUG_TYPE_PUSH_GROUP is generated.

    
    (10) Do we need a dedicated mechanism to enable and disable debug outputs?

    DISCUSSION: It could seem that using glDebugMessageControl could allow 
                to disable debug output. However with the introduction of 
                debug groups, glDebugMessageControl only disable the active 
                debug group and it could be pretty complex for an application 
                to ensure that each debug group is disable. A easier idea 
                would be to be global switch glEnable(GL_DEBUG_OUTPUT) 
                allowing the application to completely switch on and off the 
                entire debug output mechanism.

    RESOLVED: Issue covered by ARB_debug_output2


    (11) Should there be a way to enable and disable the debug output
         functionality via glEnable(GL_DEBUG_OUTPUT) in addition to the way
         the context is created? This may be useful for third-party or 
         pre-existing code that doesn't have control over how the context is 
         created. This could be exposed in addition to the context creation 
         flag, and the context creation flag just sets the default state of 
         the enable.
    
    RESOLVED: Yes, based on various feedback this would be useful. Added
              to revision 3 of this extension spec.


    (12) Should we use a single function to set the label for all objects?

    DISCUSSION: This is the approach chosen in OpenGL ES extension 
                EXT_debug_label. It builds up a new strong precedent 
                for an important functionality but not exactly one 
                which purpose is to build a strong design precedent.

                On one hand using a unique function for all objects 
                reduce the number of new entry point from 24 to 2.

    RESOLVED: For the purpose of convergence with ES, the groups have 
              voted for only 2 functions.


    (13) Do we need a maximum length (MAX_LABEL_LENGTH) for the label?

    DISCUSSION: Following the precedents given by others strings in 
                OpenGL, this seems useful. On one hand ARB_debug_output 
                has a maximum size of the debug message 
                (MAX_DEBUG_MESSAGE_LENGTH), shader variable names have 
                a maximum length but on other hand the shader source 
                and the program info log doesn't have such limitation. 
                However, it seems hard to imagine that implementations 
                doesn't have limitation somehow. 

    RESOLVED: Yes


    (14) Should we provide a function to label a display list?

    RESOLVED: Yes for compatibility profile only.


    (15) Should the ES version of this extension supports the message log
         or only the callback function?

    DISCUSSION: When promoting AMD_debug_output to ARB_debug_output, the ARB
                has added a message log that can be query by the application 
                if no callback function has been specified by the application.
                The purpose of this addition was to support remote rendering. 
                Is remote rendering supported by OpenGL ES? The ES group 
                typically wants to have only one way to do things, should we
                only support the callback function for ES debug output?

    RESOLVED: The ES group has chosen to keep it by vote
    

    (16) Why do OpenGL implementations use KHR suffixes, while OpenGL
         implementations use no suffix?

    DISCUSSION: this functionality was initially defined by OpenGL 4.3, and
    set of "backwards compatibility" extensions were defined to allow
    implementing it against earlier GL versions. OpenGL ARB policy in the
    case of backwards compatibility extensions is that extension suffixes
    should not be added. The OpenGL ES Working Group then decided to support
    the same functionality as an OpenGL ES extension, and both groups agreed
    to share a single KHR specification for the extension. However, OpenGL
    ES policy requires extension suffixes on Khronos-approved OES and KHR
    extensions.

    We are aware of this inconsistency, but both working groups have chosen
    to stand by their own naming policies and the inconsistency is unlikely
    to be resolved.

Revision History

    Revision 17, 2015/07/02 (Jan-Harald Fredriksen)
      - Clarify CONTEXT_FLAGS state for ES3.1 and earlier in the Interactions
        section (Bug 13104).

    Revision 16, 2015/03/11 (Jon Leech)
      - Clarify dependencies required to support PROGRAM_PIPELINE (Bug
        13545).

    Revision 15, 2014/03/04 (Jon Leech)
      - Minor changes to clean up expected message output format in example
        code and refer to the value of state named by tokens, rather than
        the token values themselves (Bug 10083).

    Revision 14, 2013/11/05 (Jon Leech)
      - Edit state tables to replace the "Get Value" of LABEL with "-",
        indicating unnamed state. There is no token LABEL in the extension,
        and the GetObject*Label commands do not take <pname> parameters (Bug
        11131).

    Revision 13, 2013/06/24 (Jon Leech)
      - Add 'const' attribute to <userParam> for DebugMessageCallback and
        the corresponding GLDEBUGPROC type. Specify that unrecognized
        message IDs are ignored in the DebugMessageControl <ids> array.
        Specify that GetDebugMessageLog <messageLog> parameter must be
        NULL when <bufSize> is less than zero, to allow an early out.
        Replace spurious GLvoid with void. (Bug 10083).

    Revision 12, 2013/06/15 (Jon Leech)
      - Clarify in the New Tokens section that the <source> parameter of
        some commands may not allow all possible values shown in this
        section (public Bug 889).

    Revision 11, 2013/04/26 (Jon Leech)
      - Implement OpenGL ES policy of adding KHR suffixes to all KHR
        extensions. Add notes, OpenGL ES Interaction section, and issue 16
        explaining the situation (Bug 9716).

    Revision 10, 2013/04/16 (Jon Leech)
      - Fix type of <ids> parameter in GetDebugMessageLog body (Bug 10083)

    Revision 9, 2012/09/18 (pbrown)
      - Add a "void" function argument list for PopDebugGroup().  The GLEW 
        library needs this to properly parse the extension spec file.

    Revision 8, 2012/09/16 (Jon Leech)
      - Add existing tokens allowed for ObjectLabel identifiers to "New
        Tokens" section, without enum values since they aren't actually new
        (Bug 9506).

    Revision 7, 2012/09/12 (Jon Leech)
      - Clarify description of DebugMessageControl parameters to avoid
        triple negatives (Bug 9392).

    Revision 6, 2012/07/31 (criccio)
      - ObjectLabel generates an INVALID_VALUE error if <name> 
        doesn't identify a valid object.

    Revision 5, 2012/06/22 (criccio)
      - Resolved issue 15

    Revision 4, 2012/06/19 (Jon Leech)
      - Change logSize parameter to bufSize

    Revision 3, 2012/06/12 (criccio)
      - Added ObjectPtrLabel and GetObjectPtrLabel (bug 9140)

    Revision 2, 2012/06/07 (criccio)
      - Updated overview for higher consistence of the language. 
      - Clarified when the message is generated by the GL when popping
        a debug group.

    Revision 1, 2012/06/04 (criccio)
      - First draft, merged GL_ARB_debug_output, GL_ARB_debug_output2, 
        GL_ARB_debug_group and GL_ARB_debug_label.

