1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file errors.c
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa debugging and error handling functions.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.1
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "errors.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "imports.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dispatch.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "hash.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "version.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAXSTRING MAX_DEBUG_MESSAGE_LENGTH
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_client_severity
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct simple_node link;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint ID;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic char out_of_memory[] = "Debugging error: out of memory";
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define enum_is(e, kind1, kind2) \
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ((e) == GL_DEBUG_##kind1##_##kind2##_ARB || (e) == GL_DONT_CARE)
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define severity_is(sev, kind) enum_is(sev, SEVERITY, kind)
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define source_is(s, kind) enum_is(s, SOURCE, kind)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define type_is(t, kind) enum_is(t, TYPE, kind)
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Prevent define collision on Windows */
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef ERROR
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum {
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SOURCE_APPLICATION,
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SOURCE_THIRD_PARTY,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SOURCE_COUNT,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SOURCE_ANY = -1
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum {
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_ERROR,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_DEPRECATED,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_UNDEFINED,
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_PORTABILITY,
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_PERFORMANCE,
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_OTHER,
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_COUNT,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TYPE_ANY = -1
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum {
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SEVERITY_LOW,
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SEVERITY_MEDIUM,
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SEVERITY_HIGH,
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SEVERITY_COUNT,
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SEVERITY_ANY = -1
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum_to_index(GLenum e)
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (e) {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_APPLICATION_ARB:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)SOURCE_APPLICATION;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)SOURCE_THIRD_PARTY;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_ERROR_ARB:
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_ERROR;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_DEPRECATED;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_UNDEFINED;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PERFORMANCE_ARB:
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_PERFORMANCE;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PORTABILITY_ARB:
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_PORTABILITY;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_OTHER_ARB:
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_OTHER;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_LOW_ARB:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)SEVERITY_LOW;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_MEDIUM_ARB:
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)SEVERITY_MEDIUM;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_HIGH_ARB:
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)SEVERITY_HIGH;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DONT_CARE:
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (int)TYPE_ANY;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "unreachable");
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -2;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We store a bitfield in the hash table, with five possible values total.
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The ENABLED_BIT's purpose is self-explanatory.
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The FOUND_BIT is needed to differentiate the value of DISABLED from
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the value returned by HashTableLookup() when it can't find the given key.
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The KNOWN_SEVERITY bit is a bit complicated:
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A client may call Control() with an array of IDs, then call Control()
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on all message IDs of a certain severity, then Insert() one of the
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * previously specified IDs, giving us a known severity level, then call
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Control() on all message IDs of a certain severity level again.
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * After the first call, those IDs will have a FOUND_BIT, but will not
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * exist in any severity-specific list, so the second call will not
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * impact them. This is undesirable but unavoidable given the API:
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The only entrypoint that gives a severity for a client-defined ID
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is the Insert() call.
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For the sake of Control(), we want to maintain the invariant
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that an ID will either appear in none of the three severity lists,
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or appear once, to minimize pointless duplication and potential surprises.
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Because Insert() is the only place that will learn an ID's severity,
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it should insert an ID into the appropriate list, but only if the ID
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * doesn't exist in it or any other list yet. Because searching all three
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * lists at O(n) is needlessly expensive, we store KNOWN_SEVERITY.
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FOUND_BIT = 1 << 0,
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ENABLED_BIT = 1 << 1,
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   KNOWN_SEVERITY = 1 << 2,
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* HashTable reserves zero as a return value meaning 'not found' */
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NOT_FOUND = 0,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DISABLED = FOUND_BIT,
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ENABLED = ENABLED_BIT | FOUND_BIT
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the state of the given message ID in a client-controlled
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * namespace.
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'source', 'type', and 'severity' are array indices like TYPE_ERROR,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not GL enums.
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_message_state(struct gl_context *ctx, int source, int type,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLuint id, int severity)
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_client_namespace *nspace =
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &ctx->Debug.ClientIDs.Namespaces[source][type];
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uintptr_t state;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* In addition to not being able to store zero as a value, HashTable also
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      can't use zero as a key. */
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (id)
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state = nspace->ZeroID;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Only do this once for each ID. This makes sure the ID exists in,
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      at most, one list, and does not pointlessly appear multiple times. */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(state & KNOWN_SEVERITY)) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_client_severity *entry;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (state == NOT_FOUND) {
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (ctx->Debug.ClientIDs.Defaults[severity][source][type])
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            state = ENABLED;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            state = DISABLED;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry = malloc(sizeof *entry);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!entry)
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto out;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state |= KNOWN_SEVERITY;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (id)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_HashInsert(nspace->IDs, id, (void*)state);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nspace->ZeroID = state;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry->ID = id;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      insert_at_tail(&nspace->Severity[severity], &entry->link);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout:
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return !!(state & ENABLED_BIT);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sets the state of the given message ID in a client-controlled
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * namespace.
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'source' and 'type' are array indices like TYPE_ERROR, not GL enums.
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgset_message_state(struct gl_context *ctx, int source, int type,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLuint id, GLboolean enabled)
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_client_namespace *nspace =
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &ctx->Debug.ClientIDs.Namespaces[source][type];
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uintptr_t state;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* In addition to not being able to store zero as a value, HashTable also
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      can't use zero as a key. */
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (id)
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state = nspace->ZeroID;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state == NOT_FOUND)
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      state = enabled ? ENABLED : DISABLED;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (enabled)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         state |= ENABLED_BIT;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         state &= ~ENABLED_BIT;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (id)
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_HashInsert(nspace->IDs, id, (void*)state);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nspace->ZeroID = state;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Whether a debugging message should be logged or not.
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For implementation-controlled namespaces, we keep an array
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of booleans per namespace, per context, recording whether
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * each individual message is enabled or not. The message ID
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is an index into the namespace's array.
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshould_log(struct gl_context *ctx, GLenum source, GLenum type,
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           GLuint id, GLenum severity)
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source == GL_DEBUG_SOURCE_APPLICATION_ARB ||
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       source == GL_DEBUG_SOURCE_THIRD_PARTY_ARB) {
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int s, t, sev;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      s = enum_to_index(source);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = enum_to_index(type);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sev = enum_to_index(severity);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return get_message_state(ctx, s, t, sev, id);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type_is(type, ERROR)) {
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source_is(source, API))
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ctx->Debug.ApiErrors[id];
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source_is(source, WINDOW_SYSTEM))
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ctx->Debug.WinsysErrors[id];
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source_is(source, SHADER_COMPILER))
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ctx->Debug.ShaderErrors[id];
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source_is(source, OTHER))
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ctx->Debug.OtherErrors[id];
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (severity != GL_DEBUG_SEVERITY_LOW_ARB);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'buf' is not necessarily a null-terminated string. When logging, copy
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'len' characters from it, store them in a new, null-terminated string,
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and remember the number of bytes used by that string, *including*
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the null terminator this time.
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_log_msg(struct gl_context *ctx, GLenum source, GLenum type,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              GLuint id, GLenum severity, GLint len, const char *buf)
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint nextEmpty;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_debug_msg *emptySlot;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(len >= 0 && len < MAX_DEBUG_MESSAGE_LENGTH);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!should_log(ctx, source, type, id, severity))
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Debug.Callback) {
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Debug.Callback(source, type, id, severity,
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          len, buf, ctx->Debug.CallbackData);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Debug.NumMessages == MAX_DEBUG_LOGGED_MESSAGES)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nextEmpty = (ctx->Debug.NextMsg + ctx->Debug.NumMessages)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          % MAX_DEBUG_LOGGED_MESSAGES;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emptySlot = &ctx->Debug.Log[nextEmpty];
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!emptySlot->message && !emptySlot->length);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emptySlot->message = MALLOC(len+1);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emptySlot->message) {
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void) strncpy(emptySlot->message, buf, (size_t)len);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->message[len] = '\0';
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->length = len+1;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->source = source;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->type = type;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->id = id;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->severity = severity;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* malloc failed! */
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->message = out_of_memory;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->length = strlen(out_of_memory)+1;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->source = GL_DEBUG_SOURCE_OTHER_ARB;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->type = GL_DEBUG_TYPE_ERROR_ARB;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->id = OTHER_ERROR_OUT_OF_MEMORY;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emptySlot->severity = GL_DEBUG_SEVERITY_HIGH_ARB;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Debug.NumMessages == 0)
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Debug.NextMsgLength = ctx->Debug.Log[ctx->Debug.NextMsg].length;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NumMessages++;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Pop the oldest debug message out of the log.
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Writes the message string, including the null terminator, into 'buf',
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * using up to 'bufSize' bytes. If 'bufSize' is too small, or
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if 'buf' is NULL, nothing is written.
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the number of bytes written on success, or when 'buf' is NULL,
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the number that would have been written. A return value of 0
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * indicates failure.
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLsizei
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_msg(struct gl_context *ctx, GLenum *source, GLenum *type,
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              GLuint *id, GLenum *severity, GLsizei bufSize, char *buf)
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_debug_msg *msg;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLsizei length;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Debug.NumMessages == 0)
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   msg = &ctx->Debug.Log[ctx->Debug.NextMsg];
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   length = msg->length;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(length > 0 && length == ctx->Debug.NextMsgLength);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bufSize < length && buf != NULL)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (severity)
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *severity = msg->severity;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source)
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *source = msg->source;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type)
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *type = msg->type;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (id)
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *id = msg->id;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (buf) {
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(msg->message[length-1] == '\0');
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void) strncpy(buf, msg->message, (size_t)length);
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (msg->message != (char*)out_of_memory)
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(msg->message);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   msg->message = NULL;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   msg->length = 0;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NumMessages--;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NextMsg++;
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NextMsg %= MAX_DEBUG_LOGGED_MESSAGES;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NextMsgLength = ctx->Debug.Log[ctx->Debug.NextMsg].length;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return length;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Verify that source, type, and severity are valid enums.
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glDebugMessageInsertARB only accepts two values for 'source',
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and glDebugMessageControlARB will additionally accept GL_DONT_CARE
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in any parameter, so handle those cases specially.
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvalidate_params(struct gl_context *ctx, unsigned caller,
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLenum source, GLenum type, GLenum severity)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INSERT 1
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CONTROL 2
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(source) {
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_APPLICATION_ARB:
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_API_ARB:
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SOURCE_OTHER_ARB:
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (caller != INSERT)
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DONT_CARE:
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (caller == CONTROL)
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(type) {
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_ERROR_ARB:
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PERFORMANCE_ARB:
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PORTABILITY_ARB:
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_OTHER_ARB:
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DONT_CARE:
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (caller == CONTROL)
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(severity) {
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_HIGH_ARB:
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_MEDIUM_ARB:
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_SEVERITY_LOW_ARB:
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DONT_CARE:
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (caller == CONTROL)
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *callerstr;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (caller == INSERT)
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         callerstr = "glDebugMessageInsertARB";
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (caller == CONTROL)
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         callerstr = "glDebugMessageControlARB";
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_FALSE;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error( ctx, GL_INVALID_ENUM, "bad values passed to %s"
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  "(source=0x%x, type=0x%x, severity=0x%x)", callerstr,
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  source, type, severity);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_FALSE;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GLAPIENTRY
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id,
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            GLenum severity, GLint length,
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            const GLcharARB* buf)
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GET_CURRENT_CONTEXT(ctx);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!validate_params(ctx, INSERT, source, type, severity))
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* GL_INVALID_ENUM */
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (length < 0)
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      length = strlen(buf);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (length >= MAX_DEBUG_MESSAGE_LENGTH) {
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_VALUE, "glDebugMessageInsertARB"
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "(length=%d, which is not less than "
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "GL_MAX_DEBUG_MESSAGE_LENGTH_ARB=%d)", length,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 MAX_DEBUG_MESSAGE_LENGTH);
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_log_msg(ctx, source, type, id, severity, length, buf);
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint GLAPIENTRY
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum* sources,
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            GLenum* types, GLenum* ids, GLenum* severities,
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            GLsizei* lengths, GLcharARB* messageLog)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GET_CURRENT_CONTEXT(ctx);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint ret;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!messageLog)
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      logSize = 0;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (logSize < 0) {
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_VALUE, "glGetDebugMessageLogARB"
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "(logSize=%d : logSize must not be negative)", logSize);
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (ret = 0; ret < count; ret++) {
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLsizei written = _mesa_get_msg(ctx, sources, types, ids, severities,
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      logSize, messageLog);
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!written)
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (messageLog) {
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         messageLog += written;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         logSize -= written;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lengths) {
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *lengths = written;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lengths++;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (severities)
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         severities++;
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (sources)
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sources++;
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (types)
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         types++;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ids)
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ids++;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'array' is an array representing a particular debugging-message namespace.
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * I.e., the set of all API errors, or the set of all Shader Compiler errors.
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'size' is the size of 'array'. 'count' is the size of 'ids', an array
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of indices into 'array'. All the elements of 'array' at the indices
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * listed in 'ids' will be overwritten with the value of 'enabled'.
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If 'count' is zero, all elements in 'array' are overwritten with the
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * value of 'enabled'.
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcontrol_messages(GLboolean *array, GLuint size,
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLsizei count, const GLuint *ids, GLboolean enabled)
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLsizei i;
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!count) {
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint id;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (id = 0; id < size; id++) {
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         array[id] = enabled;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ids[i] >= size) {
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* XXX: The spec doesn't say what to do with a non-existent ID. */
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      array[ids[i]] = enabled;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set the state of all message IDs found in the given intersection
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of 'source', 'type', and 'severity'. Note that all three of these
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * parameters are array indices, not the corresponding GL enums.
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This requires both setting the state of all previously seen message
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IDs in the hash table, and setting the default state for all
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applicable combinations of source/type/severity, so that all the
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * yet-unknown message IDs that may be used in the future will be
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * impacted as if they were already known.
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcontrol_app_messages_by_group(struct gl_context *ctx, int source, int type,
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              int severity, GLboolean enabled)
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int s, t, sev, smax, tmax, sevmax;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source == SOURCE_ANY) {
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      source = 0;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      smax = SOURCE_COUNT;
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      smax = source+1;
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type == TYPE_ANY) {
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = 0;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmax = TYPE_COUNT;
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmax = type+1;
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (severity == SEVERITY_ANY) {
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      severity = 0;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sevmax = SEVERITY_COUNT;
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sevmax = severity+1;
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (sev = severity; sev < sevmax; sev++)
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (s = source; s < smax; s++)
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (t = type; t < tmax; t++) {
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct simple_node *node;
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct gl_client_severity *entry;
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* change the default for IDs we've never seen before. */
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ClientIDs->Defaults[sev][s][t] = enabled;
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Now change the state of IDs we *have* seen... */
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            foreach(node, &ClientIDs->Namespaces[s][t].Severity[sev]) {
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               entry = (struct gl_client_severity *)node;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               set_message_state(ctx, s, t, entry->ID, enabled);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Debugging-message namespaces with the source APPLICATION or THIRD_PARTY
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * require special handling, since the IDs in them are controlled by clients,
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not the OpenGL implementation.
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'count' is the length of the array 'ids'. If 'count' is nonzero, all
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the given IDs in the namespace defined by 'esource' and 'etype'
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will be affected.
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If 'count' is zero, this sets the state of all IDs that match
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the combination of 'esource', 'etype', and 'eseverity'.
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcontrol_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype,
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     GLenum eseverity, GLsizei count, const GLuint *ids,
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     GLboolean enabled)
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int source, type, severity;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLsizei i;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   source = enum_to_index(esource);
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type = enum_to_index(etype);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   severity = enum_to_index(eseverity);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (count)
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(severity == SEVERITY_ANY && type != TYPE_ANY
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             && source != SOURCE_ANY);
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++)
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      set_message_state(ctx, source, type, ids[i], enabled);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (count)
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   control_app_messages_by_group(ctx, source, type, severity, enabled);
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GLAPIENTRY
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_DebugMessageControlARB(GLenum source, GLenum type, GLenum severity,
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             GLsizei count, const GLuint *ids,
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             GLboolean enabled)
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GET_CURRENT_CONTEXT(ctx);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (count < 0) {
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_VALUE, "glDebugMessageControlARB"
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "(count=%d : count must not be negative)", count);
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!validate_params(ctx, CONTROL, source, type, severity))
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* GL_INVALID_ENUM */
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (count && (severity != GL_DONT_CARE || type == GL_DONT_CARE
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 || source == GL_DONT_CARE)) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_OPERATION, "glDebugMessageControlARB"
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "(When passing an array of ids, severity must be"
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         " GL_DONT_CARE, and source and type must not be GL_DONT_CARE.");
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source_is(source, APPLICATION) || source_is(source, THIRD_PARTY))
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      control_app_messages(ctx, source, type, severity, count, ids, enabled);
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (severity_is(severity, HIGH)) {
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type_is(type, ERROR)) {
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (source_is(source, API))
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            control_messages(ctx->Debug.ApiErrors, API_ERROR_COUNT,
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             count, ids, enabled);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (source_is(source, WINDOW_SYSTEM))
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            control_messages(ctx->Debug.WinsysErrors, WINSYS_ERROR_COUNT,
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             count, ids, enabled);
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (source_is(source, SHADER_COMPILER))
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            control_messages(ctx->Debug.ShaderErrors, SHADER_ERROR_COUNT,
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             count, ids, enabled);
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (source_is(source, OTHER))
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            control_messages(ctx->Debug.OtherErrors, OTHER_ERROR_COUNT,
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             count, ids, enabled);
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void GLAPIENTRY
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_DebugMessageCallbackARB(GLDEBUGPROCARB callback, const GLvoid *userParam)
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GET_CURRENT_CONTEXT(ctx);
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.Callback = callback;
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.CallbackData = (void *) userParam;
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_init_errors_dispatch(struct _glapi_table *disp)
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SET_DebugMessageCallbackARB(disp, _mesa_DebugMessageCallbackARB);
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SET_DebugMessageControlARB(disp, _mesa_DebugMessageControlARB);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SET_DebugMessageInsertARB(disp, _mesa_DebugMessageInsertARB);
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SET_GetDebugMessageLogARB(disp, _mesa_GetDebugMessageLogARB);
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_init_errors(struct gl_context *ctx)
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int s, t, sev;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs;
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.Callback = NULL;
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.SyncOutput = GL_FALSE;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.Log[0].length = 0;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NumMessages = 0;
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NextMsg = 0;
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->Debug.NextMsgLength = 0;
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Enable all the messages with severity HIGH or MEDIUM by default. */
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ctx->Debug.ApiErrors, GL_TRUE, sizeof ctx->Debug.ApiErrors);
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ctx->Debug.WinsysErrors, GL_TRUE, sizeof ctx->Debug.WinsysErrors);
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ctx->Debug.ShaderErrors, GL_TRUE, sizeof ctx->Debug.ShaderErrors);
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ctx->Debug.OtherErrors, GL_TRUE, sizeof ctx->Debug.OtherErrors);
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ClientIDs->Defaults[SEVERITY_HIGH], GL_TRUE,
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          sizeof ClientIDs->Defaults[SEVERITY_HIGH]);
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ClientIDs->Defaults[SEVERITY_MEDIUM], GL_TRUE,
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          sizeof ClientIDs->Defaults[SEVERITY_MEDIUM]);
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(ClientIDs->Defaults[SEVERITY_LOW], GL_FALSE,
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          sizeof ClientIDs->Defaults[SEVERITY_LOW]);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Initialize state for filtering client-provided debug messages. */
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (s = 0; s < SOURCE_COUNT; s++)
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (t = 0; t < TYPE_COUNT; t++) {
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ClientIDs->Namespaces[s][t].IDs = _mesa_NewHashTable();
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(ClientIDs->Namespaces[s][t].IDs);
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (sev = 0; sev < SEVERITY_COUNT; sev++)
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            make_empty_list(&ClientIDs->Namespaces[s][t].Severity[sev]);
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_free_errors_data(struct gl_context *ctx)
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int s, t, sev;
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs;
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Tear down state for filtering client-provided debug messages. */
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (s = 0; s < SOURCE_COUNT; s++)
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (t = 0; t < TYPE_COUNT; t++) {
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_DeleteHashTable(ClientIDs->Namespaces[s][t].IDs);
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (sev = 0; sev < SEVERITY_COUNT; sev++) {
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct simple_node *node, *tmp;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct gl_client_severity *entry;
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            foreach_s(node, tmp, &ClientIDs->Namespaces[s][t].Severity[sev]) {
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               entry = (struct gl_client_severity *)node;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               FREE(entry);
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Diagnostics */
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgoutput_if_debug(const char *prefixString, const char *outputString,
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLboolean newline)
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static int debug = -1;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static FILE *fout = NULL;
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Init the local 'debug' var once.
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note: the _mesa_init_debug() function should have been called
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * by now so MESA_DEBUG_FLAGS will be initialized.
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (debug == -1) {
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings,
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * etc to the named file.  Otherwise, output to stderr.
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *logFile = _mesa_getenv("MESA_LOG_FILE");
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (logFile)
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fout = fopen(logFile, "w");
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!fout)
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fout = stderr;
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* in debug builds, print messages unless MESA_DEBUG="silent" */
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = 0;
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = 1;
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* in release builds, be silent unless MESA_DEBUG is set */
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug = _mesa_getenv("MESA_DEBUG") != NULL;
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now only print the string if we're required to do so. */
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (debug) {
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(fout, "%s: %s", prefixString, outputString);
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (newline)
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(fout, "\n");
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fflush(fout);
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_WIN32) && !defined(_WIN32_WCE)
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* stderr from windows applications without console is not usually
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * visible, so communicate with the debugger instead */
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         char buf[4096];
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         OutputDebugStringA(buf);
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return string version of GL error code.
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror_string( GLenum error )
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (error) {
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NO_ERROR:
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_NO_ERROR";
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INVALID_VALUE:
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_INVALID_VALUE";
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INVALID_ENUM:
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_INVALID_ENUM";
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INVALID_OPERATION:
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_INVALID_OPERATION";
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STACK_OVERFLOW:
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_STACK_OVERFLOW";
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STACK_UNDERFLOW:
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_STACK_UNDERFLOW";
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_OUT_OF_MEMORY:
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_OUT_OF_MEMORY";
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TABLE_TOO_LARGE:
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_TABLE_TOO_LARGE";
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "GL_INVALID_FRAMEBUFFER_OPERATION";
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return "unknown";
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When a new type of error is recorded, print a message describing
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * previous errors which were accumulated.
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgflush_delayed_errors( struct gl_context *ctx )
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char s[MAXSTRING];
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->ErrorDebugCount) {
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     ctx->ErrorDebugCount,
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     error_string(ctx->ErrorValue));
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      output_if_debug("Mesa", s, GL_TRUE);
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->ErrorDebugCount = 0;
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Report a warning (a recoverable error condition) to stderr if
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * either DEBUG is defined or the MESA_DEBUG env var is set.
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx GL context.
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fmtString printf()-like format string.
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char str[MAXSTRING];
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_list args;
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_start( args, fmtString );
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) _mesa_vsnprintf( str, MAXSTRING, fmtString, args );
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_end( args );
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx)
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flush_delayed_errors( ctx );
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   output_if_debug("Mesa warning", str, GL_TRUE);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Report an internal implementation problem.
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Prints the message to stderr via fprintf().
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx GL context.
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fmtString problem description string.
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_list args;
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char str[MAXSTRING];
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static int numCalls = 0;
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (numCalls < 50) {
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numCalls++;
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      va_start( args, fmtString );
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_vsnprintf( str, MAXSTRING, fmtString, args );
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      va_end( args );
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr, "Mesa %s implementation error: %s\n",
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              MESA_VERSION_STRING, str);
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr, "Please report at bugs.freedesktop.org\n");
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshould_output(struct gl_context *ctx, GLenum error, const char *fmtString)
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static GLint debug = -1;
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check debug environment variable only once:
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (debug == -1) {
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *debugEnv = _mesa_getenv("MESA_DEBUG");
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (debugEnv && strstr(debugEnv, "silent"))
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = GL_FALSE;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = GL_TRUE;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (debugEnv)
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = GL_TRUE;
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug = GL_FALSE;
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (debug) {
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->ErrorValue != error ||
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ctx->ErrorDebugFmtString != fmtString) {
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         flush_delayed_errors( ctx );
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ctx->ErrorDebugFmtString = fmtString;
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ctx->ErrorDebugCount = 0;
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_TRUE;
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->ErrorDebugCount++;
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_FALSE;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Record an OpenGL state error.  These usually occur when the user
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * passes invalid parameters to a GL function.
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If debugging is enabled (either at compile-time via the DEBUG macro, or
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * run-time via the MESA_DEBUG environment variable), report the error with
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * _mesa_debug().
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx the GL context.
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param error the error value.
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fmtString printf() style format string, followed by optional args
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean do_output, do_log;
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do_output = should_output(ctx, error, fmtString);
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do_log = should_log(ctx, GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB,
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       API_ERROR_UNKNOWN, GL_DEBUG_SEVERITY_HIGH_ARB);
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (do_output || do_log) {
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      char s[MAXSTRING], s2[MAXSTRING];
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int len;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      va_list args;
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      va_start(args, fmtString);
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      len = _mesa_vsnprintf(s, MAXSTRING, fmtString, args);
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      va_end(args);
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (len >= MAXSTRING) {
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Too long error message. Whoever calls _mesa_error should use
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * shorter strings. */
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(0);
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      len = _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (len >= MAXSTRING) {
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Same as above. */
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(0);
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Print the error to stderr if needed. */
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (do_output) {
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         output_if_debug("Mesa: User error", s2, GL_TRUE);
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Log the error via ARB_debug_output if needed.*/
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (do_log) {
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_log_msg(ctx, GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB,
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       API_ERROR_UNKNOWN, GL_DEBUG_SEVERITY_HIGH_ARB, len, s2);
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Set the GL context error state for glGetError. */
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_record_error(ctx, error);
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Report debug information.  Print error message to stderr via fprintf().
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * No-op if DEBUG mode not enabled.
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx GL context.
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fmtString printf()-style format string, followed by optional args.
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char s[MAXSTRING];
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_list args;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_start(args, fmtString);
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_vsnprintf(s, MAXSTRING, fmtString, args);
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_end(args);
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   output_if_debug("Mesa", s, GL_FALSE);
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* DEBUG */
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) fmtString;
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Report debug information from the shader compiler via GL_ARB_debug_output.
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx GL context.
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type The namespace to which this message belongs.
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param id The message ID within the given namespace.
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param msg The message to output. Need not be null-terminated.
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param len The length of 'msg'. If negative, 'msg' must be null-terminated.
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id,
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const char *msg, int len )
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLenum source = GL_DEBUG_SOURCE_SHADER_COMPILER_ARB,
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          severity;
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type) {
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_ERROR_ARB:
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(id < SHADER_ERROR_COUNT);
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      severity = GL_DEBUG_SEVERITY_HIGH_ARB;
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PORTABILITY_ARB:
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_PERFORMANCE_ARB:
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEBUG_TYPE_OTHER_ARB:
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "other categories not implemented yet");
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(ctx, "bad enum in _mesa_shader_debug()");
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (len < 0)
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      len = strlen(msg);
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Truncate the message if necessary. */
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (len >= MAX_DEBUG_MESSAGE_LENGTH)
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      len = MAX_DEBUG_MESSAGE_LENGTH - 1;
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_log_msg(ctx, source, type, id, severity, len, msg);
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
1118