diff options
Diffstat (limited to 'src/gallium/auxiliary/util/p_debug.c')
-rw-r--r-- | src/gallium/auxiliary/util/p_debug.c | 107 |
1 files changed, 102 insertions, 5 deletions
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index b9607a6ba7..09cabdae25 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -36,14 +36,37 @@ #include <stdlib.h> #endif -#include "pipe/p_debug.h" #include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + + +#ifdef WIN32 +static INLINE void +rpl_EngDebugPrint(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + EngDebugPrint("", (PCHAR)format, ap); + va_end(ap); +} + +int rpl_vsnprintf(char *, size_t, const char *, va_list); +#endif void debug_vprintf(const char *format, va_list ap) { #ifdef WIN32 - EngDebugPrint("Gallium3D: ", (PCHAR)format, ap); +#ifndef WINCE + /* EngDebugPrint does not handle float point arguments, so we need to use + * our own vsnprintf implementation */ + char buf[512 + 1]; + rpl_vsnprintf(buf, sizeof(buf), format, ap); + rpl_EngDebugPrint("%s", buf); +#else + /* TODO: Implement debug print for WINCE */ +#endif #else vfprintf(stderr, format, ap); #endif @@ -59,18 +82,92 @@ void debug_printf(const char *format, ...) } -static INLINE void debug_abort(void) +/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */ + + +static INLINE void debug_break(void) { -#ifdef WIN32 +#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) + __asm("int3"); +#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) + _asm {int 3}; +#elif defined(WIN32) && !defined(WINCE) EngDebugBreak(); #else abort(); #endif } +#if defined(WIN32) +ULONG_PTR debug_config_file = 0; +void *mapped_config_file = 0; + +enum { + eAssertAbortEn = 0x1, +}; + +/* Check for aborts enabled. */ +static unsigned abort_en() +{ + if (!mapped_config_file) + { + /* Open an 8 byte file for configuration data. */ + mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); + } + /* An value of "0" (ascii) in the configuration file will clear the first 8 bits in the test byte. */ + /* An value of "1" (ascii) in the configuration file will set the first bit in the test byte. */ + /* An value of "2" (ascii) in the configuration file will set the second bit in the test byte. */ + return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; +} +#else /* WIN32 */ +static unsigned abort_en() +{ + return !GETENV("GALLIUM_ABORT_ON_ASSERT"); +} +#endif void debug_assert_fail(const char *expr, const char *file, unsigned line) { debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); - debug_abort(); + if (abort_en()) + { + debug_break(); + } else + { + debug_printf("continuing...\n"); + } +} + + +#define DEBUG_MASK_TABLE_SIZE 256 + + +/** + * Mask hash table. + * + * For now we just take the lower bits of the key, and do no attempt to solve + * collisions. Use a proper hash table when we have dozens of drivers. + */ +static uint32_t debug_mask_table[DEBUG_MASK_TABLE_SIZE]; + + +void debug_mask_set(uint32_t uuid, uint32_t mask) +{ + unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); + debug_mask_table[hash] = mask; +} + + +uint32_t debug_mask_get(uint32_t uuid) +{ + unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); + return debug_mask_table[hash]; +} + + +void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_list ap) +{ + uint32_t mask = debug_mask_get(uuid); + if(mask & what) + debug_vprintf(format, ap); } |