gallium: add debug facility to dump random blobs as hex
[mesa.git] / src / gallium / include / pipe / p_debug.h
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Cross-platform debugging helpers.
31 *
32 * For now it just has assert and printf replacements, but it might be extended
33 * with stack trace reports and more advanced logging in the near future.
34 *
35 * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
36 */
37
38 #ifndef P_DEBUG_H_
39 #define P_DEBUG_H_
40
41
42 #include <stdarg.h>
43
44 #include "p_compiler.h"
45
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51
52 #ifdef DBG
53 #ifndef DEBUG
54 #define DEBUG 1
55 #endif
56 #else
57 #ifndef NDEBUG
58 #define NDEBUG 1
59 #endif
60 #endif
61
62
63 /**
64 * Print debug messages.
65 *
66 * A debug message will be printed regardless of the DEBUG/NDEBUG macros.
67 *
68 * The actual channel used to output debug message is platform specific. To
69 * avoid misformating or truncation, follow these rules of thumb:
70 * - output whole lines
71 * - avoid outputing large strings (512 bytes is the current maximum length
72 * that is guaranteed to be printed in all platforms)
73 */
74 void debug_printf(const char *format, ...);
75
76
77 /* Dump a blob in hex to the same place that debug_printf sends its
78 * messages:
79 */
80 void debug_print_blob( const char *name,
81 const void *blob,
82 unsigned size );
83
84 /**
85 * @sa debug_printf
86 */
87 void debug_vprintf(const char *format, va_list ap);
88
89 void debug_assert_fail(const char *expr, const char *file, unsigned line);
90
91
92 /** Assert macro */
93 #ifdef DEBUG
94 #define debug_assert(expr) ((expr) ? (void)0 : debug_assert_fail(#expr, __FILE__, __LINE__))
95 #else
96 #define debug_assert(expr) ((void)0)
97 #endif
98
99
100 #ifdef assert
101 #undef assert
102 #endif
103 #define assert(expr) debug_assert(expr)
104
105
106 /**
107 * Set a channel's debug mask.
108 *
109 * uuid is just a random 32 bit integer that uniquely identifies the debugging
110 * channel.
111 *
112 * @note Due to current implementation issues, make sure the lower 8 bits of
113 * UUID are unique.
114 */
115 void debug_mask_set(uint32_t uuid, uint32_t mask);
116
117
118 uint32_t debug_mask_get(uint32_t uuid);
119
120
121 /**
122 * Conditional debug output.
123 *
124 * This is just a generalization of the debug filtering mechanism used
125 * throughout Gallium.
126 *
127 * You use this function as:
128 *
129 * @code
130 * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier
131 *
132 * static void inline
133 * mydriver_debug(uint32_t what, const char *format, ...)
134 * {
135 * #ifdef DEBUG
136 * va_list ap;
137 * va_start(ap, format);
138 * debug_mask_vprintf(MYDRIVER_UUID, what, format, ap);
139 * va_end(ap);
140 * #endif
141 * }
142 *
143 * ...
144 *
145 * debug_mask_set(MYDRIVER_UUID,
146 * MYDRIVER_DEBUG_THIS |
147 * MYDRIVER_DEBUG_THAT |
148 * ... );
149 *
150 * ...
151 *
152 * mydriver_debug(MYDRIVER_DEBUG_THIS,
153 * "this and this happened\n");
154 *
155 * mydriver_debug(MYDRIVER_DEBUG_THAT,
156 * "that = %f\n", that);
157 * ...
158 * @endcode
159 *
160 * You can also define several variants of mydriver_debug, with hardcoded what.
161 * Note that although macros with variable number of arguments would accomplish
162 * more in less code, they are not portable.
163 */
164 void debug_mask_vprintf(uint32_t uuid,
165 uint32_t what,
166 const char *format,
167 va_list ap);
168
169
170 #ifdef DEBUG
171 #define debug_warning(__msg) \
172 debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg))
173 #else
174 #define debug_warning(__msg) \
175 ((void)0)
176 #endif
177
178
179 /**
180 * Used by debug_dump_enum and debug_dump_flags to describe symbols.
181 */
182 struct debug_named_value
183 {
184 const char *name;
185 unsigned long value;
186 };
187
188
189 /**
190 * Some C pre-processor magic to simplify creating named values.
191 *
192 * Example:
193 * @code
194 * static const debug_named_value my_names[] = {
195 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X),
196 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y),
197 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z),
198 * DEBUG_NAMED_VALUE_END
199 * };
200 *
201 * ...
202 * debug_printf("%s = %s\n",
203 * name,
204 * debug_dump_enum(my_names, my_value));
205 * ...
206 * @endcode
207 */
208 #define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol}
209 #define DEBUG_NAMED_VALUE_END {NULL, 0}
210
211
212 /**
213 * Convert a enum value to a string.
214 */
215 const char *
216 debug_dump_enum(const struct debug_named_value *names,
217 unsigned long value);
218
219
220 /**
221 * Convert binary flags value to a string.
222 */
223 const char *
224 debug_dump_flags(const struct debug_named_value *names,
225 unsigned long value);
226
227
228 #ifdef __cplusplus
229 }
230 #endif
231
232 #endif /* P_DEBUG_H_ */