+/**
+ * Set the state of all message IDs found in the given intersection of
+ * 'source', 'type', and 'severity'. The _COUNT enum can be used for
+ * GL_DONT_CARE (include all messages in the class).
+ *
+ * This requires both setting the state of all previously seen message
+ * IDs in the hash table, and setting the default state for all
+ * applicable combinations of source/type/severity, so that all the
+ * yet-unknown message IDs that may be used in the future will be
+ * impacted as if they were already known.
+ */
+static void
+control_messages(struct gl_context *ctx,
+ enum mesa_debug_source source,
+ enum mesa_debug_type type,
+ enum mesa_debug_severity severity,
+ GLboolean enabled)
+{
+ int s, t, sev, smax, tmax, sevmax;
+ GLint gstack = ctx->Debug.GroupStackDepth;
+
+ if (source == MESA_DEBUG_SOURCE_COUNT) {
+ source = 0;
+ smax = MESA_DEBUG_SOURCE_COUNT;
+ } else {
+ smax = source+1;
+ }
+
+ if (type == MESA_DEBUG_TYPE_COUNT) {
+ type = 0;
+ tmax = MESA_DEBUG_TYPE_COUNT;
+ } else {
+ tmax = type+1;
+ }
+
+ if (severity == MESA_DEBUG_SEVERITY_COUNT) {
+ severity = 0;
+ sevmax = MESA_DEBUG_SEVERITY_COUNT;
+ } else {
+ sevmax = severity+1;
+ }
+
+ for (sev = severity; sev < sevmax; sev++)
+ for (s = source; s < smax; s++)
+ for (t = type; t < tmax; t++) {
+ struct simple_node *node;
+ struct gl_debug_severity *entry;
+
+ /* change the default for IDs we've never seen before. */
+ ctx->Debug.Defaults[gstack][sev][s][t] = enabled;
+
+ /* Now change the state of IDs we *have* seen... */
+ foreach(node, &ctx->Debug.Namespaces[gstack][s][t].Severity[sev]) {
+ entry = (struct gl_debug_severity *)node;
+ set_message_state(ctx, s, t, entry->ID, enabled);
+ }
+ }
+}
+
+/**
+ * Debugging-message namespaces with the source APPLICATION or THIRD_PARTY
+ * require special handling, since the IDs in them are controlled by clients,
+ * not the OpenGL implementation.
+ *
+ * 'count' is the length of the array 'ids'. If 'count' is nonzero, all
+ * the given IDs in the namespace defined by 'esource' and 'etype'
+ * will be affected.
+ *
+ * If 'count' is zero, this sets the state of all IDs that match
+ * the combination of 'esource', 'etype', and 'eseverity'.
+ */
+static void
+control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype,
+ GLenum eseverity, GLsizei count, const GLuint *ids,
+ GLboolean enabled)
+{
+ GLsizei i;
+ enum mesa_debug_source source = gl_enum_to_debug_source(esource);
+ enum mesa_debug_type type = gl_enum_to_debug_type(etype);
+ enum mesa_debug_severity severity = gl_enum_to_debug_severity(eseverity);
+
+ for (i = 0; i < count; i++)
+ set_message_state(ctx, source, type, ids[i], enabled);
+
+ if (count)
+ return;
+
+ control_messages(ctx, source, type, severity, enabled);
+}
+
+/**
+ * This is a generic message control function for use by both
+ * glDebugMessageControlARB and glDebugMessageControl.
+ */
+static void
+message_control(GLenum gl_source, GLenum gl_type,
+ GLenum gl_severity,
+ GLsizei count, const GLuint *ids,
+ GLboolean enabled,
+ unsigned caller, const char *callerstr)