summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util/p_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util/p_debug.c')
-rw-r--r--src/gallium/auxiliary/util/p_debug.c107
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);
}