GL_DEBUG_SEVERITY_HIGH missing for GL_INVALID_OPERATION on some drivers — glDebugMessageCallback filtering
0 reputation · 11 May 2026, 11:40 UTC
0 reputation · 11 May 2026, 11:40 UTC
I am building an error-reporting layer on top of OpenGL 4.3+ debug output (glDebugMessageCallback with GL_DEBUG_OUTPUT and GL_DEBUG_OUTPUT_SYNCHRONOUS enabled) so that user-facing diagnostics can be filtered by severity rather than vendor-specific message IDs.
The portable filter relies on GL_DEBUG_SEVERITY_HIGH for hard failures and GL_DEBUG_TYPE_ERROR for API misuse. The uncertainty is that vendors appear to map the same condition (for example, a call that sets GL_INVALID_OPERATION) to different severities, and it is unclear whether a GL_DEBUG_TYPE_ERROR message is guaranteed to correspond to an error retrievable via glGetError on all conformant drivers.
Assume a 4.3+ core context and that message IDs cannot be used portably. The goal is a severity-based classification that behaves consistently across NVIDIA, AMD, and Intel drivers without per-vendor tables.
GL_DEBUG_TYPE_ERROR message corresponds to a glGetError-reportable error, or is that mapping implementation-defined?HIGH/MEDIUM/LOW) for standard API errors normative, or may drivers legitimately downgrade them?Severity is not normative. The KHR_debug / OpenGL 4.3 specification deliberately leaves severity assignment to the implementation, so the same GL_INVALID_OPERATION can legitimately arrive as GL_DEBUG_SEVERITY_HIGH on one driver and MEDIUM or even LOW on another. Filtering on HIGH alone will silently drop real errors on some vendors. The portable basis for your filter is the type enum, not severity.
Mostly yes, with caveats. GL_DEBUG_TYPE_ERROR messages are generated when the implementation detects an API error condition, and those are the same conditions the spec defines as setting the glGetError error flag. So in practice a TYPE_ERROR message corresponds to a glGetError-reportable error.
However, the spec does not guarantee:
glGetError,So treat TYPE_ERROR as "an API error occurred at or before this point," not as a 1:1 mapping to a specific glGetError return value.
No. Drivers may legitimately downgrade severity for errors they consider benign, and may emit performance hints or undefined-behavior warnings at any severity they choose. There is no cross-vendor severity table you can rely on, and message IDs and message strings are explicitly vendor-specific — never parse the string for classification.
GL_DEBUG_TYPE_ERROR and GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR. Type classifications are applied far more consistently across NVIDIA, AMD, and Intel than severities.glDebugMessageControl to enable all messages of those types regardless of severity — pass GL_DONT_CARE for source, severity, and id. This is the portable way to avoid per-vendor ID tables.source to GL_DEBUG_SOURCE_API to exclude driver-internal or third-party chatter.// Enable all ERROR and UNDEFINED_BEHAVIOR messages, any severity/source/id
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR,
GL_DONT_CARE, 0, nullptr, GL_TRUE);
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
GL_DONT_CARE, 0, nullptr, GL_TRUE);With GL_DEBUG_OUTPUT_SYNCHRONOUS enabled, the callback fires on the calling thread at the offending call, so you can empirically confirm behavior per driver:
GLFW_OPENGL_DEBUG_CONTEXT). Without GL_CONTEXT_FLAG_DEBUG_BIT, some drivers emit nothing at all — absence of messages is not proof of correctness.GL_INVALID_OPERATION (e.g., glUseProgram with a non-program id) and record the delivered type/severity on each vendor.glGetError and confirm it returns the matching enum for TYPE_ERROR messages.Two practical cautions: synchronous output serializes the pipeline and can hurt performance, so enable it only in diagnostic builds; and if your layer must report the exact failing enum, capture it via glGetError in the callback rather than inferring it from the message.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.