Name

    ARB_debug_output
        
Name Strings

    GL_ARB_debug_output

Contact

    Jaakko Konttinen (jaakko.konttinen 'at' amd.com)

Contributors

    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
    
Notice

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

Status
    
    Complete. Approved by the ARB on June 9, 2010.
    Approved by the Khronos Board of Promoters on July 23, 2010.
        
Version
    
    Last Modified Date: July 8, 2013
    Author Revision: 17

Number

    ARB Extension #104

Dependencies

    OpenGL 1.1 is required.
    
    The extension is written against the OpenGL 4.0 Core specification
    (March 11, 2010).
    
    The extension interacts with OpenGL 4.0 Compatibility specification
    and other specifications that provide display list support.
    
    The extension interacts with OpenGL 4.0 Compatibility specification
    and other specifications that provide the GetPointerv entry point.
    
Overview

    This extension allows the GL to notify applications when various
    events occur that may be useful during application development and
    debugging.
    
    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, or warnings about undefined behavior.
    
    A message's ID for a given source and type further
    distinguishes messages within those groups.  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.
    
    Finally, 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, 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 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 groups of messages can be
    turned off based on combination of source and type.
    
    The only requirement on the minimum quantity and type of messages
    that implementations of this extension must support is that some
    sort of message must be sent notifying the application whenever any
    GL error occurs.  Any further messages are left to the
    implementation.  Implementations do not have to output messages from
    all sources nor do they have to use all types of messages listed
    by this extension, and both new sources and types can be added by
    other extensions. 

    For performance reasons it is recommended, but not required, that
    implementations restrict supporting this extension only to
    contexts created using the debug flag as provided by
    WGL_create_context or GLX_create_context.  This extension places no
    limits on any other functionality provided by debug contexts through
    other extensions.
    
IP Status
    
    No known IP claims.
    
New Procedures and Functions
    
    void DebugMessageControlARB(enum source,
                                enum type,
                                enum severity,
                                sizei count,
                                const uint* ids,
                                boolean enabled);

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

    void DebugMessageCallbackARB(DEBUGPROCARB callback,
                                 const void* userParam);
    
    uint GetDebugMessageLogARB(uint count,
                               sizei bufSize,
                               enum* sources,
                               enum* types,
                               uint* ids,
                               enum* severities,
                               sizei* lengths, 
                               char* messageLog);
    
    void GetPointerv(enum pname,
                     void** params);
                     
New Types
    
    The callback function that applications can define, and
    is accepted by DebugMessageCallbackARB, is defined as:
    
        typedef void (APIENTRY *DEBUGPROCARB)(enum source,
                                              enum type,
                                              uint id,
                                              enum severity,
                                              sizei length,
                                              const char* message,
                                              const void* userParam);

    Note that this function pointer is defined as having the
    same calling convention as the GL functions.
    
New Tokens
    
    Tokens accepted by the <target> parameters of Enable, Disable,
    and IsEnabled:
    
        DEBUG_OUTPUT_SYNCHRONOUS_ARB                      0x8242

    Tokens accepted by the <value> parameters of GetBooleanv,
    GetIntegerv, GetFloatv, and GetDoublev:
    
        MAX_DEBUG_MESSAGE_LENGTH_ARB                      0x9143
        MAX_DEBUG_LOGGED_MESSAGES_ARB                     0x9144
        DEBUG_LOGGED_MESSAGES_ARB                         0x9145
        DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB              0x8243
    
    Tokens accepted by the <pname> parameter of GetPointerv:
        
        DEBUG_CALLBACK_FUNCTION_ARB                       0x8244
        DEBUG_CALLBACK_USER_PARAM_ARB                     0x8245

    Tokens accepted or provided by the <source> parameters of
    DebugMessageControlARB, DebugMessageInsertARB and DEBUGPROCARB,
    and the <sources> parameter of GetDebugMessageLogARB:
        
        DEBUG_SOURCE_API_ARB                              0x8246
        DEBUG_SOURCE_WINDOW_SYSTEM_ARB                    0x8247
        DEBUG_SOURCE_SHADER_COMPILER_ARB                  0x8248
        DEBUG_SOURCE_THIRD_PARTY_ARB                      0x8249
        DEBUG_SOURCE_APPLICATION_ARB                      0x824A
        DEBUG_SOURCE_OTHER_ARB                            0x824B

    Tokens accepted or provided by the <type> parameters of
    DebugMessageControlARB, DebugMessageInsertARB and DEBUGPROCARB,
    and the <types> parameter of GetDebugMessageLogARB:

        DEBUG_TYPE_ERROR_ARB                              0x824C
        DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB                0x824D
        DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB                 0x824E
        DEBUG_TYPE_PORTABILITY_ARB                        0x824F
        DEBUG_TYPE_PERFORMANCE_ARB                        0x8250
        DEBUG_TYPE_OTHER_ARB                              0x8251
            
    Tokens accepted or provided by the <severity> parameters of
    DebugMessageControlARB, DebugMessageInsertARB and DEBUGPROCARB
    callback functions, and the <severities> parameter of
    GetDebugMessageLogARB:

        DEBUG_SEVERITY_HIGH_ARB                           0x9146
        DEBUG_SEVERITY_MEDIUM_ARB                         0x9147
        DEBUG_SEVERITY_LOW_ARB                            0x9148

Additions to Chapter 2 of the OpenGL 4.0 Core 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_ARB and the type
    DEBUG_TYPE_ERROR_ARB, and an implementation-dependent ID."
    
Additions to Chapter 3 of the OpenGL 4.0 Core Specification
(Rasterization)
    
    None.

Additions to Chapter 4 of the OpenGL 4.0 Core Specification
(Per-Fragment Operations and the Frame Buffer)
    
    None.
    
Additions to Chapter 5 of the OpenGL 4.0 Core Specification
(Special Functions)
    
    After section 5.4 - Hints (pg. 300), 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.
    
    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_ARB                  The GL

    DEBUG_SOURCE_SHADER_COMPILER_ARB      The GLSL shader compiler or compilers for
                                          other extension-provided languages
                                          
    DEBUG_SOURCE_WINDOW_SYSTEM_ARB        The window system, such as WGL or GLX
                                          
    DEBUG_SOURCE_THIRD_PARTY_ARB          External debuggers or third-party middleware
                                          libraries
                                          
    DEBUG_SOURCE_APPLICATION_ARB          The application
    
    DEBUG_SOURCE_OTHER_ARB                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_ARB                    Events that generated an error

    DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB      Behavior that has been marked for
                                            deprecation
                                            
    DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB       Behavior that is undefined according to
                                            the specification
    
    DEBUG_TYPE_PERFORMANCE_ARB              Implementation-dependent performance
                                            warnings
    
    DEBUG_TYPE_PORTABILITY_ARB              Use of extensions or shaders in a way that
                                            is highly vendor-specific
    
    DEBUG_TYPE_OTHER_ARB                    Types of events that do not fit any of
                                            the ones listed above
    
    ----------------------------------------------------------------------------
    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_ARB               Any GL error; dangerous undefined behavior;
                                          any GLSL or ARB shader compiler and
                                          linker errors;
                                          
    DEBUG_SEVERITY_MEDIUM_ARB             Severe performance warnings; GLSL
                                          or other shader compiler and linker
                                          warnings; use of currently deprecated
                                          behavior
    
    DEBUG_SEVERITY_LOW_ARB                Performance warnings from redundant
                                          state changes; trivial undefined behavior
    ----------------------------------------------------------------------------
    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 implementation-dependent
    constant MAX_DEBUG_MESSAGE_LENGTH_ARB.
    
    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_ARB.  The
    enabled state of messages can be changed using the command
    DebugMessageControlARB.
    
    5.5.2 - Debug Message Callback
    
    Applications can provide a callback function for receiving debug
    messages using the command
    
        void DebugMessageCallbackARB(DEBUGPROCARB callback,
                                     const void* userParam);
        
    with <callback> storing the address of the callback function.  This
    function's prototype must follow the type definition of
    DEBUGPROCARB 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 DEBUGPROCARB 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 DebugMessageCallbackARB.
    
    Applications can query the current callback function and
    the current user-specified parameter by obtaining the values of
    DEBUG_CALLBACK_FUNCTION_ARB and DEBUG_CALLBACK_USER_PARAM_ARB,
    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.
        
    5.5.3 - Debug Message Log

    If DEBUG_CALLBACK_FUNCTION_ARB 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_ARB.
    
    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_ARB, and the
    string length (including its null terminator) of the oldest message
    in the log through the value of
    DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB.
    
    To fetch message data stored in the log, the command
    GetDebugMessageLogARB can be used.
    
    If DEBUG_CALLBACK_FUNCTION_ARB 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.
    
    5.5.4 - Controlling Debug Messages
    
    Applications can control the volume of debug output by disabling
    specific or groups of messages with the command:

        void DebugMessageControlARB(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> is not DONT_CARE, then all messages whose source
          does not match <source> will not be referenced.
          
        - If <type> is not DONT_CARE, then all messages whose type does
          not match <type> will not be referenced.
          
        - If <severity> is not DONT_CARE, then all messages whose
          severity level does not match <severity> will not 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.  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.
    
    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 DebugMessageInsertARB(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_ARB or
    DEBUG_SOURCE_THIRD_PARTY_ARB, 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
    MAX_DEBUG_MESSAGE_LENGTH_ARB.

    5.5.6 - 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_ARB.  This state can be modified
    by the Enable and Disable commands.  Its initial value is FALSE.
    
    When DEBUG_OUTPUT_SYNCHRONOUS_ARB 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_ARB 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_ARB
    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_ARB 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.
    
    The DEBUG_OUTPUT_SYNCHRONOUS_ARB 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_ARB is enabled
    in all contexts."

Additions to Chapter 6 of the OpenGL 4.0 Core 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_ARB and
    DEBUG_CALLBACK_USER_PARAM_ARB, which respectively return the current
    debug output callback function pointer and its application-specified
    user parameter.  Each <pname> returns a single pointer value.
    
    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 GetDebugMessageLogARB(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, the error INVALID_VALUE
    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
    <messageLog> is NULL, the value of <bufSize> is ignored.

Additions to the OpenGL / GLX / GLX Protocol Specifications

    None.

Additions to the WGL Specification

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

        - Remove the modifications to Section 6.1.6 from this
          specification with the exception that GetPointerv will still
          accept DEBUG_CALLBACK_FUNCTION_ARB and
          DEBUG_CALLBACK_USER_PARAM_ARB as valid values for <pname>,
          and will return the same values as described in Chapter 6.
          
    Dependencies on OpenGL 4.0 Compatibility specification and any other
    versions that support display lists
    
        - DebugMessageControlARB, DebugMessageInsertARB,
          DebugMessageCallbackARB, and GetDebugMessageLogARB 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: DebugMessageControlARB,
             DebugMessageInsertARB, DebugMessageCallbackARB, and
             GetDebugMessageLogARB"
             
          Add the same language to corresponding sections of other
          specifications.
          
Errors
    
    The error INVALID_ENUM will be generated by DebugMessageControlARB
    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 DebugMessageControlARB
    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 DebugMessageControlARB
    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 DebugMessageControlARB
    if <count> is less than zero.

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

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

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

    The error INVALID_VALUE will be generated by GetDebugMessageLogARB
    if <bufSize> is less than zero.
    
    The error INVALID_ENUM will be generated by DebugMessageInsertARB if
    the value of <source> is not DEBUG_SOURCE_APPLICATION_ARB or
    DEBUG_SOURCE_THIRD_PARTY_ARB.
    
    The error INVALID_ENUM will be generated by DebugMessageInsertARB if
    the value of <type> is not one of the values from Table 5.4.

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

    The error INVALID_VALUE will be generated by DebugMessageInsertARB
    if the number of characters in <buf>, excluding the null terminator
    when <length> is negative, is not less than
    MAX_DEBUG_MESSAGE_LENGTH_ARB.
    
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_ARB           Y     GetPointerv            NULL       The current debug output  5.5.2     -
                                                                                  callback function pointer

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

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

    DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB  Z+    GetIntegerv            0          The string length of the  5.5.3     -
                                                                                  oldest debug message in
                                                                                  the debug message log
                                                                                
    DEBUG_OUTPUT_SYNCHRONOUS_ARB          B     IsEnabled              FALSE      The enabled state for     5.5.6
                                                                                  synchronous debug message
                                                                                  callbacks
    
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_ARB         Z+    GetIntegerv   1        The maximum length of a     5.5.1      -
                                                                      debug message string,
                                                                      including its null
                                                                      terminator

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

Issues

    01) Should we reserve tokens for arbitrary vendor-specific
        categories (e.g. DEBUG_CATEGORY_VENDOR0)?
    
        RESOLVED:  No.  Since this is an ARB extension, there is no
                   reason to do this now in the current version.
                   

    02) Should we allow explicit controls for printing to stderr or
        through OutputDebugString instead of the callback?

        RESOLVED:  No.  It is up to the application to setup this
                   behavior itself using the provided functionality.
    

    03) How do the different filtering rules interact?  If a category is
        filtered, but a message in that same category is set to be
        unfiltered by ID or severity level, should that message still be
        filtered?  If I specifically filter a category and then unfilter
        all messages globally with a later command, should that category
        still be filtered?
    
        RESOLVED:  Message enable state is stored individually for each
                   message.  There is no explicit group-wise enable
                   state or different ordered levels of "enabledness" in
                   the implied hierarchy of messages.  Operations on
                   groups of messages affect all messages within
                   that group individually, and overwrite the previous
                   and individual state of those messages.
        
    04) Should applications be allowed to insert their own messages
        through a custom category?  How would this be done?
    
        RESOLVED:  Yes.  A new category will be provided for
                   application-specific messages and an entry point will
                   be provided to write messages  in that category.

    05) Should we provide a mechanism to ensure synchronized calls of
        the debug output callback by the implementation?
        
        RESOLVED:  Yes.  This is useful for the application to observe
                   which GL function caused a specific message to be
                   generated by observing the debugger call stack.
                   
                   It will also simplify the application's
                   responsibility for creating a thread-safe callback
                   routine at the understood price of potential reduced
                   driver performance when the debug layer is active.
                   
                   A new state
                   DEBUG_OUTPUT_SYNCHRONOUS_CALLBACK_ARB will be
                   provided that can be enabled by the application to
                   provide this functionality.
    
    06) Is it possible that multi-threaded drivers that generate
        messages asynchronously into the message log can cause a
        race condition where a message is inserted between the time
        an application queries DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB
        and the attempted fetch of the oldest message?
        
        RESOLVED:  Yes.  When the message log is full, the oldest
                   message would be bumped out by the new message which
                   would make the queried value incorrect.  A solution
                   to this is to make the message log discard messages
                   when it has filled up but otherwise preserve its
                   contents.
                   
                   A similar race condition can still occur when
                   querying DEBUG_LOGGED_MESSAGES_ARB when the message
                   log is not full.  However in this case the value at
                   the time of the fetch can only either be equal or
                   greater than at the time of the query, and neither
                   case will result in lost information.
                   
                   The synchronous callback toggle has also been
                   modified to also explicitly affect the placing of
                   messages into the message log.

Revision History

    (v17, 2013-07-08, Jon Leech)
        - Change type of userParam parameter to DebugMessageCallbackARB and
          GLDEBUGPROCARB from 'void *' to 'const void *' to match GL core
          and KHR_debug (Bug 10083).

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

    (v15, 2012-06-22, Piers Daniell)
        - Restored the ARB suffixes removed by mistake.

    (v14, 2012-06-19, Jon Leech)
        - Change logSize parameter to bufSize

    (v13, 2012-04-19, pdaniell)
        - Remove ARB suffixs to make the extension ready for OpenGL 4.3.
    
    (v12, 2010-06-01, jkontti)
        - Added DEBUG_TYPE_PORTABILITY_ARB
        - Renamed DEBUG_OUTPUT_SYNCHRONOUS_CALLBACK_ARB to
          DEBUG_OUTPUT_SYNCHRONOUS_ARB and made it explicitly affect
          not just callbacks but also messages in the message log.
        - Moved discussion abotu DEBUG_OUTPUT_SYNCHRONOUS_ARB to its
          own section 5.5.6
        - When the message log fills up, new messages will be discarded
          instead of bumping off old messages (issue 6).
        - Removed restrictions from third-party sources for
          DebugMessageControlARB
        - Removed restrictions on <type> for DebugMessageInsertARB
          
    (v11, 2010-05-28, jkontti)
        - Added DEBUG_OUTPUT_SYNCHRONOUS_CALLBACK_ARB enable state for
          applications to be guaranteed that the debug callback is not 
          called asynchronously or concurrently by the implementation
        - Created tables 6.55 and 6.56 for new introduced state and
          implementation-dependent state
        - Moved sections 2.21.x to 5.5.x
        - Moved tables 2.15 to 5.3, 2.16 to 5.4, and 2.17 to 5.5
        - Changed minimum value of MAX_DEBUG_MESSAGE_LENGTH_ARB to 1
        - Renamed DebugMessageEnableARB to DebugMessageControlARB
        - For DebugMessageControlARB, DONT_CARE will now be used as the
          enum to ignore filtered message properties instead of NONE


    (v10, 2010-05-13, jkontti)
        - Split category attribute to orthogonal source and type.  This
          requires all new tokens (currently missing).
        - Table 2.15 now refers to debug output source
        - Table 2.16 now refers to debug output type
        - New table 2.17 that now contains debug output severity
        
    (v9, 2010-05-11, jkontti)
        - Rewrote against OpenGL 4.0 Core specification: Section 2.20
          renamed to 2.21 and tables 2.12 and 2.13 are now 2.15 and 2.16
        - Added missing sections for changes to Chapters 3-6.
        - Removed explicit language about contexts created using the
          debug flag.  Instead, implementations can choose, but are
          not required to, only support this extension in contexts
          created with the debug flag.
        - Added Dependencies section to discuss behavior of the
          debug output entry points when used inside display lists.
        - Added new entry point GetPointerv since it is missing
          in core profiles.
        - Added new state DEBUG_CALLBACK_FUNCTION_ARB,
          DEBUG_CALLBACK_USER_PARAM_ARB,
          DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB (token values still
          missing).
        - Rewrote sections of GetDebugMessageLog to be clearer and
          changed some of the error generation.
        - DebugMessageInsert parameter <length> can now be negative
          which indicates that the passed-in string is null-terminated.
        - Updated contributors section
        
    (v8, 2010-05-07, jkontti)
        - Removed inconsistent language from New Tokens category for
          tokens that are no longer accepted by DebugMessageEnableARB
          since revision v5.
        - Cleaned up some language and formatting issues.
        
    (v7, 2010-01-21, jkontti)
        - Added user-specifiable parameter to debug message callback
          function.

    (v6, 2010-01-15, jkontti)
        - Updated contact section.
        - Updated contributor section.
        - Updated status section.
        - Updated enums.
        
    (v5, 2009-09-17, jkontti)
        - Message ID namespaces are now contained within categories
          instead of being in a single global namespace.
        - Reworked DebugMessageEnable to allow disabling/enabling more
          combinations of messages.
        - Resolved issue 01.
        - Resolved issue 03.
        
    (v4, 2009-09-16, jkontti)
        - Added category as a parameter to DebugMessageInsert for
          future-proofing purposes,
        - Added missing errors to DebugMessageInsert and
          GetDebugMessageLog.
        - Added missing tokens to New Tokens.
        - Renamed DebugMessageFilter to DebugMessageEnable.
        
    (v3, 2009-09-15, myoung)
        - Cleaned up some language
        - Added values using AMD reserved ranges.  Values do not overlap
          so can be re-used.

    (v2, 2009-09-15, jkontti)
        - Application-generated messages.
        - More categories (window system, deprecation, profile,
          application).
        
    (v1, 2009-09-09, jkontti)
        - Initial revision.
