summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/util/p_debug.c34
-rw-r--r--src/gallium/include/pipe/p_debug.h64
2 files changed, 98 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 93bfaea3939..04e55dd91de 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -103,3 +103,37 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line)
debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr);
debug_break();
}
+
+
+#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);
+}
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index a14a1fc5f6c..f45363f3558 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -41,6 +41,8 @@
#include <stdarg.h>
+#include "p_compiler.h"
+
#ifdef __cplusplus
extern "C" {
@@ -93,6 +95,68 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line);
#define assert(expr) debug_assert(expr)
+/**
+ * Set a channel's debug mask.
+ *
+ * uuid is just a random 32 bit integer that uniquely identifies the debugging
+ * channel.
+ *
+ * @note Due to current implementation issues, make sure the lower 8 bits of
+ * UUID are unique.
+ */
+void debug_mask_set(uint32_t uuid, uint32_t mask);
+
+
+uint32_t debug_mask_get(uint32_t uuid);
+
+
+/**
+ * Conditional debug output.
+ *
+ * This is just a generalization of the debug filtering mechanism used
+ * throughout Gallium.
+ *
+ * You use this function as:
+ *
+ * @code
+ * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier
+ *
+ * static inline mydriver_debug(uint32_t what, const char *format, ...)
+ * {
+ * #ifdef DEBUG
+ * va_list ap;
+ * va_start(ap, format);
+ * debug_mask_vprintf(MYDRIVER_UUID, what, format, ap);
+ * va_end(ap);
+ * #endif
+ * }
+ *
+ * ...
+ *
+ * debug_mask_set(MYDRIVER_UUID,
+ * MYDRIVER_DEBUG_THIS |
+ * MYDRIVER_DEBUG_THAT |
+ * ... );
+ *
+ * ...
+ *
+ * mydriver_debug(MYDRIVER_DEBUG_THIS,
+ * "this and this happened\n");
+ *
+ * mydriver_debug(MYDRIVER_DEBUG_THAT,
+ * "that = %f\n", that);
+ * ...
+ * @endcode
+ *
+ * You can also define several variants of mydriver_debug, with hardcoded what.
+ * Note that although macros with variable number of arguments would accomplish
+ * more in less code, they are not portable.
+ */
+void debug_mask_vprintf(uint32_t uuid,
+ uint32_t what,
+ const char *format,
+ va_list ap);
+
#ifdef __cplusplus
}
#endif