X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fp_debug.c;h=951dd5a2d4fbaee93ce473989d703c3bc08821f4;hb=d2ec02f44026244130b4e6f9d87eac6a03a9c6c1;hp=19ad3f4663394ec87c74b610d24c3113fd0158a7;hpb=48ef11d308c395837c1685df6ab701a69507e8b9;p=mesa.git diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 19ad3f46633..951dd5a2d4f 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -26,9 +26,11 @@ **************************************************************************/ +#include "pipe/p_config.h" + #include -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY #include #include #else @@ -39,34 +41,36 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" +#include "pipe/p_format.h" +#include "util/u_string.h" -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY static INLINE void -rpl_EngDebugPrint(const char *format, ...) +_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); -int rpl_snprintf(char *str, size_t size, const char *format, ...); -#define vsnprintf rpl_vsnprintf -#define snprintf rpl_snprintf #endif -void debug_vprintf(const char *format, va_list ap) +void _debug_vprintf(const char *format, va_list ap) { -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY #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); + * our own vsnprintf implementation. It is also very slow, so buffer until + * we find a newline. */ + static char buf[512 + 1] = {'\0'}; + size_t len = strlen(buf); + int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); + if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { + _EngDebugPrint("%s", buf); + buf[0] = '\0'; + } #else /* TODO: Implement debug print for WINCE */ #endif @@ -76,15 +80,7 @@ void debug_vprintf(const char *format, va_list ap) } -void debug_printf(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - debug_vprintf(format, ap); - va_end(ap); -} - - +#ifdef DEBUG void debug_print_blob( const char *name, const void *blob, unsigned size ) @@ -99,72 +95,177 @@ void debug_print_blob( const char *name, debug_printf("%d:\t%08x\n", i, ublob[i]); } } +#endif -/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */ - - -static INLINE void debug_break(void) +void _debug_break(void) { #if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) __asm("int3"); #elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) _asm {int 3}; -#elif defined(WIN32) && !defined(WINCE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) EngDebugBreak(); #else abort(); #endif } -#if defined(WIN32) -ULONG_PTR debug_config_file = 0; -void *mapped_config_file = 0; -enum { - eAssertAbortEn = 0x1, -}; +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +static const char * +find(const char *start, const char *end, char c) +{ + const char *p; + for(p = start; !end || p != end; ++p) { + if(*p == c) + return p; + if(*p < 32) + break; + } + return NULL; +} -/* Check for aborts enabled. */ -static unsigned abort_en() +static int +compare(const char *start, const char *end, const char *s) { - if (!mapped_config_file) - { - /* Open an 8 byte file for configuration data. */ - mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); + const char *p, *q; + for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { + if(*p != *q) + return 0; } + return p == end && *q == '\0'; +} - /* A value of "0" (ascii) in the configuration file will clear the - * first 8 bits in the test byte. - * - * A value of "1" (ascii) in the configuration file will set the - * first bit in the test byte. - * - * A value of "2" (ascii) in the configuration file will set the - * second bit in the test byte. - * - * Currently the only interesting values are 0 and 1, which clear - * and set abort-on-assert behaviour respectively. +static void +copy(char *dst, const char *start, const char *end, size_t n) +{ + const char *p; + char *q; + for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) + *q = *p; + *q = '\0'; +} +#endif + + +const char * +debug_get_option(const char *name, const char *dfault) +{ + const char *result; +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + ULONG_PTR iFile = 0; + const void *pMap = NULL; + const char *sol, *eol, *sep; + static char output[1024]; + + result = dfault; + /* XXX: this creates the file if it does not exists, so it must either be + * disabled on release versions, or put in a less conspicuous place. */ - return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; + pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); + if(pMap) { + sol = (const char *)pMap; + while(1) { + /* TODO: handle LF line endings */ + eol = find(sol, NULL, '\r'); + if(!eol || eol == sol) + break; + sep = find(sol, eol, '='); + if(!sep) + break; + if(compare(sol, sep, name)) { + copy(output, sep + 1, eol, sizeof(output)); + result = output; + break; + } + sol = eol + 2; + } + EngUnmapFile(iFile); + } +#else + + result = getenv(name); + if(!result) + result = dfault; +#endif + + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)"); + + return result; } -#else /* WIN32 */ -static unsigned abort_en() + +boolean +debug_get_bool_option(const char *name, boolean dfault) { - return !GETENV("GALLIUM_ABORT_ON_ASSERT"); + const char *str = debug_get_option(name, NULL); + boolean result; + + if(str == NULL) + result = dfault; + else if(!util_strcmp(str, "n")) + result = FALSE; + else if(!util_strcmp(str, "no")) + result = FALSE; + else if(!util_strcmp(str, "0")) + result = FALSE; + else if(!util_strcmp(str, "f")) + result = FALSE; + else if(!util_strcmp(str, "false")) + result = FALSE; + else + result = TRUE; + + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? "TRUE" : "FALSE"); + + return result; } -#endif -void debug_assert_fail(const char *expr, const char *file, unsigned line) + +long +debug_get_num_option(const char *name, long dfault) { - debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); - if (abort_en()) - { - debug_break(); - } else - { - debug_printf("continuing...\n"); + /* FIXME */ + return dfault; +} + + +unsigned long +debug_get_flags_option(const char *name, + const struct debug_named_value *flags, + unsigned long dfault) +{ + unsigned long result; + const char *str; + + str = debug_get_option(name, NULL); + if(!str) + result = dfault; + else { + result = 0; + while( flags->name ) { + if (!util_strcmp(str, "all") || util_strstr(str, flags->name )) + result |= flags->value; + ++flags; + } } + + debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result); + + return result; +} + + +void _debug_assert_fail(const char *expr, + const char *file, + unsigned line, + const char *function) +{ + _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); + if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) + debug_break(); + else + _debug_printf("continuing...\n"); } @@ -180,7 +281,7 @@ debug_dump_enum(const struct debug_named_value *names, ++names; } - snprintf(rest, sizeof(rest), "0x%08x", value); + util_snprintf(rest, sizeof(rest), "0x%08lx", value); return rest; } @@ -198,10 +299,10 @@ debug_dump_flags(const struct debug_named_value *names, while(names->name) { if((names->value & value) == names->value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; - strncat(output, names->name, sizeof(output)); + util_strncat(output, names->name, sizeof(output)); value &= ~names->value; } ++names; @@ -209,12 +310,12 @@ debug_dump_flags(const struct debug_named_value *names, if (value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; - snprintf(rest, sizeof(rest), "0x%08x", value); - strncat(output, rest, sizeof(output)); + util_snprintf(rest, sizeof(rest), "0x%08lx", value); + util_strncat(output, rest, sizeof(output)); } if(first) @@ -224,3 +325,159 @@ debug_dump_flags(const struct debug_named_value *names, } +static const struct debug_named_value pipe_format_names[] = { +#ifdef DEBUG + DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA), +#endif + DEBUG_NAMED_VALUE_END +}; + +#ifdef DEBUG +void debug_print_format(const char *msg, unsigned fmt ) +{ + debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); +} +#endif + +char *pf_sprint_name( char *str, enum pipe_format format ) +{ + strcpy( str, debug_dump_enum(pipe_format_names, format) ); + return str; +} + + +#ifdef DEBUG +void debug_dump_image(const char *prefix, + unsigned format, unsigned cpp, + unsigned width, unsigned height, + unsigned pitch, + const void *data) +{ +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + static unsigned no = 0; + char filename[256]; + WCHAR wfilename[sizeof(filename)]; + ULONG_PTR iFile = 0; + struct { + unsigned format; + unsigned cpp; + unsigned width; + unsigned height; + } header; + unsigned char *pMap = NULL; + unsigned i; + + util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u%s.raw", ++no, prefix); + for(i = 0; i < sizeof(filename); ++i) + wfilename[i] = (WCHAR)filename[i]; + + pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile); + if(!pMap) + return; + + header.format = format; + header.cpp = cpp; + header.width = width; + header.height = height; + memcpy(pMap, &header, sizeof(header)); + pMap += sizeof(header); + + for(i = 0; i < height; ++i) { + memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width); + pMap += cpp*width; + } + + EngUnmapFile(iFile); +#endif +} +#endif