KHR_debug

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

Specification Update Policy

Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL and OpenGL ES Working Groups. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
    https://www.khronos.org/registry/OpenGL/docs/update_policy.php

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.7 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.