1af69d88dSmrg/**
2af69d88dSmrg * \file errors.c
3af69d88dSmrg * Mesa debugging and error handling functions.
4af69d88dSmrg */
5af69d88dSmrg
6af69d88dSmrg/*
7af69d88dSmrg * Mesa 3-D graphics library
8af69d88dSmrg *
9af69d88dSmrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
10af69d88dSmrg *
11af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
12af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
13af69d88dSmrg * to deal in the Software without restriction, including without limitation
14af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
16af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
17af69d88dSmrg *
18af69d88dSmrg * The above copyright notice and this permission notice shall be included
19af69d88dSmrg * in all copies or substantial portions of the Software.
20af69d88dSmrg *
21af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22af69d88dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
28af69d88dSmrg */
29af69d88dSmrg
30af69d88dSmrg
3101e04c3fSmrg#include <stdarg.h>
3201e04c3fSmrg#include <stdio.h>
33af69d88dSmrg#include "errors.h"
34af69d88dSmrg#include "enums.h"
357ec681f3Smrg
36af69d88dSmrg#include "context.h"
3701e04c3fSmrg#include "debug_output.h"
38af69d88dSmrg
39af69d88dSmrg
4001e04c3fSmrgstatic FILE *LogFile = NULL;
41af69d88dSmrg
42af69d88dSmrg
43af69d88dSmrgstatic void
44af69d88dSmrgoutput_if_debug(const char *prefixString, const char *outputString,
45af69d88dSmrg                GLboolean newline)
46af69d88dSmrg{
47af69d88dSmrg   static int debug = -1;
48af69d88dSmrg
49af69d88dSmrg   /* Init the local 'debug' var once.
50af69d88dSmrg    * Note: the _mesa_init_debug() function should have been called
51af69d88dSmrg    * by now so MESA_DEBUG_FLAGS will be initialized.
52af69d88dSmrg    */
53af69d88dSmrg   if (debug == -1) {
54af69d88dSmrg      /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings,
55af69d88dSmrg       * etc to the named file.  Otherwise, output to stderr.
56af69d88dSmrg       */
5701e04c3fSmrg      const char *logFile = getenv("MESA_LOG_FILE");
58af69d88dSmrg      if (logFile)
5901e04c3fSmrg         LogFile = fopen(logFile, "w");
6001e04c3fSmrg      if (!LogFile)
6101e04c3fSmrg         LogFile = stderr;
627ec681f3Smrg#ifndef NDEBUG
63af69d88dSmrg      /* in debug builds, print messages unless MESA_DEBUG="silent" */
64af69d88dSmrg      if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
65af69d88dSmrg         debug = 0;
66af69d88dSmrg      else
67af69d88dSmrg         debug = 1;
68af69d88dSmrg#else
697ec681f3Smrg      const char *env = getenv("MESA_DEBUG");
707ec681f3Smrg      debug = env && strstr(env, "silent") == NULL;
71af69d88dSmrg#endif
72af69d88dSmrg   }
73af69d88dSmrg
74af69d88dSmrg   /* Now only print the string if we're required to do so. */
75af69d88dSmrg   if (debug) {
7601e04c3fSmrg      if (prefixString)
7701e04c3fSmrg         fprintf(LogFile, "%s: %s", prefixString, outputString);
7801e04c3fSmrg      else
7901e04c3fSmrg         fprintf(LogFile, "%s", outputString);
80af69d88dSmrg      if (newline)
8101e04c3fSmrg         fprintf(LogFile, "\n");
8201e04c3fSmrg      fflush(LogFile);
83af69d88dSmrg
8401e04c3fSmrg#if defined(_WIN32)
857ec681f3Smrg      /* stderr from windows applications without console is not usually
867ec681f3Smrg       * visible, so communicate with the debugger instead */
87af69d88dSmrg      {
88af69d88dSmrg         char buf[4096];
897ec681f3Smrg         if (prefixString)
907ec681f3Smrg            snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
917ec681f3Smrg         else
927ec681f3Smrg            snprintf(buf, sizeof(buf), "%s%s", outputString, newline ? "\n" : "");
93af69d88dSmrg         OutputDebugStringA(buf);
94af69d88dSmrg      }
95af69d88dSmrg#endif
96af69d88dSmrg   }
97af69d88dSmrg}
98af69d88dSmrg
99af69d88dSmrg
10001e04c3fSmrg/**
10101e04c3fSmrg * Return the file handle to use for debug/logging.  Defaults to stderr
10201e04c3fSmrg * unless MESA_LOG_FILE is defined.
10301e04c3fSmrg */
10401e04c3fSmrgFILE *
10501e04c3fSmrg_mesa_get_log_file(void)
10601e04c3fSmrg{
10701e04c3fSmrg   assert(LogFile);
10801e04c3fSmrg   return LogFile;
10901e04c3fSmrg}
11001e04c3fSmrg
11101e04c3fSmrg
112af69d88dSmrg/**
113af69d88dSmrg * When a new type of error is recorded, print a message describing
114af69d88dSmrg * previous errors which were accumulated.
115af69d88dSmrg */
116af69d88dSmrgstatic void
117af69d88dSmrgflush_delayed_errors( struct gl_context *ctx )
118af69d88dSmrg{
119af69d88dSmrg   char s[MAX_DEBUG_MESSAGE_LENGTH];
120af69d88dSmrg
121af69d88dSmrg   if (ctx->ErrorDebugCount) {
1227ec681f3Smrg      snprintf(s, MAX_DEBUG_MESSAGE_LENGTH, "%d similar %s errors",
123af69d88dSmrg                     ctx->ErrorDebugCount,
12401e04c3fSmrg                     _mesa_enum_to_string(ctx->ErrorValue));
125af69d88dSmrg
126af69d88dSmrg      output_if_debug("Mesa", s, GL_TRUE);
127af69d88dSmrg
128af69d88dSmrg      ctx->ErrorDebugCount = 0;
129af69d88dSmrg   }
130af69d88dSmrg}
131af69d88dSmrg
132af69d88dSmrg
133af69d88dSmrg/**
134af69d88dSmrg * Report a warning (a recoverable error condition) to stderr if
135af69d88dSmrg * either DEBUG is defined or the MESA_DEBUG env var is set.
136af69d88dSmrg *
137af69d88dSmrg * \param ctx GL context.
138af69d88dSmrg * \param fmtString printf()-like format string.
139af69d88dSmrg */
140af69d88dSmrgvoid
141af69d88dSmrg_mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
142af69d88dSmrg{
143af69d88dSmrg   char str[MAX_DEBUG_MESSAGE_LENGTH];
144af69d88dSmrg   va_list args;
14501e04c3fSmrg   va_start( args, fmtString );
1467ec681f3Smrg   (void) vsnprintf( str, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args );
147af69d88dSmrg   va_end( args );
14801e04c3fSmrg
149af69d88dSmrg   if (ctx)
150af69d88dSmrg      flush_delayed_errors( ctx );
151af69d88dSmrg
152af69d88dSmrg   output_if_debug("Mesa warning", str, GL_TRUE);
153af69d88dSmrg}
154af69d88dSmrg
155af69d88dSmrg
156af69d88dSmrg/**
157af69d88dSmrg * Report an internal implementation problem.
158af69d88dSmrg * Prints the message to stderr via fprintf().
159af69d88dSmrg *
160af69d88dSmrg * \param ctx GL context.
161af69d88dSmrg * \param fmtString problem description string.
162af69d88dSmrg */
163af69d88dSmrgvoid
164af69d88dSmrg_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
165af69d88dSmrg{
166af69d88dSmrg   va_list args;
167af69d88dSmrg   char str[MAX_DEBUG_MESSAGE_LENGTH];
168af69d88dSmrg   static int numCalls = 0;
169af69d88dSmrg
170af69d88dSmrg   (void) ctx;
171af69d88dSmrg
172af69d88dSmrg   if (numCalls < 50) {
173af69d88dSmrg      numCalls++;
174af69d88dSmrg
17501e04c3fSmrg      va_start( args, fmtString );
1767ec681f3Smrg      vsnprintf( str, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args );
177af69d88dSmrg      va_end( args );
17801e04c3fSmrg      fprintf(stderr, "Mesa " PACKAGE_VERSION " implementation error: %s\n",
17901e04c3fSmrg              str);
180af69d88dSmrg      fprintf(stderr, "Please report at " PACKAGE_BUGREPORT "\n");
181af69d88dSmrg   }
182af69d88dSmrg}
183af69d88dSmrg
184af69d88dSmrg
185af69d88dSmrgstatic GLboolean
186af69d88dSmrgshould_output(struct gl_context *ctx, GLenum error, const char *fmtString)
187af69d88dSmrg{
188af69d88dSmrg   static GLint debug = -1;
189af69d88dSmrg
190af69d88dSmrg   /* Check debug environment variable only once:
191af69d88dSmrg    */
192af69d88dSmrg   if (debug == -1) {
19301e04c3fSmrg      const char *debugEnv = getenv("MESA_DEBUG");
194af69d88dSmrg
1957ec681f3Smrg#ifndef NDEBUG
196af69d88dSmrg      if (debugEnv && strstr(debugEnv, "silent"))
197af69d88dSmrg         debug = GL_FALSE;
198af69d88dSmrg      else
199af69d88dSmrg         debug = GL_TRUE;
200af69d88dSmrg#else
201af69d88dSmrg      if (debugEnv)
202af69d88dSmrg         debug = GL_TRUE;
203af69d88dSmrg      else
204af69d88dSmrg         debug = GL_FALSE;
205af69d88dSmrg#endif
206af69d88dSmrg   }
207af69d88dSmrg
208af69d88dSmrg   if (debug) {
209af69d88dSmrg      if (ctx->ErrorValue != error ||
210af69d88dSmrg          ctx->ErrorDebugFmtString != fmtString) {
211af69d88dSmrg         flush_delayed_errors( ctx );
212af69d88dSmrg         ctx->ErrorDebugFmtString = fmtString;
213af69d88dSmrg         ctx->ErrorDebugCount = 0;
214af69d88dSmrg         return GL_TRUE;
215af69d88dSmrg      }
216af69d88dSmrg      ctx->ErrorDebugCount++;
217af69d88dSmrg   }
218af69d88dSmrg   return GL_FALSE;
219af69d88dSmrg}
220af69d88dSmrg
221af69d88dSmrg
22201e04c3fSmrgvoid
223a8bb7a65Smaya_mesa_gl_vdebugf(struct gl_context *ctx,
224a8bb7a65Smaya                 GLuint *id,
225a8bb7a65Smaya                 enum mesa_debug_source source,
226a8bb7a65Smaya                 enum mesa_debug_type type,
227a8bb7a65Smaya                 enum mesa_debug_severity severity,
228a8bb7a65Smaya                 const char *fmtString,
229a8bb7a65Smaya                 va_list args)
23001e04c3fSmrg{
23101e04c3fSmrg   char s[MAX_DEBUG_MESSAGE_LENGTH];
23201e04c3fSmrg   int len;
23301e04c3fSmrg
23401e04c3fSmrg   _mesa_debug_get_id(id);
23501e04c3fSmrg
2367ec681f3Smrg   len = vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
237993e1d59Smrg   if (len >= MAX_DEBUG_MESSAGE_LENGTH)
238993e1d59Smrg      /* message was truncated */
239993e1d59Smrg      len = MAX_DEBUG_MESSAGE_LENGTH - 1;
24001e04c3fSmrg
24101e04c3fSmrg   _mesa_log_msg(ctx, source, type, *id, severity, len, s);
24201e04c3fSmrg}
24301e04c3fSmrg
24401e04c3fSmrg
245af69d88dSmrgvoid
246a8bb7a65Smaya_mesa_gl_debugf(struct gl_context *ctx,
247a8bb7a65Smaya                GLuint *id,
248a8bb7a65Smaya                enum mesa_debug_source source,
249a8bb7a65Smaya                enum mesa_debug_type type,
250a8bb7a65Smaya                enum mesa_debug_severity severity,
251a8bb7a65Smaya                const char *fmtString, ...)
252a8bb7a65Smaya{
253a8bb7a65Smaya   va_list args;
254a8bb7a65Smaya   va_start(args, fmtString);
255a8bb7a65Smaya   _mesa_gl_vdebugf(ctx, id, source, type, severity, fmtString, args);
256a8bb7a65Smaya   va_end(args);
257a8bb7a65Smaya}
258a8bb7a65Smaya
259a8bb7a65Smayasize_t
260af69d88dSmrg_mesa_gl_debug(struct gl_context *ctx,
261af69d88dSmrg               GLuint *id,
26201e04c3fSmrg               enum mesa_debug_source source,
263af69d88dSmrg               enum mesa_debug_type type,
264af69d88dSmrg               enum mesa_debug_severity severity,
265a8bb7a65Smaya               const char *msg)
266af69d88dSmrg{
267a8bb7a65Smaya   _mesa_debug_get_id(id);
268a8bb7a65Smaya
269a8bb7a65Smaya   size_t len = strnlen(msg, MAX_DEBUG_MESSAGE_LENGTH);
270a8bb7a65Smaya   if (len < MAX_DEBUG_MESSAGE_LENGTH) {
271a8bb7a65Smaya      _mesa_log_msg(ctx, source, type, *id, severity, len, msg);
272a8bb7a65Smaya      return len;
273a8bb7a65Smaya   }
274a8bb7a65Smaya
275a8bb7a65Smaya   /* limit the message to fit within KHR_debug buffers */
276a8bb7a65Smaya   char s[MAX_DEBUG_MESSAGE_LENGTH];
277a8bb7a65Smaya   strncpy(s, msg, MAX_DEBUG_MESSAGE_LENGTH);
278a8bb7a65Smaya   s[MAX_DEBUG_MESSAGE_LENGTH - 1] = '\0';
279a8bb7a65Smaya   len = MAX_DEBUG_MESSAGE_LENGTH - 1;
280a8bb7a65Smaya   _mesa_log_msg(ctx, source, type, *id, severity, len, s);
281a8bb7a65Smaya
282a8bb7a65Smaya   /* report the number of characters that were logged */
283a8bb7a65Smaya   return len;
284af69d88dSmrg}
285af69d88dSmrg
286af69d88dSmrg
287af69d88dSmrg/**
288af69d88dSmrg * Record an OpenGL state error.  These usually occur when the user
289af69d88dSmrg * passes invalid parameters to a GL function.
290af69d88dSmrg *
291af69d88dSmrg * If debugging is enabled (either at compile-time via the DEBUG macro, or
292af69d88dSmrg * run-time via the MESA_DEBUG environment variable), report the error with
293af69d88dSmrg * _mesa_debug().
29401e04c3fSmrg *
295af69d88dSmrg * \param ctx the GL context.
296af69d88dSmrg * \param error the error value.
297af69d88dSmrg * \param fmtString printf() style format string, followed by optional args
298af69d88dSmrg */
299af69d88dSmrgvoid
300af69d88dSmrg_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
301af69d88dSmrg{
302af69d88dSmrg   GLboolean do_output, do_log;
303af69d88dSmrg   /* Ideally this would be set up by the caller, so that we had proper IDs
304af69d88dSmrg    * per different message.
305af69d88dSmrg    */
306af69d88dSmrg   static GLuint error_msg_id = 0;
307af69d88dSmrg
30801e04c3fSmrg   _mesa_debug_get_id(&error_msg_id);
309af69d88dSmrg
310af69d88dSmrg   do_output = should_output(ctx, error, fmtString);
31101e04c3fSmrg
31201e04c3fSmrg   simple_mtx_lock(&ctx->DebugMutex);
313af69d88dSmrg   if (ctx->Debug) {
31401e04c3fSmrg      do_log = _mesa_debug_is_message_enabled(ctx->Debug,
31501e04c3fSmrg                                              MESA_DEBUG_SOURCE_API,
31601e04c3fSmrg                                              MESA_DEBUG_TYPE_ERROR,
31701e04c3fSmrg                                              error_msg_id,
31801e04c3fSmrg                                              MESA_DEBUG_SEVERITY_HIGH);
319af69d88dSmrg   }
320af69d88dSmrg   else {
321af69d88dSmrg      do_log = GL_FALSE;
322af69d88dSmrg   }
32301e04c3fSmrg   simple_mtx_unlock(&ctx->DebugMutex);
324af69d88dSmrg
325af69d88dSmrg   if (do_output || do_log) {
326af69d88dSmrg      char s[MAX_DEBUG_MESSAGE_LENGTH], s2[MAX_DEBUG_MESSAGE_LENGTH];
327af69d88dSmrg      int len;
328af69d88dSmrg      va_list args;
329af69d88dSmrg
330af69d88dSmrg      va_start(args, fmtString);
3317ec681f3Smrg      len = vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
332af69d88dSmrg      va_end(args);
333af69d88dSmrg
334af69d88dSmrg      if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
335af69d88dSmrg         /* Too long error message. Whoever calls _mesa_error should use
336af69d88dSmrg          * shorter strings.
337af69d88dSmrg          */
33801e04c3fSmrg         assert(0);
339af69d88dSmrg         return;
340af69d88dSmrg      }
341af69d88dSmrg
3427ec681f3Smrg      len = snprintf(s2, MAX_DEBUG_MESSAGE_LENGTH, "%s in %s",
34301e04c3fSmrg                           _mesa_enum_to_string(error), s);
344af69d88dSmrg      if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
345af69d88dSmrg         /* Same as above. */
34601e04c3fSmrg         assert(0);
347af69d88dSmrg         return;
348af69d88dSmrg      }
349af69d88dSmrg
350af69d88dSmrg      /* Print the error to stderr if needed. */
351af69d88dSmrg      if (do_output) {
352af69d88dSmrg         output_if_debug("Mesa: User error", s2, GL_TRUE);
353af69d88dSmrg      }
354af69d88dSmrg
355af69d88dSmrg      /* Log the error via ARB_debug_output if needed.*/
356af69d88dSmrg      if (do_log) {
35701e04c3fSmrg         _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_ERROR,
35801e04c3fSmrg                       error_msg_id, MESA_DEBUG_SEVERITY_HIGH, len, s2);
359af69d88dSmrg      }
360af69d88dSmrg   }
361af69d88dSmrg
362af69d88dSmrg   /* Set the GL context error state for glGetError. */
36301e04c3fSmrg   if (ctx->ErrorValue == GL_NO_ERROR)
36401e04c3fSmrg      ctx->ErrorValue = error;
365af69d88dSmrg}
366af69d88dSmrg
367af69d88dSmrgvoid
368af69d88dSmrg_mesa_error_no_memory(const char *caller)
369af69d88dSmrg{
370af69d88dSmrg   GET_CURRENT_CONTEXT(ctx);
371af69d88dSmrg   _mesa_error(ctx, GL_OUT_OF_MEMORY, "out of memory in %s", caller);
372af69d88dSmrg}
373af69d88dSmrg
374af69d88dSmrg/**
375af69d88dSmrg * Report debug information.  Print error message to stderr via fprintf().
376af69d88dSmrg * No-op if DEBUG mode not enabled.
37701e04c3fSmrg *
378af69d88dSmrg * \param ctx GL context.
379af69d88dSmrg * \param fmtString printf()-style format string, followed by optional args.
380af69d88dSmrg */
381af69d88dSmrgvoid
382af69d88dSmrg_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
383af69d88dSmrg{
3847ec681f3Smrg#ifndef NDEBUG
385af69d88dSmrg   char s[MAX_DEBUG_MESSAGE_LENGTH];
386af69d88dSmrg   va_list args;
387af69d88dSmrg   va_start(args, fmtString);
3887ec681f3Smrg   vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
389af69d88dSmrg   va_end(args);
390af69d88dSmrg   output_if_debug("Mesa", s, GL_FALSE);
391af69d88dSmrg#endif /* DEBUG */
392af69d88dSmrg   (void) ctx;
393af69d88dSmrg   (void) fmtString;
394af69d88dSmrg}
395af69d88dSmrg
396af69d88dSmrg
39701e04c3fSmrgvoid
39801e04c3fSmrg_mesa_log(const char *fmtString, ...)
39901e04c3fSmrg{
40001e04c3fSmrg   char s[MAX_DEBUG_MESSAGE_LENGTH];
40101e04c3fSmrg   va_list args;
40201e04c3fSmrg   va_start(args, fmtString);
4037ec681f3Smrg   vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
40401e04c3fSmrg   va_end(args);
4057ec681f3Smrg   output_if_debug(NULL, s, GL_FALSE);
40601e04c3fSmrg}
40701e04c3fSmrg
40801e04c3fSmrg
409af69d88dSmrg/**
410af69d88dSmrg * Report debug information from the shader compiler via GL_ARB_debug_output.
411af69d88dSmrg *
412af69d88dSmrg * \param ctx GL context.
413af69d88dSmrg * \param type The namespace to which this message belongs.
414af69d88dSmrg * \param id The message ID within the given namespace.
41501e04c3fSmrg * \param msg The message to output. Must be null-terminated.
416af69d88dSmrg */
417af69d88dSmrgvoid
41801e04c3fSmrg_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
41901e04c3fSmrg                   const char *msg)
420af69d88dSmrg{
421af69d88dSmrg   enum mesa_debug_source source = MESA_DEBUG_SOURCE_SHADER_COMPILER;
422af69d88dSmrg   enum mesa_debug_severity severity = MESA_DEBUG_SEVERITY_HIGH;
42301e04c3fSmrg   int len;
424af69d88dSmrg
42501e04c3fSmrg   _mesa_debug_get_id(id);
426af69d88dSmrg
42701e04c3fSmrg   len = strlen(msg);
428af69d88dSmrg
429af69d88dSmrg   /* Truncate the message if necessary. */
430af69d88dSmrg   if (len >= MAX_DEBUG_MESSAGE_LENGTH)
431af69d88dSmrg      len = MAX_DEBUG_MESSAGE_LENGTH - 1;
432af69d88dSmrg
43301e04c3fSmrg   _mesa_log_msg(ctx, source, type, *id, severity, len, msg);
434af69d88dSmrg}
4357ec681f3Smrg
4367ec681f3Smrg/**
4377ec681f3Smrg * Set the parameter as the current GL error. Used by glthread.
4387ec681f3Smrg */
4397ec681f3Smrgvoid GLAPIENTRY
4407ec681f3Smrg_mesa_InternalSetError(GLenum error)
4417ec681f3Smrg{
4427ec681f3Smrg   GET_CURRENT_CONTEXT(ctx);
4437ec681f3Smrg   _mesa_error(ctx, error, "glthread");
4447ec681f3Smrg}
445