blob: 5da20d1f522c71afb1e33023f3fbbec0047540c0 [file] [log] [blame]
Name
KHR_debug
Name Strings
GL_KHR_debug
Contact
Christophe Riccio (christophe.riccio 'at' amd.com)
Contributors
Jaakko Konttinen, AMD
Graham Sellers, AMD
Mark Young, AMD
Ahmet Oguz Akyuz, AMD
Bruce Merry, ARM
Daniel Koch, TransGaming
Jon Leech, Independent
Pat Brown, NVIDIA
Greg Roth, NVIDIA
Yaki Tebeka, Graphic Remedy
Piers Daniell, NVIDIA
Seth Sowerby, Apple
Benj Lipchak, Apple
Jean-François Roy, Apple
Daniel Rakos, AMD
Mark Callow, HI
Notice
Copyright (c) 2012-2014 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
Complete.
Approved by the ARB on 2012/06/18.
Approved by the OpenGL ES WG on 2012/06/15.
Ratified by the Khronos Board of Promoters on 2012/07/27.
Version
Last Modified Date: July 2, 2015
Author Revision: 17
Number
ARB Extension #119
OpenGL ES Extension #118
Dependencies
OpenGL 1.1 is required.
The extension is written against the OpenGL 4.2 Compatibility Profile
specification (April 27, 2012).
Overview
This extension allows the GL to notify applications when various events
occur that may be useful during application development, debugging and
profiling.
These events are represented in the form of enumerable messages with a
human-readable string representation. Examples of debug events include
incorrect use of the GL, warnings of undefined behavior, and performance
warnings.
A message is uniquely identified by a source, a type and an
implementation-dependent ID within the source and type pair.
A message's source identifies the origin of the message and can either
describe components of the GL, the window system, third-party external
sources such as external debuggers, or even the application itself.
The type of the message roughly identifies the nature of the event that
caused the message. Examples include errors, performance warnings,
warnings about undefined behavior or notifications identifying that the
application is within a specific section of the application code.
A message's ID for a given source and type further distinguishes messages
within namespaces. For example, an error caused by a negative parameter
value or an invalid internal texture format are both errors generated by
the API, but would likely have different message IDs.
Each message is also assigned to a severity level that denotes roughly how
"important" that message is in comparison to other messages across all
sources and types. For example, notification of a GL error would likely
have a higher severity than a performance warning due to redundant state
changes.
Furthermore, every message contains an implementation-dependent string
representation that provides a useful description of the event.
Messages are communicated to the application through an application-
defined callback function that is called by the GL implementation on each
debug message. The motivation for the callback routine is to free
application developers from actively having to query whether a GL error,
or any other debuggable event has happened after each call to a GL
function. With a callback, developers can keep their code free of debug
checks, set breakpoints in the callback function, and only have to react
to messages as they occur. In situations where using a callback is not
possible, a message log is also provided that stores only copies of recent
messages until they are actively queried.
To control the volume of debug output, messages can be disabled either
individually by ID, or entire sets of messages can be turned off based on
combination of source and type, through the entire application code or
only section of the code encapsulated in debug groups. A debug group may
also be used to annotate the command stream using descriptive texts.
This extension also defines debug markers, a mechanism for the OpenGL
application to annotate the command stream with markers for discrete
events.
When profiling or debugging an OpenGL application with a built-in or an
external debugger or profiler, it is difficult to relate the commands
within the command stream to the elements of the scene or parts of the
program code to which they correspond. Debug markers and debug groups help
obviate this by allowing applications to specify this link. For example, a
debug marker can be used to identify the beginning of a frame in the
command stream and a debug group can encapsulate a specific command stream
to identify a rendering pass. Debug groups also allow control of the debug
outputs volume per section of an application code providing an effective
way to handle the massive amount of debug outputs that drivers can
generate.
Some existing implementations of ARB_debug_output only expose the
ARB_debug_output extension string if the context was created with the
debug flag {GLX|WGL}_CONTEXT_DEBUG_BIT_ARB as specified in
{GLX|WGL}_ARB_create_context. The behavior is not obvious when the
functionality is brought into the OpenGL core specification because the
extension string and function entry points must always exist.
This extension modifies the existing ARB_debug_output extension to allow
implementations to always have an empty message log. The specific messages
written to the message log or callback routines are already implementation
defined, so this specification simply makes it explicit that it's fine for
there to be zero messages generated, even when a GL error occurs, which is
useful if the context is non-debug.
Debug output can be enabled and disabled by changing the DEBUG_OUTPUT
state. It is implementation defined how much debug output is generated if
the context was created without the CONTEXT_DEBUG_BIT set. This is a new
query bit added to the existing GL_CONTEXT_FLAGS state to specify whether
the context was created with debug enabled.
Finally, this extension defines a mechanism for OpenGL applications to
label their objects (textures, buffers, shaders, etc.) with a descriptive
string.
When profiling or debugging an OpenGL application within an external or
built-in (debut output API) debugger or profiler it is difficult to
identify objects from their object names (integers).
Even when the object itself is viewed it can be problematic to
differentiate between similar objects. Attaching a descriptive string, a
label, to an object obviates this difficulty.
The intended purpose of this extension is purely to improve the user
experience within OpenGL development tools and application built-in
profilers and debuggers. This extension typically improves OpenGL
programmers efficiency by allowing them to instantly detect issues and the
reason for these issues giving him more time to focus on adding new
features to an OpenGL application.
IP Status
No known IP claims.
New Procedures and Functions
NOTE: when implemented in an OpenGL ES context, all entry points defined
by this extension must have a "KHR" suffix. When implemented in an
OpenGL context, all entry points must have NO suffix, as shown below.
void DebugMessageControl(enum source,
enum type,
enum severity,
sizei count,
const uint* ids,
boolean enabled);
void DebugMessageInsert(enum source,
enum type,
uint id,
enum severity,
sizei length,
const char* buf);
void DebugMessageCallback(DEBUGPROC callback,
const void* userParam);
uint GetDebugMessageLog(uint count,
sizei bufSize,
enum* sources,
enum* types,
uint* ids,
enum* severities,
sizei* lengths,
char* messageLog);
void GetPointerv(enum pname,
void** params);
void PushDebugGroup(enum source, uint id, sizei length,
const char * message);
void PopDebugGroup(void);
void ObjectLabel(enum identifier, uint name, sizei length,
const char *label);
void GetObjectLabel(enum identifier, uint name, sizei bufSize,
sizei *length, char *label);
void ObjectPtrLabel(void* ptr, sizei length,
const char *label);
void GetObjectPtrLabel(void* ptr, sizei bufSize,
sizei *length, char *label);
New Types
NOTE: when implemented in an OpenGL ES context, this typedef must have a
"KHR" suffix (GLDEBUGPROCKHR). When implemented in an OpenGL context,
thie typedef must have NO suffix, as shown below.
The callback function that applications can define, and
is accepted by DebugMessageCallback, is defined as:
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam);
Note that this function pointer is defined as having the same calling
convention as the GL functions.
New Tokens
NOTE: when implemented in an OpenGL ES context, all tokens defined by
this extension must have a "_KHR" suffix. When implemented in an OpenGL
context, all tokens must have NO suffix, as described below.
Tokens accepted by the <target> parameters of Enable, Disable, and
IsEnabled:
DEBUG_OUTPUT 0x92E0
DEBUG_OUTPUT_SYNCHRONOUS 0x8242
Returned by GetIntegerv when <pname> is CONTEXT_FLAGS:
CONTEXT_FLAG_DEBUG_BIT 0x00000002
Tokens accepted by the <value> parameters of GetBooleanv, GetIntegerv,
GetFloatv, GetDoublev and GetInteger64v:
MAX_DEBUG_MESSAGE_LENGTH 0x9143
MAX_DEBUG_LOGGED_MESSAGES 0x9144
DEBUG_LOGGED_MESSAGES 0x9145
DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
DEBUG_GROUP_STACK_DEPTH 0x826D
MAX_LABEL_LENGTH 0x82E8
Tokens accepted by the <pname> parameter of GetPointerv:
DEBUG_CALLBACK_FUNCTION 0x8244
DEBUG_CALLBACK_USER_PARAM 0x8245
Tokens accepted or provided by the <source> parameters of
DebugMessageControl, DebugMessageInsert and DEBUGPROC, and the <sources>
parameter of GetDebugMessageLog (some commands restrict <source> to a
subset of these parameters; see the specification body for details):
DEBUG_SOURCE_API 0x8246
DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
DEBUG_SOURCE_SHADER_COMPILER 0x8248
DEBUG_SOURCE_THIRD_PARTY 0x8249
DEBUG_SOURCE_APPLICATION 0x824A
DEBUG_SOURCE_OTHER 0x824B
Tokens accepted or provided by the <type> parameters of
DebugMessageControl, DebugMessageInsert and DEBUGPROC, and the <types>
parameter of GetDebugMessageLog:
DEBUG_TYPE_ERROR 0x824C
DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
DEBUG_TYPE_PORTABILITY 0x824F
DEBUG_TYPE_PERFORMANCE 0x8250
DEBUG_TYPE_OTHER 0x8251
DEBUG_TYPE_MARKER 0x8268
Tokens accepted or provided by the <type> parameters of
DebugMessageControl and DEBUGPROC, and the <types> parameter of
GetDebugMessageLog:
DEBUG_TYPE_PUSH_GROUP 0x8269
DEBUG_TYPE_POP_GROUP 0x826A
Tokens accepted or provided by the <severity> parameters of
DebugMessageControl, DebugMessageInsert and DEBUGPROC callback functions,
and the <severities> parameter of GetDebugMessageLog:
DEBUG_SEVERITY_HIGH 0x9146
DEBUG_SEVERITY_MEDIUM 0x9147
DEBUG_SEVERITY_LOW 0x9148
DEBUG_SEVERITY_NOTIFICATION 0x826B
Returned by GetError:
STACK_UNDERFLOW 0x0504
STACK_OVERFLOW 0x0503
Tokens accepted or provided by the <identifier> parameters of
ObjectLabel and GetObjectLabel:
BUFFER 0x82E0
SHADER 0x82E1
PROGRAM 0x82E2
VERTEX_ARRAY
QUERY 0x82E3
PROGRAM_PIPELINE 0x82E4
TRANSFORM_FEEDBACK
SAMPLER 0x82E6
TEXTURE
RENDERBUFFER
FRAMEBUFFER
[[ Compatibility Profile ]]
DISPLAY_LIST 0x82E7
[[ End Profile-Specific Language ]]
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, GetDoublev, and GetInteger64v:
MAX_LABEL_LENGTH
Additions to Chapter 2 of the OpenGL 4.2 Specification
(OpenGL Operation)
In section 2.5 - GL Errors:
Add to the end of the section (pg 19):
"When an error is generated, the GL will also generate a debug output
message describing its cause (see section 5.5). The message has the
source DEBUG_SOURCE_API and the type DEBUG_TYPE_ERROR, and an
implementation-dependent ID."
Additions to Chapter 3 of the OpenGL 4.2 Specification
(Rasterization)
None.
Additions to Chapter 4 of the OpenGL 4.2 Specification
(Per-Fragment Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 4.2 Specification
(Special Functions)
After section 5.4 - Hints (pg. 300) (section 5.3, p 217 in OpenGL ES 3.0),
add new section:
"5.5 - Debug Output
Application developers can obtain more information from the GL runtime in
the form of debug output. This information can include details about GL
errors, undefined behavior, implementation-dependent performance warnings,
or other useful hints.
This information is communicated through a stream of debug messages that
are generated as GL commands are executed. The application can choose to
receive these messages either through a callback routine, or by querying
for them from a message log.
Controls are provided for disabling messages that the application does not
care about, and for inserting application-generated messages into the
stream.
The GL may provide different levels of debug output depending on how the
context was created. If the context was created without the
CONTEXT_FLAG_DEBUG_BIT in the CONTEXT_FLAGS state, as described in Section
6.1.12, then the GL may optionally not generate any debug messages, but
the functions described below will otherwise operate without error.
Debug output functionality is controlled with the DEBUG_OUTPUT enable
state. If the context is created with the CONTEXT_FLAG_DEBUG_BIT set then
the initial state of DEBUG_OUTPUT is TRUE, otherwise the initial state of
DEBUG_OUTPUT is FALSE. In a debug context, if DEBUG_OUTPUT is disabled the
GL will not generate any debug output logs or callbacks. Enabling
DEBUG_OUTPUT again will enable full debug output functionality. If the
context was created without the CONTEXT_FLAG_DEBUG_BIT and the
DEBUG_OUTPUT is later enabled, the level of debug output logging is
defined by the GL implementation, which may have zero debug output. To
guarantee the full debug output support of the GL implementation the
context should be created with CONTEXT_FLAG_DEBUG_BIT context flag bit
set.
5.5.1 - Debug Messages
A debug message is uniquely identified by the source that generated it, a
type within that source, and an unsigned integer ID identifying the
message within that type. The message source is one of the symbolic
constants listed in Table 5.3. The message type is one of the symbolic
constants listed in Table 5.4.
Debug Output Message Source Messages Generated by
--------------------------- ---------------------
DEBUG_SOURCE_API The GL
DEBUG_SOURCE_SHADER_COMPILER The GLSL shader compiler or compilers for
other extension-provided languages
DEBUG_SOURCE_WINDOW_SYSTEM The window system, such as WGL or GLX
DEBUG_SOURCE_THIRD_PARTY External debuggers or third-party middleware
libraries
DEBUG_SOURCE_APPLICATION The application
DEBUG_SOURCE_OTHER Sources that do not fit to any of the ones listed above
----------------------------------------------------------------------------
Table 5.3: Sources of debug output messages. Each message must originate
from a source listed in this table.
Debug Output Message Type Informs about
------------------------- -------------
DEBUG_TYPE_ERROR Events that generated an error
DEBUG_TYPE_DEPRECATED_BEHAVIOR Behavior that has been marked for
deprecation
DEBUG_TYPE_UNDEFINED_BEHAVIOR Behavior that is undefined according to
the specification
DEBUG_TYPE_PERFORMANCE Implementation-dependent performance
warnings
DEBUG_TYPE_PORTABILITY Use of extensions or shaders in a way that
is highly vendor-specific
DEBUG_TYPE_OTHER Types of events that do not fit any of
the ones listed above
DEBUG_TYPE_MARKER Annotation of the command stream
DEBUG_TYPE_PUSH_GROUP Entering a debug group
DEBUG_TYPE_POP_GROUP Leaving a debug group
----------------------------------------------------------------------------
Table 5.4: Types of debug output messages. Each message is associated with
one of these types that describes the nature of the message.
Each message source and type pair contains its own namespace of messages
with every message being associated with an ID. The assignment of IDs to
messages within a namespace is implementation-dependent. There can
potentially be overlap between the namespaces of two different pairs of
source and type, so messages can only be uniquely distinguished from each
other by the full combination of source, type and ID.
Each message is also assigned a severity level that roughly describes its
importance across all sources and types along a single global axis. The
severity of a message is one of the symbolic constants defined in
Table 5.5. Because messages can be disabled by their severity, this allows
for quick control the global volume of debug output.
Severity Level Token Suggested examples of messages
-------------------- ------------------------------
DEBUG_SEVERITY_HIGH Any GL error; dangerous undefined behavior;
any GLSL or ARB shader compiler and
linker errors;
DEBUG_SEVERITY_MEDIUM Severe performance warnings; GLSL
or other shader compiler and linker
warnings; use of currently deprecated
behavior
DEBUG_SEVERITY_LOW Performance warnings from redundant
state changes; trivial undefined behavior
DEBUG_SEVERITY_NOTIFICATION Any message which is not an
error or performance concern
----------------------------------------------------------------------------
Table 5.5: Severity levels of messages. Each debug output message is
associated with one of these severity levels.
Every message also has a null-terminated string representation that is
used to describe the message. The contents of the string can change
slightly between different instances of the same message (e.g. which
parameter value caused a specific GL error to occur). The format of a
message string is left as implementation-dependent, although it should at
least represent a concise description of the event that caused the message
to be generated. Messages with different IDs should also have
sufficiently distinguishable string representations to warrant their
separation.
The lengths of all messages, including their null terminators, must be
guaranteed to be less or equal to the value of the
implementation-dependent constant MAX_DEBUG_MESSAGE_LENGTH.
Messages can be either enabled or disabled. Messages that are disabled
will not be generated. All messages are initially enabled unless their
assigned severity is DEBUG_SEVERITY_LOW. The enabled state of messages can
be changed using the command DebugMessageControl.
5.5.2 - Debug Message Callback
Applications can provide a callback function for receiving debug messages
using the command
void DebugMessageCallback(DEBUGPROC callback,
const void* userParam);
with <callback> storing the address of the callback function. This
function's prototype must follow the type definition of DEBUGPROC
including its platform-dependent calling convention. Anything else will
result in undefined behavior. Only one debug callback can be specified
for the current context, and further calls overwrite the previous
callback. Specifying NULL as the value of <callback> clears the current
callback and disables message output through callbacks. Applications can
provide user-specified data through the pointer <userParam>. The context
will store this pointer and will include it as one of the parameters in
each call to the callback function.
If the application has specified a callback function for receiving debug
output, the implementation will call that function whenever any enabled
message is generated. The source, type, ID, and severity of the message
are specified by the DEBUGPROC parameters <source>, <type>, <id>, and
<severity>, respectively. The string representation of the message is
stored in <message> and its length (excluding the null-terminator) is
stored in <length>. The parameter <userParam> is the user-specified
parameter that was given when calling DebugMessageCallback.
Applications can query the current callback function and the current
user-specified parameter by obtaining the values of
DEBUG_CALLBACK_FUNCTION and DEBUG_CALLBACK_USER_PARAM, respectively.
Applications that specify a callback function must be aware of certain
special conditions when executing code inside a callback when it is
called by the GL, regardless of the debug source.
The memory for <message> is owned and managed by the GL, and should
only be considered valid for the duration of the function call.
The behavior of calling any GL or window system function from within the
callback function is undefined and may lead to program termination.
Care must also be taken in securing debug callbacks for use with
asynchronous debug output by multi-threaded GL implementations.
Section 5.5.6 describes this in further detail.
If the DEBUG_OUTPUT state is disabled then the GL will not call the
callback function.
5.5.3 - Debug Message Log
If DEBUG_CALLBACK_FUNCTION is NULL, then debug messages are instead
stored in an internal message log up to some maximum number of messages
as defined by the value of MAX_DEBUG_LOGGED_MESSAGES.
Each context stores its own message log and will only store messages
generated by commands operating in that context. If the message log
fills up, then any subsequently generated messages will not be
placed in the log until the message log is cleared, and will instead
be discarded.
Applications can query the number of messages currently in the log by
obtaining the value of DEBUG_LOGGED_MESSAGES, and the string length
(including its null terminator) of the oldest message in the log through
the value of DEBUG_NEXT_LOGGED_MESSAGE_LENGTH.
To fetch message data stored in the log, the command GetDebugMessageLog
can be used as described in section 6.1.15.
If DEBUG_CALLBACK_FUNCTION is not NULL, no generated messages will be
stored in the log but will instead be passed to the debug callback routine
as described in section 5.5.2.
If the DEBUG_OUTPUT state is disabled then no messages are added to the
message log.
5.5.4 - Controlling Debug Messages
Applications can control the volume of debug output in the active debug
group, by disabling specific or groups of messages with the command:
void DebugMessageControl(enum source,
enum type,
enum severity,
sizei count,
const uint* ids,
boolean enabled);
If <enabled> is TRUE, the referenced subset of messages will be enabled.
If FALSE, then those messages will be disabled.
This command can reference different subsets of messages by first
considering the set of all messages, and filtering out messages based on
the following ways:
- If <source>, <type>, or <severity> is DONT_CARE, the messages from
all sources, of all types, or of all severities are referenced
respectively.
- When values other than DONT_CARE are specified, all messages whose
source, type, or severity match the specified <source>, <type>, or
<severity> respectively will be referenced.
- If <count> is greater than zero, then <ids> is an array of <count>
message IDs for the specified combination of <source> and <type>. In
this case, if <source> or <type> is DONT_CARE, or <severity> is not
DONT_CARE, the error INVALID_OPERATION is generated.
Unrecognized message IDs in <ids> are ignored. If <count> is zero,
the value if <ids> is ignored.
In addition, if any of <source>, <type>, and <severity> is not DONT_CARE
and is not one of the symbols from, respectively, Table 5.3, Table 5.4,
and Table 5.5, the error INVALID_ENUM is generated. If <count> is
negative, the error INVALID_VALUE is generated.
Although messages are grouped into an implicit hierarchy by their
sources and types, there is no explicit per-source, per-type or
per-severity enabled state. Instead, the enabled state is stored
individually for each message. There is no difference between disabling
all messages from one source in a single call, and individually
disabling all messages from that source using their types and IDs.
If the DEBUG_OUTPUT state is disabled the GL operates the same as
if messages of every <source>, <type> or <severity> are disabled.
5.5.5 - Externally Generated Messages
To support applications and third-party libraries generating their own
messages, such as ones containing timestamp information or signals about
specific render system events, the following function can be called
void DebugMessageInsert(enum source,
enum type,
uint id,
enum severity,
int length,
const char* buf);
The value of <id> specifies the ID for the message and <severity>
indicates its severity level as defined by the caller. If <severity> is
not one of the severity levels listed in Table 5.5, the error
INVALID_ENUM will be generated. The value of <type> must be one of the
values from Table 5.4 and the value of <source> must be either
DEBUG_SOURCE_APPLICATION or DEBUG_SOURCE_THIRD_PARTY, or the error
INVALID_ENUM will be generated. The string <buf> contains the string
representation of the message. The parameter <length> contains the number
of characters in <buf>. If <length> is negative, it is implied that <buf>
contains a null terminated string. The error INVALID_VALUE will be
generated if the number of characters in <buf>, excluding the null
terminator when <length> is negative, is not less than the value of
MAX_DEBUG_MESSAGE_LENGTH.
If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are
discarded and do not generate an error.
5.5.6 - Debug Groups
Debug groups provide a method for annotating a command stream with
discrete groups of commands using a descriptive text. Debug output
messages, either generated by the implementation or inserted by the
application with DebugMessageInsert are written to the active debug group,
the top of the debug group stack. Debug groups are strictly hierarchical.
Their sequences may be nested within other debug groups but can not
overlap. If no debug group has been pushed by the application then the
active debug group is the default debug group.
The command
void PushDebugGroup(enum source, uint id, sizei length,
const char *message);
pushes a debug group described by the string <message> into the command
stream. The value of <id> specifies the ID of messages generated. The
parameter <length> contains the number of characters in <message>. If
<length> is negative, it is implied that <message> contains a null
terminated string. The message has the specified <source> and <id>, <type>
DEBUG_TYPE_PUSH_GROUP, and <severity> DEBUG_SEVERITY_NOTIFICATION. The GL
will put a new debug group on top of the debug group stack which inherits
the control of the volume of debug output of the debug group previously
residing on the top of the debug group stack. Because debug groups are
strictly hierarchical, any additional control of the debug output volume
will only apply within the active debug group and the debug groups pushed
on top of the active debug group.
An INVALID_ENUM error is generated if the value of <source> is neither
DEBUG_SOURCE_APPLICATION nor DEBUG_SOURCE_THIRD_PARTY. An INVALID_VALUE
error is generated if <length> is negative and the number of characters in
<message>, excluding the null-terminator, is not less than the value of
MAX_DEBUG_MESSAGE_LENGTH.
The command
void PopDebugGroup();
pops the active debug group. When a debug group is popped, the GL
will also generate a debug output message describing its cause based
on the <message> string, the source <source>, and an ID <id> submitted
to the associated PushDebugGroup command. DEBUG_TYPE_PUSH_GROUP
and DEBUG_TYPE_POP_GROUP share a single namespace for message <id>.
<severity> has the value DEBUG_SEVERITY_NOTIFICATION. The <type>
has the value DEBUG_TYPE_POP_GROUP. Popping a debug group restores
the debug output volume control of the parent debug group.
Attempting to pop the default debug group off the stack generates a
STACK_UNDERFLOW error; pushing a debug group onto a stack containing
MAX_DEBUG_GROUP_STACK_DEPTH minus one elements will generate a
STACK_OVERFLOW error.
5.5.7 - Asynchronous and Synchronous Debug Output
The behavior of how and when the GL driver is allowed to generate debug
messages, and subsequently either call back to the application or place
the message in the debug message log, is affected by the state
DEBUG_OUTPUT_SYNCHRONOUS. This state can be modified by the Enable and
Disable commands. Its initial value is FALSE.
When DEBUG_OUTPUT_SYNCHRONOUS is disabled, the driver is optionally
allowed to concurrently call the debug callback routine from
potentially multiple threads, including threads that the context that
generated the message is not currently bound to. The implementation may
also call the callback routine asynchronously after the GL command that
generated the message has already returned. The application is fully
responsible for ensuring thread safety due to debug callbacks under
these circumstances. In this situation the <userParam> value may be
helpful in identifying which application thread's command originally
generated the debug callback.
When DEBUG_OUTPUT_SYNCHRONOUS is enabled, the driver guarantees
synchronous calls to the callback routine by the context. When synchronous
callbacks are enabled, all calls to the callback routine will be made by
the thread that owns the current context; all such calls will be made
serially by the current context; and each call will be made before the GL
command that generated the debug message is allowed to return.
When no callback is specified and DEBUG_OUTPUT_SYNCHRONOUS is disabled,
the driver can still asynchronously place messages in the debug message
log, even after the context thread has returned from the GL function that
generated those messages. When DEBUG_OUTPUT_SYNCHRONOUS is enabled, the
driver guarantees that all messages are added to the log before the GL
function returns.
Enabling synchronous debug output greatly simplifies the responsibilities
of the application for making its callback functions thread-safe, but may
potentially result in drastically reduced driver performance.
DEBUG_OUTPUT_SYNCHRONOUS only guarantees intra-context synchronization for
the callbacks of messages generated by that context, and does not
guarantee synchronization across multiple contexts. If multiple contexts
are concurrently used by the application, it is allowed for those contexts
to also concurrently call their designated callbacks, and the application
is responsible for handling thread safety in that situation even if
DEBUG_OUTPUT_SYNCHRONOUS is enabled in all contexts."
5.5.8 Debug Labels:
Debug labels provide a method for annotating any object (texture, buffer,
shader, etc.) with a descriptive text label. These labels may then be used
by the debug output (see section 5.5) or an external tool such as a
debugger or profiler to describe labelled objects.
The command
void ObjectLabel(enum identifier, uint name, sizei length, const char *label);
labels the object identified by <name> and its namespace <identifier>.
<identifier> must be one of the tokens in table 5.1, indicating the type
of the object corresponding to <name>.
Identifier Object Type
---------------------------------------
BUFFER | buffer
SHADER | shader
PROGRAM | program
VERTEX_ARRAY | vertex array
QUERY | query
PROGRAM_PIPELINE | program pipeline
TRANSFORM_FEEDBACK| transform feedback
SAMPLER | sampler
TEXTURE | texture
RENDERBUFFER | render buffer
FRAMEBUFFER | frame buffer
[[ Compatibility Profile Only]]
DISPLAY_LIST | display list
[[ End Profile-Specific Language ]]
---------------------------------------
Table 5.1. Valid object namespace identifiers and the corresponding
object type.
The command
void ObjectPtrLabel(void* ptr, sizei length, const char *label);
labels a sync object identified by <ptr>.
<label> contains a string used to label an object. <length> contains the
number of characters in <label>. If <length> is negative, it is implied that
<label> contains a null-terminated string. If <label> is NULL, any debug
label is effectively removed from the object.
An INVALID_ENUM error is generated by ObjectLabel if <identifier> is not
one of the object types listed in table 5.1.
An INVALID_VALUE error is generated by ObjectLabel if <name> is not
the name of a valid object of the type specified by <identifier>.
An INVALID_VALUE is generated if the <ptr> parameter of ObjectPtrLabel
is not the name of a sync object.
An INVALID_VALUE error is generated if the number of characters in
<label>, excluding the null terminator when <length> is negative, is not
less than the value of MAX_LABEL_LENGTH.
A label is part of the state of the object to which it is associated.
The initial state of an object's label is the empty string. Labels need
not be unique.
Additions to Chapter 6 of the OpenGL 4.2 Specification
(State and State Requests)
Modify the title of Section 6.1.6 - String Queries to read
"Section 6.1.6 - Pointer and String Queries", and insert to the
beginning of the section:
The command
void GetPointerv(enum pname, void** params);
obtains the pointer or pointers named <pname> in the array <params>.
The possible values for <pname> are DEBUG_CALLBACK_FUNCTION and
DEBUG_CALLBACK_USER_PARAM, which respectively return the current
debug output callback function pointer and its application-specified
user parameter. Each <pname> returns a single pointer value.
Modify Section 6.1.12 "Pointer and String Queries"
Add to the paragraph describing the context profile mask and flags
(preceding the description of GetStringi) on page 485:
"If CONTEXT_FLAG_DEBUG_BIT is set in CONTEXT_FLAGS, then the DEBUG_OUTPUT
state, as described in section 5.5, will be enabled by default."
After Section 6.1.14 - Renderbuffer Object Queries (pg 324):
Add new Section 6.1.15 - Debug Object Queries:
6.1.15 - Debug Output Queries
When no debug callback is set, debug messages are stored in
a debug message log as described in section 5.5.3. Messages can
be queried from the log by calling
uint GetDebugMessageLog(uint count,
sizei bufSize,
enum* sources,
enum* types,
uint* ids,
enum* severities,
sizei* lengths,
char* messageLog);
This function fetches a maximum of <count> messages from the message
log, and will return the number of messages successfully fetched.
Messages will be fetched from the log in order of oldest to
newest. Those messages that were fetched will be removed from the
log.
The sources, types, severities, IDs, and string lengths of
fetched messages will be stored in the application-provided arrays
<sources>, <types>, <severities>, <ids>, and <lengths>,
respectively. The application is responsible for allocating enough
space for each array to hold up to <count> elements. The string
representations of all fetched messages are stored in the
<messageLog> array. If multiple messages are fetched, their strings
are concatenated into the same <messageLog> array and will be
separated by single null terminators. The last string in the array
will also be null-terminated. The maximum size of <messageLog>,
including the space used by all null terminators, is given by
<bufSize>. If <bufSize> is less than zero and <messageLog> is not
NULL, an INVALID_VALUE error will be generated. If a message's
string, including its null terminator, can not fully fit within the
<messageLog> array's remaining space, then that message and any
subsequent messages will not be fetched and will remain in the log.
The string lengths stored in the array <lengths> include the space
for the null terminator of each string.
Any or all of the arrays <sources>, <types>, <ids>, <severities>,
<lengths> and <messageLog> can also be null pointers, which causes
the attributes for such arrays to be discarded when messages
are fetched, however those messages will still be removed from the
log. Thus to simply delete up to <count> messages from the message
log while ignoring their attributes, the application can call the
function with null pointers for all attribute arrays.
If the context was created without the CONTEXT_FLAG_DEBUG_BIT in the
CONTEXT_FLAGS state, as described in Section 6.1.12, then the GL can opt
to never add messages to the message log so GetDebugMessageLog will
always return zero.
Add new Section 6.1.16 - Debug Label Queries:
6.1.16 - Debug Label Queries
The command
void GetObjectLabel(enum identifier, uint name, sizei bufSize,
sizei *length, char *label);
void GetObjectPtrLabel(void* ptr, sizei bufSize,
sizei *length, char *label);
returns in <label> the string labelling an object. <label> will be
null-terminated. The actual number of characters written into <label>,
excluding the null terminator, is returned in <length>. If <length> is
NULL, no length is returned. The maximum number of characters that may
be written into <label>, including the null terminator, is specified by
<bufSize>. If no debug label was specified for the object then <label>
will contain a null-terminated empty string, and zero will be returned
in <length>. If <label> is NULL and <length> is non-NULL then no string
will be returned and the length of the label will be returned in
<length>.
An INVALID_ENUM error is generated by GetObjectLabel if identifier is not
one of the object types listed in table 5.1 except SYNC.
An INVALID_VALUE error is generated by GetObjectLabel if <name> is not
the name of a valid object of the type specified by <identifier>.
Additions to the OpenGL / GLX / GLX Protocol Specifications
None.
Additions to the WGL Specification
None.
Interactions with OpenGL ES
This extension specification uses non-suffixed names for new entry
points, types, and tokens. This is correct for implementations against
OpenGL. However, when implemented in an OpenGL ES context, all new entry
points, types, and tokens are given KHR suffixes.
In OpenGL ES versions prior to and including ES 3.1 there is no
CONTEXT_FLAGS state and therefore the CONTEXT_FLAG_DEBUG_BIT cannot be
queried. GLES contexts must act as if this state existed as described
in this specification even if the state itself is not visible to
applications. For example, DEBUG_OUTPUT must still be enabled by default
if the context was created with debug enabled.
Interactions with GLX_ARB_create_context_robustness
If the GLX window-system binding API is used to create a context,
the GLX_ARB_create_context extension is supported, and the bit
GLX_CONTEXT_DEBUG_BIT_ARB is set in GLX_CONTEXT_FLAGS when
glXCreateContextAttribsARB is called, the resulting context will
have debug enabled, and the CONTEXT_FLAG_DEBUG_BIT bit will be set
in CONTEXT_FLAGS as described above in section 6.1.12.
Interactions with WGL_ARB_create_context_robustness
If the WGL window-system binding API is used to create a context,
the WGL_ARB_create_context extension is supported, and the bit
WGL_CONTEXT_DEBUG_BIT_ARB is set in WGL_CONTEXT_FLAGS when
wglCreateContextAttribsARB is called, the resulting context will
have debug enabled, and the CONTEXT_FLAG_DEBUG_BIT bit will be set
in CONTEXT_FLAGS as described above in section 6.1.12.
Dependencies on GL and ES profiles, versions, and other extensions
Dependencies on OpenGL 4.2 Compatibility specification and any other
versions or extensions that already provide the GetPointerv entry
point as provided by the OpenGL 4.2 Compatibility specification
- Remove the modifications to Section 6.1.6 from this
specification with the exception that GetPointerv will still
accept DEBUG_CALLBACK_FUNCTION and
DEBUG_CALLBACK_USER_PARAM as valid values for <pname>,
and will return the same values as described in Chapter 6.
Dependencies on OpenGL 4.2 Compatibility specification and any other
versions that support display lists
- DebugMessageControl, DebugMessageInsert,
DebugMessageCallback, and GetDebugMessageLog are
not compiled into display lists.
Add the following to section 5.5.1 of the OpenGL 4.0
Compatibility specification, after the paragraph beginning
with "GL command stream management" (pg 414):
"Debug output: DebugMessageControl,
DebugMessageInsert, DebugMessageCallback, and
GetDebugMessageLog"
Add the same language to corresponding sections of other
specifications.
Dependencies on program pipeline objects
If program pipeline objects are not supported, remove PROGRAM_PIPELINE
from table 5.1.
Program pipeline objects are supported starting with OpenGL 4.2 and
OpenGL ES 3.1. They are also supported if the OpenGL
GL_ARB_separate_shader_objects or OpenGL ES
GL_EXT_separate_shader_objects extensions are supported.
Errors
The error INVALID_ENUM will be generated by DebugMessageControl
if <source> is not DONT_CARE or one of the debug output sources
listed in Table 5.3.
The error INVALID_ENUM will be generated by DebugMessageControl
if <type> is not DONT_CARE or one of the debug output types listed
in Table 5.4.
The error INVALID_ENUM will be generated by DebugMessageControl
if <severity> is not DONT_CARE or one of the severity levels listed
in Table 5.5.
The error INVALID_VALUE will be generated by DebugMessageControl
if <count> is less than zero.
The error INVALID_OPERATION will be generated by
DebugMessageControl when <count> is greater than zero and
<source> is DONT_CARE.
The error INVALID_OPERATION will be generated by
DebugMessageControl when <count> is greater than zero and
<type> is DONT_CARE.
The error INVALID_OPERATION will be generated by
DebugMessageControl when <count> is greater than zero and
and <severity> is not DONT_CARE.
The error INVALID_VALUE will be generated by GetDebugMessageLog
if the value of <count> is less than zero.
The error INVALID_VALUE will be generated by GetDebugMessageLog
if <bufSize> is less than zero.
The error INVALID_ENUM will be generated by DebugMessageInsert if
the value of <source> is not DEBUG_SOURCE_APPLICATION or
DEBUG_SOURCE_THIRD_PARTY.
The error INVALID_ENUM will be generated by DebugMessageInsert if
the value of <type> is not one of the values from Table 5.4.
The error INVALID_ENUM will be generated by DebugMessageInsert if
<severity> is not a valid debug severity level listed in Table 5.5.
The error INVALID_VALUE will be generated by DebugMessageInsert
if the number of characters in <buf>, excluding the null terminator
when <length> is negative, is not less than
MAX_DEBUG_MESSAGE_LENGTH.
The error INVALID_ENUM will be generated by PushDebugGroup
if <source> is not DEBUG_SOURCE_APPLICATION or
DEBUG_SOURCE_THIRD_PARTY.
The error INVALID_VALUE will be generated by PushDebugGroup
if <length> is negative and the number of characters in <message>,
excluding the null-terminator, is not less than the value of
MAX_DEBUG_MESSAGE_LENGTH.
The <source> value of PushDebugGroup must be either
DEBUG_SOURCE_APPLICATION or DEBUG_SOURCE_THIRD_PARTY, or the
error INVALID_ENUM will be generated.
Popping a group off the stack with no entry generates the error
STACK_UNDERFLOW; pushing a debug group onto a full stack generates
the error STACK_OVERFLOW.
An INVALID_VALUE error is generated by ObjectLabel and
GetObjectLabel if <name> is not the name of a valid object of the type
specified by <identifier>.
An INVALID_VALUE error is generated by ObjectPtrLabel and
GetObjectPtrLabel if <ptr> is not the name of a sync object.
An INVALID_VALUE error is generated by ObjectLabel if the number of
characters in <label>, excluding the null terminator when <length> is
negative, is not less than MAX_LABEL_LENGTH.
An INVALID_ENUM error is generated by ObjectLabel and GetObjectLabel if
<identifier> is not one of the object namespace tokens in table 5.1.
New State
Add new table 6.55 after p.376 (Debug Output):
Initial
Get Value Type Get Command Value Description Sec Attribute
-------------------------- ---- ----------- ------- ------------------------- ------ ---------
DEBUG_CALLBACK_FUNCTION Y GetPointerv NULL The current debug output 5.5.2 -
callback function pointer
DEBUG_CALLBACK_USER_PARAM Y GetPointerv NULL The current debug output 5.5.2 -
callback user parameter
DEBUG_LOGGED_MESSAGES Z+ GetIntegerv 0 The number of messages 5.5.3 -
currently in the debug
message log
DEBUG_NEXT_LOGGED_MESSAGE_LENGTH Z+ GetIntegerv 0 The string length of the 5.5.3 -
oldest debug message in
the debug message log
DEBUG_GROUP_STACK_DEPTH Z+ GetIntegerv 1 Debug group stack 5.5.6 -
pointer
DEBUG_OUTPUT_SYNCHRONOUS B IsEnabled FALSE The enabled state for 5.5.7 -
synchronous debug message
callbacks
DEBUG_OUTPUT B IsEnabled Depends on The enabled state for 5.5 -
the context* debug output
functionality
* Contexts created with the CONTEXT_DEBUG_BIT bit set, as defined in
GLX_ARB_create_context and WGL_ARB_create_context control the initial
value of this state. If CONTEXT_DEBUG_BIT is set then the initial
value of DEBUG_OUTPUT is TRUE otherwise its FALSE.
Add the following to Table 6.14 Buffer Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.24 Textures (state per texture object):
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.44 Shader Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.46 Program Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.36 Renderbuffer (state per renderbuffer object):
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.33 Framebuffer (state per framebuffer object):
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.9 Vertex Array Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.54 Query Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.45 Program Pipeline Object State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.26 Textures (state per sampler object):
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.56 Transform Feedback State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- -------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
Add the following to Table 6.57 Sync (state per sync object):
Initial
Get Value Type Get Command Value Description Sec
--------- ---- ----------------- ------- ----------- ---
- S GetObjectPtrLabel empty Debug label 6.2
[[ Compatibility Profile ]]
Add Table 6.60 Display List State:
Initial
Get Value Type Get Command Value Description Sec
--------- ---- ----------------- ------- ----------- ---
- S GetObjectLabel empty Debug label 6.2
[[ End Profile-Specific Language ]]
New Implementation Dependent State
Add new table 6.56 after table 6.55 (Implementation Dependent Debug Output Values):
Minimum
Get Value Type Get Command Value Description Sec Attribute
-------------------------------- -- ----------- ----- ------------------------- ------ ---------
MAX_DEBUG_MESSAGE_LENGTH Z+ GetIntegerv 1 The maximum length of a 5.5.1 -
debug message string,
including its null
terminator
MAX_DEBUG_LOGGED_MESSAGES Z+ GetIntegerv 1 The maximum number of 5.5.3 -
messages stored in the
debug message log
MAX_DEBUG_GROUP_STACK_DEPTH Z+ GetIntegerv 64 Maximum group 5.5.6 -
stack depth
MAX_LABEL_LENGTH Z+ GetIntegerv 256 Max length of a label 5.5.8 -
string
Usage Examples
Scenario 1: skip a section of the code
// Setup of the default active debug group: Filter everything in
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
// Generate a debug marker debug output message
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_MARKER, 100,
GL_DEBUG_SEVERITY_NOTIFICATION,
-1, "Message 1");
// Push debug group 1
glPushDebugGroup(
GL_DEBUG_SOURCE_APPLICATION,
1,
-1, "Message 2");
// Setup of the debug group 1: Filter everything out
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
// This message won't appear in the debug output log of
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_MARKER, 100,
GL_DEBUG_SEVERITY_NOTIFICATION,
-1, "Message 3");
// Pop debug group 1, restore the volume control of the default debug group.
glPopDebugGroup();
// Generate a debug marker debug output message
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_MARKER, 100,
GL_DEBUG_SEVERITY_NOTIFICATION,
-1, "Message 5");
// Expected debug output from the GL implementation
// Message 1
// Message 2
// Message 2
// Message 5
Scenario 2: Only output a subsection of the code
and disable some messages for the entire application
// Setup the control of de debug output for the default debug group
glDebugMessageControl(
GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
glDebugMessageControl(
GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE);
std::vector<GLuint> Messages = {1234, 2345, 3456, 4567};
glDebugMessageControl(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
GLuint(Messages,size()), &Messages[0], GL_FALSE);
glDebugMessageControl(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, GL_DONT_CARE,
GLuint(Messages,size()), &Messages[0], GL_FALSE);
// Push debug group 1
// Inheritate of the default debug group debug output volume control
// Filtered out by glDebugMessageControl
glPushDebugGroup(
GL_DEBUG_SOURCE_APPLICATION,
1,
-1, "Message 1");
// In this section of the code, we are interested in performances.
glDebugMessageControl(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE, 0, NULL, GL_TRUE);
// But we already identify that some messages are not really useful for us.
std::vector<GLuint> Messages = {5678, 6789};
glDebugMessageControl(
GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
GLuint(Messages,size()), &Messages[0], GL_FALSE);
glDebugMessageInsert(
GL_DEBUG_SOURCE_APPLICATION,
GL_DEBUG_TYPE_PERFORMANCE, 1357,
GL_DEBUG_SEVERITY_MEDIUM,
-1, "Message 2");
glDebugMessageInsert(
GL_DEBUG_SOURCE_THIRD_PARTY, // We still filter out these messages.
GL_DEBUG_TYPE_OTHER, 3579,
GL_DEBUG_SEVERITY_MEDIUM,
-1, "Message 3");
glPopDebugGroup();
// Expected debug output from the GL implementation
// Message 2
Issues
(1) Should the extension provides a method for querying markers?
RESOLVED: No.
(2) Is the concept of <severity> meaningful for most profiling use cases?
DISCUSSION: The debug output API was originally designed for debugging
but its design has led implementation and application to use
it for profiling. Furthermore, markers are not strictly
speaking low, medium or high severity messages.
RESOLVED: Added DEBUG_SEVERITY_NOTIFICATION
(3) How should an implementation behave when the application doesn't push
and pop group markers evenly?
DISCUSSION: Extra "pop" may be ignored as it is done in OpenGL ES
EXT_debug_marker but what to do if the user push too many
time? In any case, if a software doesn't push and pop evenly,
its design is pretty ill. Hence it is better to notify the
application as soon as possible by generating an error.
OpenGL legacy handles this problem by limiting the size of the
stacks and generating STACK_UNDERFLOW and STACK_OVERFLOW
errors.
The size of the marker group stack need to be big enough so
that the application won't be limited but small enough so that
an error is generated soon when pushes and pops are not even.
Another option is to let the drivers workaround this issue by
ignoring push commands for a full stack and pop commands for
an empty stack. In such case, an application doesn't have an
immediate feedback for this behavior.
RESOLVED: Generates STACK_UNDERFLOW or STACK_UNDERFLOW errors
(4) Do we need a maximum length for a marker string?
RESOLVED: No, reuse MAX_DEBUG_MESSAGE_LENGTH
(5) Can we use this new extension to allow applications to request the
info logs from compiling, linking and validating to be automatically
submitted to the debug output log and debug output call-back function?
DISCUSSION: The API may need a new <type> value DEBUG_TYPE_INFO_LOG
for every kind of info logs. glLinkProgram, glCompileShader,
glCreateShaderProgram, glValidateProgram and
glValidateProgramPipeline, which execution generate the info
logs, could also automatically submit this logs the the debug
output API.
Such strategy can already be apply by querying the info log
manually and submitting it to the debug output API with
DebugMessageInsert but on some implementations querying the
log immediately after the operation may significantly slow
down the general compilation of shaders process.
The mechanism could be enable with glEnable with a dedicated
value (DEBUG_OUTPUT_INFO_LOG). When enable, an option is
that shader, program and program pipeline would not have to
maintain this log.
This perspective emphasis the centralised nature of OpenGL
debugging to the debug output API.
RESOLVED: Nothing prevent an implementation implementing ARB_debug_output
to do it already.
(6) Should we use dedicated functions for pushing and popping the group
marker stack or use DebugMessageInsert with a dedicated types?
DISCUSSION: These functions have side effects (causing underflow errors,
causing other messages to become disabled) rather than purely
injecting messages into the debug log.
RESOLVED: Use separated functions.
(7) Should we generate an error when we pop the last entry or when the
stack is empty?
DISCUSSION: For the deprecated stacks, at the beginning of the program the
stack depth was 1 which implies a default debug group (id 0?)
in the present case.
RESOLVED: Let's follow the deprecated stacks precedent.
(8) Should we be able to query the current debug group?
DISCUSSION: ARB_debug_output doesn't provide a query API for debug output
control states, should we follow this precedent or are there
use cases where is could be especially useful?
RESOLVED: No, it doesn't seem very useful.
(9) Should we provide within which debug group a message is generated?
DISCUSSION: Such information might be useful but we would need to add a
parameter to the callback function. Also, the application can
take the responsibility of saving the current active debug
group. Such option avoid API disruption.
RESOLVED: (8) could resolve this issue as well if this is actually at
desired feature. Also nothing prevents an implementation to use
a debug group id to form the debug output message. Finally an
application can always store the current debug group each time
a DEBUG_TYPE_PUSH_GROUP is generated.
(10) Do we need a dedicated mechanism to enable and disable debug outputs?
DISCUSSION: It could seem that using glDebugMessageControl could allow
to disable debug output. However with the introduction of
debug groups, glDebugMessageControl only disable the active
debug group and it could be pretty complex for an application
to ensure that each debug group is disable. A easier idea
would be to be global switch glEnable(GL_DEBUG_OUTPUT)
allowing the application to completely switch on and off the
entire debug output mechanism.
RESOLVED: Issue covered by ARB_debug_output2
(11) Should there be a way to enable and disable the debug output
functionality via glEnable(GL_DEBUG_OUTPUT) in addition to the way
the context is created? This may be useful for third-party or
pre-existing code that doesn't have control over how the context is
created. This could be exposed in addition to the context creation
flag, and the context creation flag just sets the default state of
the enable.
RESOLVED: Yes, based on various feedback this would be useful. Added
to revision 3 of this extension spec.
(12) Should we use a single function to set the label for all objects?
DISCUSSION: This is the approach chosen in OpenGL ES extension
EXT_debug_label. It builds up a new strong precedent
for an important functionality but not exactly one
which purpose is to build a strong design precedent.
On one hand using a unique function for all objects
reduce the number of new entry point from 24 to 2.
RESOLVED: For the purpose of convergence with ES, the groups have
voted for only 2 functions.
(13) Do we need a maximum length (MAX_LABEL_LENGTH) for the label?
DISCUSSION: Following the precedents given by others strings in
OpenGL, this seems useful. On one hand ARB_debug_output
has a maximum size of the debug message
(MAX_DEBUG_MESSAGE_LENGTH), shader variable names have
a maximum length but on other hand the shader source
and the program info log doesn't have such limitation.
However, it seems hard to imagine that implementations
doesn't have limitation somehow.
RESOLVED: Yes
(14) Should we provide a function to label a display list?
RESOLVED: Yes for compatibility profile only.
(15) Should the ES version of this extension supports the message log
or only the callback function?
DISCUSSION: When promoting AMD_debug_output to ARB_debug_output, the ARB
has added a message log that can be query by the application
if no callback function has been specified by the application.
The purpose of this addition was to support remote rendering.
Is remote rendering supported by OpenGL ES? The ES group
typically wants to have only one way to do things, should we
only support the callback function for ES debug output?
RESOLVED: The ES group has chosen to keep it by vote
(16) Why do OpenGL implementations use KHR suffixes, while OpenGL
implementations use no suffix?
DISCUSSION: this functionality was initially defined by OpenGL 4.3, and
set of "backwards compatibility" extensions were defined to allow
implementing it against earlier GL versions. OpenGL ARB policy in the
case of backwards compatibility extensions is that extension suffixes
should not be added. The OpenGL ES Working Group then decided to support
the same functionality as an OpenGL ES extension, and both groups agreed
to share a single KHR specification for the extension. However, OpenGL
ES policy requires extension suffixes on Khronos-approved OES and KHR
extensions.
We are aware of this inconsistency, but both working groups have chosen
to stand by their own naming policies and the inconsistency is unlikely
to be resolved.
Revision History
Revision 17, 2015/07/02 (Jan-Harald Fredriksen)
- Clarify CONTEXT_FLAGS state for ES3.1 and earlier in the Interactions
section (Bug 13104).
Revision 16, 2015/03/11 (Jon Leech)
- Clarify dependencies required to support PROGRAM_PIPELINE (Bug
13545).
Revision 15, 2014/03/04 (Jon Leech)
- Minor changes to clean up expected message output format in example
code and refer to the value of state named by tokens, rather than
the token values themselves (Bug 10083).
Revision 14, 2013/11/05 (Jon Leech)
- Edit state tables to replace the "Get Value" of LABEL with "-",
indicating unnamed state. There is no token LABEL in the extension,
and the GetObject*Label commands do not take <pname> parameters (Bug
11131).
Revision 13, 2013/06/24 (Jon Leech)
- Add 'const' attribute to <userParam> for DebugMessageCallback and
the corresponding GLDEBUGPROC type. Specify that unrecognized
message IDs are ignored in the DebugMessageControl <ids> array.
Specify that GetDebugMessageLog <messageLog> parameter must be
NULL when <bufSize> is less than zero, to allow an early out.
Replace spurious GLvoid with void. (Bug 10083).
Revision 12, 2013/06/15 (Jon Leech)
- Clarify in the New Tokens section that the <source> parameter of
some commands may not allow all possible values shown in this
section (public Bug 889).
Revision 11, 2013/04/26 (Jon Leech)
- Implement OpenGL ES policy of adding KHR suffixes to all KHR
extensions. Add notes, OpenGL ES Interaction section, and issue 16
explaining the situation (Bug 9716).
Revision 10, 2013/04/16 (Jon Leech)
- Fix type of <ids> parameter in GetDebugMessageLog body (Bug 10083)
Revision 9, 2012/09/18 (pbrown)
- Add a "void" function argument list for PopDebugGroup(). The GLEW
library needs this to properly parse the extension spec file.
Revision 8, 2012/09/16 (Jon Leech)
- Add existing tokens allowed for ObjectLabel identifiers to "New
Tokens" section, without enum values since they aren't actually new
(Bug 9506).
Revision 7, 2012/09/12 (Jon Leech)
- Clarify description of DebugMessageControl parameters to avoid
triple negatives (Bug 9392).
Revision 6, 2012/07/31 (criccio)
- ObjectLabel generates an INVALID_VALUE error if <name>
doesn't identify a valid object.
Revision 5, 2012/06/22 (criccio)
- Resolved issue 15
Revision 4, 2012/06/19 (Jon Leech)
- Change logSize parameter to bufSize
Revision 3, 2012/06/12 (criccio)
- Added ObjectPtrLabel and GetObjectPtrLabel (bug 9140)
Revision 2, 2012/06/07 (criccio)
- Updated overview for higher consistence of the language.
- Clarified when the message is generated by the GL when popping
a debug group.
Revision 1, 2012/06/04 (criccio)
- First draft, merged GL_ARB_debug_output, GL_ARB_debug_output2,
GL_ARB_debug_group and GL_ARB_debug_label.