X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ftrace%2Ftr_dump.c;h=48c8914f7bb495282b30116fdfd31fa72e1e814f;hb=9a91ce94484789424361f22387ba15688d6bcc7d;hp=a0ead0ded3344fc520015be88a3c4cbe212e3959;hpb=658b1bdb1cc5f9910be910dc156a2e81ed999756;p=mesa.git diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index a0ead0ded33..48c8914f7bb 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -29,50 +29,58 @@ /** * @file * Trace dumping functions. - * + * * For now we just use standard XML for dumping the trace calls, as this is - * simple to write, parse, and visually inspect, but the actual representation - * is abstracted out of this file, so that we can switch to a binary + * simple to write, parse, and visually inspect, but the actual representation + * is abstracted out of this file, so that we can switch to a binary * representation if/when it becomes justified. - * - * @author Jose Fonseca + * + * @author Jose Fonseca */ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) +#include #include -#endif #include "pipe/p_compiler.h" -#include "pipe/p_debug.h" +#include "os/os_thread.h" +#include "os/os_time.h" +#include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_string.h" -#include "util/u_stream.h" +#include "util/u_math.h" +#include "util/u_format.h" #include "tr_dump.h" +#include "tr_screen.h" +#include "tr_texture.h" -static struct util_stream *stream = NULL; +static FILE *stream = NULL; static unsigned refcount = 0; +pipe_static_mutex(call_mutex); +static long unsigned call_no = 0; +static boolean dumping = FALSE; -static INLINE void +static INLINE void trace_dump_write(const char *buf, size_t size) { - if(stream) - util_stream_write(stream, buf, size); + if (stream) { + fwrite(buf, size, 1, stream); + } } -static INLINE void +static INLINE void trace_dump_writes(const char *s) { trace_dump_write(s, strlen(s)); } -static INLINE void +static INLINE void trace_dump_writef(const char *format, ...) { static char buf[1024]; @@ -85,8 +93,8 @@ trace_dump_writef(const char *format, ...) } -static INLINE void -trace_dump_escape(const char *str) +static INLINE void +trace_dump_escape(const char *str) { const unsigned char *p = (const unsigned char *)str; unsigned char c; @@ -109,7 +117,7 @@ trace_dump_escape(const char *str) } -static INLINE void +static INLINE void trace_dump_indent(unsigned level) { unsigned i; @@ -118,14 +126,14 @@ trace_dump_indent(unsigned level) } -static INLINE void -trace_dump_newline(void) +static INLINE void +trace_dump_newline(void) { trace_dump_writes("\n"); } -static INLINE void +static INLINE void trace_dump_tag(const char *name) { trace_dump_writes("<"); @@ -134,7 +142,7 @@ trace_dump_tag(const char *name) } -static INLINE void +static INLINE void trace_dump_tag_begin(const char *name) { trace_dump_writes("<"); @@ -142,8 +150,8 @@ trace_dump_tag_begin(const char *name) trace_dump_writes(">"); } -static INLINE void -trace_dump_tag_begin1(const char *name, +static INLINE void +trace_dump_tag_begin1(const char *name, const char *attr1, const char *value1) { trace_dump_writes("<"); @@ -156,8 +164,8 @@ trace_dump_tag_begin1(const char *name, } -static INLINE void -trace_dump_tag_begin2(const char *name, +static INLINE void +trace_dump_tag_begin2(const char *name, const char *attr1, const char *value1, const char *attr2, const char *value2) { @@ -175,8 +183,8 @@ trace_dump_tag_begin2(const char *name, } -static INLINE void -trace_dump_tag_begin3(const char *name, +static INLINE void +trace_dump_tag_begin3(const char *name, const char *attr1, const char *value1, const char *attr2, const char *value2, const char *attr3, const char *value3) @@ -207,48 +215,80 @@ trace_dump_tag_end(const char *name) trace_dump_writes(">"); } -static void +void +trace_dump_trace_flush(void) +{ + if(stream) { + fflush(stream); + } +} + +static void trace_dump_trace_close(void) { if(stream) { trace_dump_writes("\n"); - util_stream_close(stream); + fclose(stream); stream = NULL; refcount = 0; + call_no = 0; + } +} + + +static void +trace_dump_call_time(int64_t time) +{ + if (stream) { + trace_dump_indent(2); + trace_dump_tag_begin("time"); + trace_dump_int(time); + trace_dump_tag_end("time"); + trace_dump_newline(); } } -boolean trace_dump_trace_begin() + +boolean +trace_dump_trace_begin(void) { const char *filename; - + filename = debug_get_option("GALLIUM_TRACE", NULL); if(!filename) return FALSE; - + if(!stream) { - - stream = util_stream_create(filename, 0); - if(!stream) - return FALSE; - + + if (strcmp(filename, "stderr") == 0) { + stream = stderr; + } + else if (strcmp(filename, "stdout") == 0) { + stream = stdout; + } + else { + stream = fopen(filename, "wt"); + if (!stream) + return FALSE; + } + trace_dump_writes("\n"); trace_dump_writes("\n"); trace_dump_writes("\n"); - -#if defined(PIPE_OS_LINUX) - /* Linux applications rarely cleanup GL / Gallium resources so catch - * application exit here */ + +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) + /* Linux applications rarely cleanup GL / Gallium resources so catch + * application exit here */ atexit(trace_dump_trace_close); #endif } - + ++refcount; - + return TRUE; } -boolean trace_dump_enabled(void) +boolean trace_dump_trace_enabled(void) { return stream ? TRUE : FALSE; } @@ -260,71 +300,193 @@ void trace_dump_trace_end(void) trace_dump_trace_close(); } -void trace_dump_call_begin(const char *klass, const char *method) +/* + * Call lock + */ + +void trace_dump_call_lock(void) +{ + pipe_mutex_lock(call_mutex); +} + +void trace_dump_call_unlock(void) +{ + pipe_mutex_unlock(call_mutex); +} + +/* + * Dumping control + */ + +void trace_dumping_start_locked(void) +{ + dumping = TRUE; +} + +void trace_dumping_stop_locked(void) +{ + dumping = FALSE; +} + +boolean trace_dumping_enabled_locked(void) +{ + return dumping; +} + +void trace_dumping_start(void) +{ + pipe_mutex_lock(call_mutex); + trace_dumping_start_locked(); + pipe_mutex_unlock(call_mutex); +} + +void trace_dumping_stop(void) +{ + pipe_mutex_lock(call_mutex); + trace_dumping_stop_locked(); + pipe_mutex_unlock(call_mutex); +} + +boolean trace_dumping_enabled(void) +{ + boolean ret; + pipe_mutex_lock(call_mutex); + ret = trace_dumping_enabled_locked(); + pipe_mutex_unlock(call_mutex); + return ret; +} + +/* + * Dump functions + */ + +static int64_t call_start_time = 0; + +void trace_dump_call_begin_locked(const char *klass, const char *method) { + if (!dumping) + return; + + ++call_no; trace_dump_indent(1); - trace_dump_tag_begin2("call", "class", klass, "method", method); + trace_dump_writes(""); trace_dump_newline(); + + call_start_time = os_time_get(); } -void trace_dump_call_end(void) +void trace_dump_call_end_locked(void) { + int64_t call_end_time; + + if (!dumping) + return; + + call_end_time = os_time_get(); + + trace_dump_call_time(call_end_time - call_start_time); trace_dump_indent(1); trace_dump_tag_end("call"); trace_dump_newline(); - util_stream_flush(stream); + fflush(stream); +} + +void trace_dump_call_begin(const char *klass, const char *method) +{ + pipe_mutex_lock(call_mutex); + trace_dump_call_begin_locked(klass, method); +} + +void trace_dump_call_end(void) +{ + trace_dump_call_end_locked(); + pipe_mutex_unlock(call_mutex); } void trace_dump_arg_begin(const char *name) { + if (!dumping) + return; + trace_dump_indent(2); trace_dump_tag_begin1("arg", "name", name); } void trace_dump_arg_end(void) { + if (!dumping) + return; + trace_dump_tag_end("arg"); trace_dump_newline(); } void trace_dump_ret_begin(void) { + if (!dumping) + return; + trace_dump_indent(2); trace_dump_tag_begin("ret"); } void trace_dump_ret_end(void) { + if (!dumping) + return; + trace_dump_tag_end("ret"); trace_dump_newline(); } void trace_dump_bool(int value) { + if (!dumping) + return; + trace_dump_writef("%c", value ? '1' : '0'); } void trace_dump_int(long long int value) { + if (!dumping) + return; + trace_dump_writef("%lli", value); } void trace_dump_uint(long long unsigned value) { + if (!dumping) + return; + trace_dump_writef("%llu", value); } void trace_dump_float(double value) { + if (!dumping) + return; + trace_dump_writef("%g", value); } void trace_dump_bytes(const void *data, - long unsigned size) + size_t size) { static const char hex_table[16] = "0123456789ABCDEF"; const uint8_t *p = data; - long unsigned i; + size_t i; + + if (!dumping) + return; + trace_dump_writes(""); for(i = 0; i < size; ++i) { uint8_t byte = *p++; @@ -336,8 +498,30 @@ void trace_dump_bytes(const void *data, trace_dump_writes(""); } +void trace_dump_box_bytes(const void *data, + enum pipe_format format, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride) +{ + size_t size; + + if (slice_stride) + size = box->depth * slice_stride; + else if (stride) + size = util_format_get_nblocksy(format, box->height) * stride; + else { + size = util_format_get_nblocksx(format, box->width) * util_format_get_blocksize(format); + } + + trace_dump_bytes(data, size); +} + void trace_dump_string(const char *str) { + if (!dumping) + return; + trace_dump_writes(""); trace_dump_escape(str); trace_dump_writes(""); @@ -345,6 +529,9 @@ void trace_dump_string(const char *str) void trace_dump_enum(const char *value) { + if (!dumping) + return; + trace_dump_writes(""); trace_dump_escape(value); trace_dump_writes(""); @@ -352,53 +539,123 @@ void trace_dump_enum(const char *value) void trace_dump_array_begin(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_array_end(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_elem_begin(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_elem_end(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_struct_begin(const char *name) { + if (!dumping) + return; + trace_dump_writef("", name); } void trace_dump_struct_end(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_member_begin(const char *name) { + if (!dumping) + return; + trace_dump_writef("", name); } void trace_dump_member_end(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_null(void) { + if (!dumping) + return; + trace_dump_writes(""); } void trace_dump_ptr(const void *value) { + if (!dumping) + return; + if(value) trace_dump_writef("0x%08lx", (unsigned long)(uintptr_t)value); else trace_dump_null(); } + + +void trace_dump_resource_ptr(struct pipe_resource *_resource) +{ + if (!dumping) + return; + + if (_resource) { + struct trace_resource *tr_resource = trace_resource(_resource); + trace_dump_ptr(tr_resource->resource); + } else { + trace_dump_null(); + } +} + +void trace_dump_surface_ptr(struct pipe_surface *_surface) +{ + if (!dumping) + return; + + if (_surface) { + struct trace_surface *tr_surf = trace_surface(_surface); + trace_dump_ptr(tr_surf->surface); + } else { + trace_dump_null(); + } +} + +void trace_dump_transfer_ptr(struct pipe_transfer *_transfer) +{ + if (!dumping) + return; + + if (_transfer) { + struct trace_transfer *tr_tran = trace_transfer(_transfer); + trace_dump_ptr(tr_tran->transfer); + } else { + trace_dump_null(); + } +}