1 /*
2 * Copyright © 2009 Pauli Nieminen
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 */
25 /*
26 * Authors:
27 * Pauli Nieminen <suokkos@gmail.com>
28 */
29
30 #ifndef RADEON_DEBUG_H_INCLUDED
31 #define RADEON_DEBUG_H_INCLUDED
32
33 #include <stdlib.h>
34
35 typedef enum radeon_debug_levels {
36 RADEON_CRITICAL = 0, /* Only errors */
37 RADEON_IMPORTANT = 1, /* Important warnings and messages */
38 RADEON_NORMAL = 2, /* Normal log messages usefull for debugging */
39 RADEON_VERBOSE = 3, /* Extra details to debugging */
40 RADEON_TRACE = 4 /* Log about everything that happens */
41 } radeon_debug_level_t;
42
43 /**
44 * Compile time option to change level of debugging compiled to dri driver.
45 * Selecting critical level is not recommended because perfromance gains are
46 * going to minimal but you will lose a lot of important warnings in case of
47 * errors.
48 */
49 #ifndef RADEON_DEBUG_LEVEL
50 # ifdef DEBUG
51 # define RADEON_DEBUG_LEVEL RADEON_TRACE
52 # else
53 # define RADEON_DEBUG_LEVEL RADEON_VERBOSE
54 # endif
55 #endif
56
57 typedef enum radeon_debug_types {
58 RADEON_TEXTURE = 0x00001,
59 RADEON_STATE = 0x00002,
60 RADEON_IOCTL = 0x00004,
61 RADEON_RENDER = 0x00008,
62 RADEON_SWRENDER = 0x00010,
63 RADEON_FALLBACKS = 0x00020,
64 RADEON_VFMT = 0x00040,
65 RADEON_SHADER = 0x00080,
66 RADEON_CS = 0x00100,
67 RADEON_DRI = 0x00200,
68 RADEON_DMA = 0x00400,
69 RADEON_SANITY = 0x00800,
70 RADEON_SYNC = 0x01000,
71 RADEON_PIXEL = 0x02000,
72 RADEON_MEMORY = 0x04000,
73 RADEON_VERTS = 0x08000,
74 RADEON_GENERAL = 0x10000 /* Used for errors and warnings */
75 } radeon_debug_type_t;
76
77 #define RADEON_MAX_INDENT 5
78
79 struct radeon_debug {
80 size_t indent_depth;
81 char indent[RADEON_MAX_INDENT];
82 };
83
84 extern radeon_debug_type_t radeon_enabled_debug_types;
85
86 /**
87 * Compabibility layer for old debug code
88 **/
89 #define RADEON_DEBUG radeon_enabled_debug_types
90
radeon_is_debug_enabled(const radeon_debug_type_t type,const radeon_debug_level_t level)91 static inline int radeon_is_debug_enabled(const radeon_debug_type_t type,
92 const radeon_debug_level_t level)
93 {
94 return RADEON_DEBUG_LEVEL >= level
95 && (type & radeon_enabled_debug_types);
96 }
97
98 extern void _radeon_print(const radeon_debug_type_t type,
99 const radeon_debug_level_t level,
100 const char* message,
101 ...) PRINTFLIKE(3, 4);
102 /**
103 * Print out debug message if channel specified by type is enabled
104 * and compile time debugging level is at least as high as level parameter
105 */
106 #define radeon_print(type, level, ...) do { \
107 const radeon_debug_level_t _debug_level = (level); \
108 const radeon_debug_type_t _debug_type = (type); \
109 /* Compile out if level of message is too high */ \
110 if (radeon_is_debug_enabled(type, level)) { \
111 _radeon_print(_debug_type, _debug_level, \
112 __VA_ARGS__); \
113 } \
114 } while(0)
115
116 /**
117 * printf style function for writing error messages.
118 */
119 #define radeon_error(...) do { \
120 radeon_print(RADEON_GENERAL, RADEON_CRITICAL, \
121 __VA_ARGS__); \
122 } while(0)
123
124 /**
125 * printf style function for writing warnings.
126 */
127 #define radeon_warning(...) do { \
128 radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, \
129 __VA_ARGS__); \
130 } while(0)
131
132 extern void radeon_init_debug(void);
133 extern void _radeon_debug_add_indent(void);
134 extern void _radeon_debug_remove_indent(void);
135
radeon_debug_add_indent(void)136 static inline void radeon_debug_add_indent(void)
137 {
138 if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
139 _radeon_debug_add_indent();
140 }
141 }
radeon_debug_remove_indent(void)142 static inline void radeon_debug_remove_indent(void)
143 {
144 if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
145 _radeon_debug_remove_indent();
146 }
147 }
148
149
150 /* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
151 I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
152 with other compilers ... GLUE!
153 */
154 #define WARN_ONCE(...) do { \
155 static int __warn_once=1; \
156 if(__warn_once){ \
157 radeon_warning("*********************************WARN_ONCE*********************************\n"); \
158 radeon_warning("File %s function %s line %d\n", \
159 __FILE__, __func__, __LINE__); \
160 radeon_warning(__VA_ARGS__);\
161 radeon_warning("***************************************************************************\n"); \
162 __warn_once=0;\
163 } \
164 } while(0)
165
166
167 #endif
168