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 /**
85  * Compabibility layer for old debug code
86  **/
87 #if defined(RADEON_R200)
88 extern radeon_debug_type_t r200_enabled_debug_types;
89 #define RADEON_DEBUG r200_enabled_debug_types
90 #elif defined(RADEON_R100)
91 extern radeon_debug_type_t r100_enabled_debug_types;
92 #define RADEON_DEBUG r100_enabled_debug_types
93 #else
94 #error "Neither RADEON_R100 nor RADEON_R200 are defined."
95 #endif
96 
radeon_is_debug_enabled(const radeon_debug_type_t type,const radeon_debug_level_t level)97 static inline int radeon_is_debug_enabled(const radeon_debug_type_t type,
98 	   const radeon_debug_level_t level)
99 {
100        return RADEON_DEBUG_LEVEL >= level
101 		&& (type & RADEON_DEBUG);
102 }
103 
104 extern void _radeon_print(const radeon_debug_type_t type,
105 	   const radeon_debug_level_t level,
106 	   const char* message,
107 	   ...)  PRINTFLIKE(3, 4);
108 /**
109  * Print out debug message if channel specified by type is enabled
110  * and compile time debugging level is at least as high as level parameter
111  */
112 #define radeon_print(type, level, ...) do {			\
113 	const radeon_debug_level_t _debug_level = (level);	\
114 	const radeon_debug_type_t _debug_type = (type);		\
115 	/* Compile out if level of message is too high */	\
116 	if (radeon_is_debug_enabled(type, level)) {		\
117 		_radeon_print(_debug_type, _debug_level,	\
118 			__VA_ARGS__);				\
119 	}							\
120 } while(0)
121 
122 /**
123  * printf style function for writing error messages.
124  */
125 #define radeon_error(...) do {					\
126 	radeon_print(RADEON_GENERAL, RADEON_CRITICAL,		\
127 		__VA_ARGS__);					\
128 } while(0)
129 
130 /**
131  * printf style function for writing warnings.
132  */
133 #define radeon_warning(...) do {				\
134 	radeon_print(RADEON_GENERAL, RADEON_IMPORTANT,		\
135 		__VA_ARGS__);					\
136 } while(0)
137 
138 extern void radeon_init_debug(void);
139 extern void _radeon_debug_add_indent(void);
140 extern void _radeon_debug_remove_indent(void);
141 
radeon_debug_add_indent(void)142 static inline void radeon_debug_add_indent(void)
143 {
144        if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
145 	      _radeon_debug_add_indent();
146        }
147 }
radeon_debug_remove_indent(void)148 static inline void radeon_debug_remove_indent(void)
149 {
150        if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
151 	      _radeon_debug_remove_indent();
152        }
153 }
154 
155 
156 /* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
157    I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
158    with other compilers ... GLUE!
159 */
160 #define WARN_ONCE(...)      do { \
161        static int __warn_once=1; \
162        if(__warn_once){ \
163                radeon_warning("*********************************WARN_ONCE*********************************\n"); \
164                radeon_warning("File %s function %s line %d\n", \
165                        __FILE__, __func__, __LINE__); \
166                radeon_warning(__VA_ARGS__);\
167                radeon_warning("***************************************************************************\n"); \
168                __warn_once=0;\
169                } \
170        } while(0)
171 
172 
173 #endif
174