OpenGL Error

From OpenGL Wiki
Jump to navigation Jump to search

If the parameters of a function call do not match the set of parameters allowed by OpenGL, or do not interact reasonably with state that is already set in the context, then an OpenGL Error will result. The errors are presented as an error code.

For most OpenGL errors, and for most OpenGL functions, a function that emits an error will have no effect. No OpenGL state will be changed, no rendering will be initiated. It will be as if the function had not been called. There are a few cases where this is not the case.

Catching errors (the hard way)[edit]

OpenGL errors are stored in a queue until the error is actually handled.[footnotes 1] Therefore, if you do not regularly test for errors, you will not know necessarily which function call elicited a particular error. As such, error testing should be done regularly if you need to know where an error came from.

To fetch the next error in the queue (and to remove it from the queue), call this function:

GLenum glGetError()

If the error queue is empty, it will return GL_NO_ERROR. Otherwise, it will return one of the error enumerators below and remove that error from the queue. So to fetch all of the errors currently in the queue, you would need to loop.


V · E

A simple loop to extract the current OpenGL errors:

GLenum err;
while((err = glGetError()) != GL_NO_ERROR)
{
  // Process/log the error.
}


Note: No OpenGL function call is valid when an OpenGL Context is not made current. Depending on the platform, a call to glGetError without having a context made current may crash or return any value, including indefinitely returning a valid OpenGL error code. So if you see an infinite loop in such a function, this is likely the reason why.

Meaning of errors[edit]

The glGetError function returns one of the following error codes, or GL_NO_ERROR if no (more) errors are available. Each error code represents a category of user error.

GL_INVALID_ENUM, 0x0500
Given when an enumeration parameter is not a legal enumeration for that function. This is given only for local problems; if the spec allows the enumeration in certain circumstances, where other parameters or state dictate those circumstances, then GL_INVALID_OPERATION is the result instead.
GL_INVALID_VALUE, 0x0501
Given when a value parameter is not a legal value for that function. This is only given for local problems; if the spec allows the value in certain circumstances, where other parameters or state dictate those circumstances, then GL_INVALID_OPERATION is the result instead.
GL_INVALID_OPERATION, 0x0502
Given when the set of state for a command is not legal for the parameters given to that command. It is also given for commands where combinations of parameters define what the legal parameters are.
GL_STACK_OVERFLOW, 0x0503
Given when a stack pushing operation cannot be done because it would overflow the limit of that stack's size.
GL_STACK_UNDERFLOW, 0x0504
Given when a stack popping operation cannot be done because the stack is already at its lowest point.
GL_OUT_OF_MEMORY, 0x0505
Given when performing an operation that can allocate memory, and the memory cannot be allocated. The results of OpenGL functions that return this error are undefined; it is allowable for partial execution of an operation to happen in this circumstance.
GL_INVALID_FRAMEBUFFER_OPERATION, 0x0506
Given when doing anything that would attempt to read from or write/render to a framebuffer that is not complete.
GL_CONTEXT_LOST, 0x0507 (with OpenGL 4.5 or ARB_KHR_robustness)
Given if the OpenGL context has been lost, due to a graphics card reset.
GL_TABLE_TOO_LARGE1, 0x8031
Part of the ARB_imaging extension.

1: These error codes are deprecated in 3.0 and removed in 3.1 core and above.

In the OpenGL Reference documentation, most errors are listed explicitly. However, GL_OUT_OF_MEMORY and GL_CONTEXT_LOST could be generated by virtually any OpenGL function. And they can be generated for reasons not directly associated with that particular function call.

Catching errors (the easy way)[edit]

The debug output feature provides a simple method for your application to be notified via an application-defined message callback function when an OpenGL error (or other interesting event) occurs within the driver. Simply enable debug output, register a callback, and wait for it to be called with a DEBUG_TYPE_ERROR message.

This method avoids the need to sprinkle expensive and code-obfuscating glGetError() calls around your application to catch and localize the causes of OpenGL errors (and the need to conditionally compile them into debug builds to avoid the performance hit in optimized builds). The feature can even ensure that message callback functions are invoked on the same thread and within the very same call stack as the GL call that triggered the GL error (or performance warning).

V · E

A simple example showing how to utilize debug message callbacks (e.g. for detecting OpenGL errors):

void GLAPIENTRY
MessageCallback( GLenum source,
                 GLenum type,
                 GLuint id,
                 GLenum severity,
                 GLsizei length,
                 const GLchar* message,
                 const void* userParam )
{
  fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
           ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
            type, severity, message );
}

// During init, enable debug output
glEnable              ( GL_DEBUG_OUTPUT );
glDebugMessageCallback( MessageCallback, 0 );


Side effects[edit]

Under most circumstances, a function that generates an error will exit without changing any OpenGL state or initiating any OpenGL operations. They will not modify any client memory passed into those functions by the user (ie: pointer arguments). Under such errors, return values are zero or something equally innocuous. However, there are certain circumstances were an error happens and OpenGL state is modified.

Whenever the GL_OUT_OF_MEMORY error is generated, the state of the OpenGL context and/or objects is undefined.

The GL_CONTEXT_LOST error is generated (which requires OpenGL 4.5 or ARB_KHR_robustness) by any commands after the OpenGL context was lost. Those commands have no side effects, with a few special-case exceptions for functions that can block the CPU.

The multi-bind functions functions have unusual error properties. Because they aggregate the ability to bind multiple objects at once, if the binding of one object fails with an error, the others will be bound as normal. Only the erronous objects will fail to bind. Note that there is no way to detect which objects failed to bind (other than querying the context for each binding point).

No error contexts[edit]

V · E
No Error Context
Core in version 4.6
Core since version 4.6
ARB extension KHR_no_error

An OpenGL Context can be created which does not report OpenGL Errors. If the context bit GL_CONTEXT_FLAG_NO_ERROR_BIT is set to true, then the context will not report most errors. It will still report GL_OUT_OF_MEMORY_ERROR where appropriate, but this can be delayed from the point where the error actually happens. No other errors will be reported.

This also means that the implementation will not check for errors either. So if you provide incorrect parameters to a function that would have provoked an error, you will get undefined behavior instead. This includes the possibility of application termination.

Contexts cannot have the no error bit and the robustsness or debug bits.

Notes[edit]

  1. The specification "OpenGL 4.6 (Core Profile) - October 22, 2019", chapter "2.3.1 Errors" doesn't talk about a error queue, it talks about several flag-code pairs.