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