/* * Copyright © 2009 Pauli Nieminen * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. */ /* * Authors: * Pauli Nieminen <suokkos@gmail.com> */ #ifndef RADEON_DEBUG_H_INCLUDED #define RADEON_DEBUG_H_INCLUDED #include <stdlib.h> typedef enum radeon_debug_levels { RADEON_CRITICAL = 0, /* Only errors */ RADEON_IMPORTANT = 1, /* Important warnings and messages */ RADEON_NORMAL = 2, /* Normal log messages usefull for debugging */ RADEON_VERBOSE = 3, /* Extra details to debugging */ RADEON_TRACE = 4 /* Log about everything that happens */ } radeon_debug_level_t; /** * Compile time option to change level of debugging compiled to dri driver. * Selecting critical level is not recommended because perfromance gains are * going to minimal but you will lose a lot of important warnings in case of * errors. */ #ifndef RADEON_DEBUG_LEVEL # ifdef DEBUG # define RADEON_DEBUG_LEVEL RADEON_TRACE # else # define RADEON_DEBUG_LEVEL RADEON_VERBOSE # endif #endif typedef enum radeon_debug_types { RADEON_TEXTURE = 0x00001, RADEON_STATE = 0x00002, RADEON_IOCTL = 0x00004, RADEON_RENDER = 0x00008, RADEON_SWRENDER = 0x00010, RADEON_FALLBACKS = 0x00020, RADEON_VFMT = 0x00040, RADEON_SHADER = 0x00080, RADEON_CS = 0x00100, RADEON_DRI = 0x00200, RADEON_DMA = 0x00400, RADEON_SANITY = 0x00800, RADEON_SYNC = 0x01000, RADEON_PIXEL = 0x02000, RADEON_MEMORY = 0x04000, RADEON_VERTS = 0x08000, RADEON_GENERAL = 0x10000 /* Used for errors and warnings */ } radeon_debug_type_t; #define RADEON_MAX_INDENT 5 struct radeon_debug { size_t indent_depth; char indent[RADEON_MAX_INDENT]; }; extern radeon_debug_type_t radeon_enabled_debug_types; /** * Compabibility layer for old debug code **/ #define RADEON_DEBUG radeon_enabled_debug_types static inline int radeon_is_debug_enabled(const radeon_debug_type_t type, const radeon_debug_level_t level) { return RADEON_DEBUG_LEVEL >= level && (type & radeon_enabled_debug_types); } /* * define macro for gcc specific __attribute__ if using alternative compiler */ #ifndef __GNUC__ #define __attribute__(x) /*empty*/ #endif extern void _radeon_print(const radeon_debug_type_t type, const radeon_debug_level_t level, const char* message, ...) __attribute__((format(printf,3,4))); /** * Print out debug message if channel specified by type is enabled * and compile time debugging level is at least as high as level parameter */ #define radeon_print(type, level, ...) do { \ const radeon_debug_level_t _debug_level = (level); \ const radeon_debug_type_t _debug_type = (type); \ /* Compile out if level of message is too high */ \ if (radeon_is_debug_enabled(type, level)) { \ _radeon_print(_debug_type, _debug_level, \ __VA_ARGS__); \ } \ } while(0) /** * printf style function for writing error messages. */ #define radeon_error(...) do { \ radeon_print(RADEON_GENERAL, RADEON_CRITICAL, \ __VA_ARGS__); \ } while(0) /** * printf style function for writing warnings. */ #define radeon_warning(...) do { \ radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, \ __VA_ARGS__); \ } while(0) extern void radeon_init_debug(void); extern void _radeon_debug_add_indent(void); extern void _radeon_debug_remove_indent(void); static inline void radeon_debug_add_indent(void) { if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) { _radeon_debug_add_indent(); } } static inline void radeon_debug_remove_indent(void) { if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) { _radeon_debug_remove_indent(); } } /* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html . I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble with other compilers ... GLUE! */ #define WARN_ONCE(...) do { \ static int __warn_once=1; \ if(__warn_once){ \ radeon_warning("*********************************WARN_ONCE*********************************\n"); \ radeon_warning("File %s function %s line %d\n", \ __FILE__, __FUNCTION__, __LINE__); \ radeon_warning(__VA_ARGS__);\ radeon_warning("***************************************************************************\n"); \ __warn_once=0;\ } \ } while(0) #endif