X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ftrace%2Ftr_dump.c;h=753b92d8b54012a31bf10fa690bc7c3166c718dc;hb=a8890494001c9bac6a4ce67247d71383dde835f8;hp=f9ee7876cbe2a2d63021e9491b61827a6bfc8f01;hpb=d2cdf6253cf06fbed6a5ca7ae17ddadf644afe26;p=mesa.git diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index f9ee7876cbe..753b92d8b54 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,37 +35,41 @@ * 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) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) +#include #include -#endif #include "pipe/p_compiler.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" -#include "tr_buffer.h" -static struct util_stream *stream = NULL; -static unsigned refcount = 0; +static boolean close_stream = FALSE; +static FILE *stream = NULL; +pipe_static_mutex(call_mutex); static long unsigned call_no = 0; +static boolean dumping = FALSE; 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); + } } @@ -211,19 +215,44 @@ trace_dump_tag_end(const char *name) trace_dump_writes(">"); } +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); - stream = NULL; - refcount = 0; + if (close_stream) { + fclose(stream); + close_stream = FALSE; + stream = NULL; + } call_no = 0; } } -boolean trace_dump_trace_begin() + +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(void) { const char *filename; @@ -233,110 +262,227 @@ boolean trace_dump_trace_begin() if(!stream) { - stream = util_stream_create(filename, 0); - if(!stream) - return FALSE; + if (strcmp(filename, "stderr") == 0) { + close_stream = FALSE; + stream = stderr; + } + else if (strcmp(filename, "stdout") == 0) { + close_stream = FALSE; + stream = stdout; + } + else { + close_stream = TRUE; + 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) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) - /* Linux applications rarely cleanup GL / Gallium resources so catch - * application exit here */ + /* Many applications don't exit cleanly, others may create and destroy a + * screen multiple times, so we only write tag and close at exit + * time. + */ atexit(trace_dump_trace_close); -#endif } - ++refcount; - return TRUE; } -boolean trace_dump_enabled(void) +boolean trace_dump_trace_enabled(void) { return stream ? TRUE : FALSE; } -void trace_dump_trace_end(void) +/* + * Call lock + */ + +void trace_dump_call_lock(void) { - if(stream) - if(!--refcount) - trace_dump_trace_close(); + pipe_mutex_lock(call_mutex); } -void trace_dump_call_begin(const char *klass, const char *method) +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_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++; @@ -348,8 +494,39 @@ void trace_dump_bytes(const void *data, trace_dump_writes(""); } +void trace_dump_box_bytes(const void *data, + struct pipe_resource *resource, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride) +{ + size_t size; + + /* + * Only dump buffer transfers to avoid huge files. + * TODO: Make this run-time configurable + */ + if (resource->target != PIPE_BUFFER) { + size = 0; + } else { + enum pipe_format format = resource->format; + 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(""); @@ -357,6 +534,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(""); @@ -364,73 +544,96 @@ 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_buffer_ptr(struct pipe_buffer *_buffer) -{ - if (_buffer) { - struct trace_screen *tr_scr = trace_screen(_buffer->screen); - struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer); - trace_dump_ptr(tr_buf->buffer); - } else { - trace_dump_null(); - } -} -void trace_dump_texture_ptr(struct pipe_texture *_texture) +void trace_dump_resource_ptr(struct pipe_resource *_resource) { - if (_texture) { - struct trace_texture *tr_tex = trace_texture(_texture); - trace_dump_ptr(tr_tex->texture); + if (!dumping) + return; + + if (_resource) { + struct trace_resource *tr_resource = trace_resource(_resource); + trace_dump_ptr(tr_resource->resource); } else { trace_dump_null(); } @@ -438,6 +641,9 @@ void trace_dump_texture_ptr(struct pipe_texture *_texture) 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); @@ -448,6 +654,9 @@ void trace_dump_surface_ptr(struct pipe_surface *_surface) 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);