diff options
Diffstat (limited to 'src/gallium/drivers/trace')
| -rw-r--r-- | src/gallium/drivers/trace/README | 64 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/SConscript | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_context.c | 1072 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_context.h | 68 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_dump.c | 404 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_dump.h | 132 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_screen.c | 469 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_screen.h | 60 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_state.c | 464 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_state.h | 76 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_texture.c | 112 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_texture.h | 95 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_winsys.c | 497 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/tr_winsys.h | 76 | ||||
| -rw-r--r-- | src/gallium/drivers/trace/trace.xsl | 185 | 
15 files changed, 3790 insertions, 0 deletions
| diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README new file mode 100644 index 0000000000..f0e1cd596d --- /dev/null +++ b/src/gallium/drivers/trace/README @@ -0,0 +1,64 @@ +                             TRACE PIPE DRIVER + + += About = + +This directory contains a Gallium3D pipe driver which traces all incoming calls. + + += Build Instructions = + +To build, invoke scons on the top dir as +  + scons statetrackers=mesa drivers=softpipe,i965simple,trace winsys=xlib + + += Usage = + +To use do + + ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + +ensure the right libGL.so is being picked by doing + + ldd progs/trivial/tri  + +and then try running + + GALLIUM_TRACE=tri.trace progs/trivial/tri + +which should create a tri.trace file, which is an XML file. You can view copying  +trace.xsl to the same directory, and opening with a XSLT capable browser such as  +Firefox or Internet Explorer. + + += Integrating = + +You can integrate the trace pipe driver either inside the state tracker or the  +winsys. The procedure on both cases is the same. Let's assume you have a  +pipe_screen and a pipe_context pair obtained by the usual means (variable and  +function names are just for illustration purposes): + +  real_screen = real_screen_create(...); +   +  real_context = real_context_create(...); +   +The trace screen and pipe_context is then created by doing + +  trace_screen = trace_screen_create(real_screen); +   +  trace_context = trace_context_create(trace_screen, real_context); +   +You can then simply use trace_screen and trace_context instead of real_screen +and real_context. + +Do not call trace_winsys_create. Simply pass trace_screen->winsys or  +trace_context->winsys in places you would pass winsys. + +You can create as many contexts you wish. Just ensure that you don't mistake  +trace_screen with real_screen when creating them. + + +-- +Jose Fonseca <jrfonseca@tungstengraphics.com> diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript new file mode 100644 index 0000000000..0a6bfb8f4c --- /dev/null +++ b/src/gallium/drivers/trace/SConscript @@ -0,0 +1,16 @@ +Import('*') + +env = env.Clone() + +trace = env.ConvenienceLibrary( +    target = 'trace', +    source = [ +        'tr_context.c', +        'tr_dump.c', +        'tr_screen.c', +        'tr_state.c', +        'tr_texture.c', +        'tr_winsys.c', +    ]) + +Export('trace')
\ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c new file mode 100644 index 0000000000..1dd7719379 --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.c @@ -0,0 +1,1072 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#include "util/u_memory.h" +#include "pipe/p_screen.h" + +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_screen.h" +#include "tr_texture.h" +#include "tr_winsys.h" +#include "tr_context.h" + + +static INLINE struct pipe_texture *  +trace_texture_unwrap(struct trace_context *tr_ctx, +                     struct pipe_texture *texture) +{ +   struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);  +   struct trace_texture *tr_tex; +    +   if(!texture) +      return NULL; +    +   tr_tex = trace_texture(tr_scr, texture); +    +   assert(tr_tex->texture); +   assert(tr_tex->texture->screen == tr_scr->screen); +   return tr_tex->texture; +} + + +static INLINE struct pipe_surface *  +trace_surface_unwrap(struct trace_context *tr_ctx, +                     struct pipe_surface *surface) +{ +   struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);  +   struct trace_texture *tr_tex; +   struct trace_surface *tr_surf; +    +   if(!surface) +      return NULL; + +   assert(surface->texture); +   if(!surface->texture) +      return surface; +    +   tr_tex = trace_texture(tr_scr, surface->texture); +   tr_surf = trace_surface(tr_tex, surface); +    +   assert(tr_surf->surface); +   assert(tr_surf->surface->texture->screen == tr_scr->screen); +   return tr_surf->surface; +} + + +static INLINE void +trace_context_set_edgeflags(struct pipe_context *_pipe, +                            const unsigned *bitfield) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_edgeflags"); +    +   trace_dump_arg(ptr, pipe); +   /* FIXME: we don't know how big this array is */ +   trace_dump_arg(ptr, bitfield); + +   pipe->set_edgeflags(pipe, bitfield);; + +   trace_dump_call_end(); +} + + +static INLINE boolean +trace_context_draw_arrays(struct pipe_context *_pipe, +                          unsigned mode, unsigned start, unsigned count) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   boolean result; + +   trace_dump_call_begin("pipe_context", "draw_arrays"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, mode); +   trace_dump_arg(uint, start); +   trace_dump_arg(uint, count); + +   result = pipe->draw_arrays(pipe, mode, start, count);; + +   trace_dump_ret(bool, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE boolean +trace_context_draw_elements(struct pipe_context *_pipe, +                          struct pipe_buffer *indexBuffer, +                          unsigned indexSize, +                          unsigned mode, unsigned start, unsigned count) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   boolean result; + +   trace_winsys_user_buffer_update(_pipe->winsys, indexBuffer); + +   trace_dump_call_begin("pipe_context", "draw_elements"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, indexBuffer); +   trace_dump_arg(uint, indexSize); +   trace_dump_arg(uint, mode); +   trace_dump_arg(uint, start); +   trace_dump_arg(uint, count); + +   result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);; + +   trace_dump_ret(bool, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE boolean +trace_context_draw_range_elements(struct pipe_context *_pipe, +                                  struct pipe_buffer *indexBuffer, +                                  unsigned indexSize, +                                  unsigned minIndex, +                                  unsigned maxIndex, +                                  unsigned mode,  +                                  unsigned start,  +                                  unsigned count) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   boolean result; + +   trace_winsys_user_buffer_update(_pipe->winsys, indexBuffer); + +   trace_dump_call_begin("pipe_context", "draw_range_elements"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, indexBuffer); +   trace_dump_arg(uint, indexSize); +   trace_dump_arg(uint, minIndex); +   trace_dump_arg(uint, maxIndex); +   trace_dump_arg(uint, mode); +   trace_dump_arg(uint, start); +   trace_dump_arg(uint, count); + +   result = pipe->draw_range_elements(pipe,  +                                      indexBuffer,  +                                      indexSize, minIndex, maxIndex,  +                                      mode, start, count); +    +   trace_dump_ret(bool, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE struct pipe_query * +trace_context_create_query(struct pipe_context *_pipe, +                           unsigned query_type) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   struct pipe_query *result; + +   trace_dump_call_begin("pipe_context", "create_query"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, query_type); + +   result = pipe->create_query(pipe, query_type);; + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_destroy_query(struct pipe_context *_pipe, +                            struct pipe_query *query) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "destroy_query"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, query); + +   pipe->destroy_query(pipe, query);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_begin_query(struct pipe_context *_pipe,  +                          struct pipe_query *query) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "begin_query"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, query); + +   pipe->begin_query(pipe, query);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_end_query(struct pipe_context *_pipe,  +                        struct pipe_query *query) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "end_query"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, query); + +   pipe->end_query(pipe, query); + +   trace_dump_call_end(); +} + + +static INLINE boolean +trace_context_get_query_result(struct pipe_context *_pipe,  +                               struct pipe_query *query, +                               boolean wait, +                               uint64 *presult) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   uint64 result; +   boolean _result; + +   trace_dump_call_begin("pipe_context", "get_query_result"); + +   trace_dump_arg(ptr, pipe); + +   _result = pipe->get_query_result(pipe, query, wait, presult);; +   result = *presult; + +   trace_dump_arg(uint, result); +   trace_dump_ret(bool, _result); +    +   trace_dump_call_end(); +    +   return _result; +} + + +static INLINE void * +trace_context_create_blend_state(struct pipe_context *_pipe, +                                 const struct pipe_blend_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_blend_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(blend_state, state); + +   result = pipe->create_blend_state(pipe, state);; + +   trace_dump_ret(ptr, result); + +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_blend_state(struct pipe_context *_pipe,  +                               void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_blend_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->bind_blend_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_blend_state(struct pipe_context *_pipe,  +                                 void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_blend_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_blend_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void * +trace_context_create_sampler_state(struct pipe_context *_pipe, +                                   const struct pipe_sampler_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_sampler_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(sampler_state, state); + +   result = pipe->create_sampler_state(pipe, state);; + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_sampler_states(struct pipe_context *_pipe,  +                                  unsigned num_states, void **states) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_sampler_states"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, num_states); +   trace_dump_arg_array(ptr, states, num_states); + +   pipe->bind_sampler_states(pipe, num_states, states);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_sampler_state(struct pipe_context *_pipe,  +                                   void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_sampler_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_sampler_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void * +trace_context_create_rasterizer_state(struct pipe_context *_pipe, +                                      const struct pipe_rasterizer_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_rasterizer_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(rasterizer_state, state); + +   result = pipe->create_rasterizer_state(pipe, state);; + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_rasterizer_state(struct pipe_context *_pipe,  +                                    void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_rasterizer_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->bind_rasterizer_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_rasterizer_state(struct pipe_context *_pipe,  +                                      void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_rasterizer_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_rasterizer_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void * +trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, +                                               const struct pipe_depth_stencil_alpha_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state"); + +   result = pipe->create_depth_stencil_alpha_state(pipe, state);; + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(depth_stencil_alpha_state, state); +    +   trace_dump_ret(ptr, result); + +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,  +                                             void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_depth_stencil_alpha_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->bind_depth_stencil_alpha_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,  +                                               void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_depth_stencil_alpha_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_depth_stencil_alpha_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void * +trace_context_create_fs_state(struct pipe_context *_pipe, +                              const struct pipe_shader_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_fs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(shader_state, state); + +   result = pipe->create_fs_state(pipe, state);; + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_fs_state(struct pipe_context *_pipe,  +                            void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_fs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->bind_fs_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_fs_state(struct pipe_context *_pipe,  +                              void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_fs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_fs_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void * +trace_context_create_vs_state(struct pipe_context *_pipe, +                              const struct pipe_shader_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   void * result; + +   trace_dump_call_begin("pipe_context", "create_vs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(shader_state, state); + +   result = pipe->create_vs_state(pipe, state);; + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static INLINE void +trace_context_bind_vs_state(struct pipe_context *_pipe,  +                            void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "bind_vs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->bind_vs_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_delete_vs_state(struct pipe_context *_pipe,  +                              void *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "delete_vs_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, state); + +   pipe->delete_vs_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_blend_color(struct pipe_context *_pipe, +                              const struct pipe_blend_color *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_blend_color"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(blend_color, state); + +   pipe->set_blend_color(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_clip_state(struct pipe_context *_pipe, +                             const struct pipe_clip_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_clip_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(clip_state, state); + +   pipe->set_clip_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_constant_buffer(struct pipe_context *_pipe, +                                  uint shader, uint index, +                                  const struct pipe_constant_buffer *buffer) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_winsys_user_buffer_update(_pipe->winsys, (struct pipe_buffer *)buffer); +    +   trace_dump_call_begin("pipe_context", "set_constant_buffer"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, shader); +   trace_dump_arg(uint, index); +   trace_dump_arg(constant_buffer, buffer); + +   pipe->set_constant_buffer(pipe, shader, index, buffer);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_framebuffer_state(struct pipe_context *_pipe, +                                    const struct pipe_framebuffer_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   struct pipe_framebuffer_state unwrapped_state; +   unsigned i; +    +   /* Unwrap the input state */ +   memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); +   for(i = 0; i < state->num_cbufs; ++i) +      unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]); +   for(i = state->num_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i) +      unwrapped_state.cbufs[i] = NULL; +   unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf); +   state = &unwrapped_state; +    +   trace_dump_call_begin("pipe_context", "set_framebuffer_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(framebuffer_state, state); + +   pipe->set_framebuffer_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_polygon_stipple(struct pipe_context *_pipe, +                                  const struct pipe_poly_stipple *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_polygon_stipple"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(poly_stipple, state); + +   pipe->set_polygon_stipple(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_scissor_state(struct pipe_context *_pipe, +                                const struct pipe_scissor_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_scissor_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(scissor_state, state); + +   pipe->set_scissor_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_viewport_state(struct pipe_context *_pipe, +                                 const struct pipe_viewport_state *state) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_viewport_state"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(viewport_state, state); + +   pipe->set_viewport_state(pipe, state);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_sampler_textures(struct pipe_context *_pipe, +                                   unsigned num_textures, +                                   struct pipe_texture **textures) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; +   unsigned i; +    +   for(i = 0; i < num_textures; ++i) +      unwrapped_textures[i] = trace_texture_unwrap(tr_ctx, textures[i]); +   textures = unwrapped_textures; + +   trace_dump_call_begin("pipe_context", "set_sampler_textures"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, num_textures); +   trace_dump_arg_array(ptr, textures, num_textures); + +   pipe->set_sampler_textures(pipe, num_textures, textures);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_vertex_buffers(struct pipe_context *_pipe, +                                 unsigned num_buffers, +                                 const struct pipe_vertex_buffer *buffers) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; +   unsigned i; + +   for(i = 0; i < num_buffers; ++i) +      trace_winsys_user_buffer_update(_pipe->winsys, buffers[i].buffer); + +   trace_dump_call_begin("pipe_context", "set_vertex_buffers"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, num_buffers); +    +   trace_dump_arg_begin("buffers"); +   trace_dump_struct_array(vertex_buffer, buffers, num_buffers); +   trace_dump_arg_end(); + +   pipe->set_vertex_buffers(pipe, num_buffers, buffers);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_vertex_elements(struct pipe_context *_pipe, +                                  unsigned num_elements, +                                  const struct pipe_vertex_element *elements) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "set_vertex_elements"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, num_elements); + +   trace_dump_arg_begin("elements"); +   trace_dump_struct_array(vertex_element, elements, num_elements); +   trace_dump_arg_end(); + +   pipe->set_vertex_elements(pipe, num_elements, elements);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_surface_copy(struct pipe_context *_pipe, +                           boolean do_flip, +                           struct pipe_surface *dest, +                           unsigned destx, unsigned desty, +                           struct pipe_surface *src, +                           unsigned srcx, unsigned srcy, +                           unsigned width, unsigned height) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   dest = trace_surface_unwrap(tr_ctx, dest); +   src = trace_surface_unwrap(tr_ctx, src); +    +   trace_dump_call_begin("pipe_context", "surface_copy"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(bool, do_flip); +   trace_dump_arg(ptr, dest); +   trace_dump_arg(uint, destx); +   trace_dump_arg(uint, desty); +   trace_dump_arg(ptr, src); +   trace_dump_arg(uint, srcx); +   trace_dump_arg(uint, srcy); +   trace_dump_arg(uint, width); +   trace_dump_arg(uint, height); + +   pipe->surface_copy(pipe, do_flip,  +                      dest, destx, desty,  +                      src, srcx, srcy, width, height); +    +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_surface_fill(struct pipe_context *_pipe, +                           struct pipe_surface *dst, +                           unsigned dstx, unsigned dsty, +                           unsigned width, unsigned height, +                           unsigned value) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   dst = trace_surface_unwrap(tr_ctx, dst); + +   trace_dump_call_begin("pipe_context", "surface_fill"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, dst); +   trace_dump_arg(uint, dstx); +   trace_dump_arg(uint, dsty); +   trace_dump_arg(uint, width); +   trace_dump_arg(uint, height); + +   pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_clear(struct pipe_context *_pipe,  +                    struct pipe_surface *surface, +                    unsigned clearValue) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   surface = trace_surface_unwrap(tr_ctx, surface); + +   trace_dump_call_begin("pipe_context", "clear"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, surface); +   trace_dump_arg(uint, clearValue); + +   pipe->clear(pipe, surface, clearValue);; + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_flush(struct pipe_context *_pipe, +                    unsigned flags, +                    struct pipe_fence_handle **fence) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "flush"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(uint, flags); + +   pipe->flush(pipe, flags, fence);; + +   if(fence) +      trace_dump_ret(ptr, *fence); + +   trace_dump_call_end(); +} + + +static INLINE void +trace_context_destroy(struct pipe_context *_pipe) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct pipe_context *pipe = tr_ctx->pipe; + +   trace_dump_call_begin("pipe_context", "destroy"); + +   trace_dump_arg(ptr, pipe); + +   pipe->destroy(pipe); +    +   trace_dump_call_end(); + +   FREE(tr_ctx); +} + + +struct pipe_context * +trace_context_create(struct pipe_screen *screen,  +                     struct pipe_context *pipe) +{ +   struct trace_context *tr_ctx; +    +   if(!pipe) +      goto error1; +    +   if(!trace_dump_enabled()) +      goto error1; +    +   tr_ctx = CALLOC_STRUCT(trace_context); +   if(!tr_ctx) +      goto error1; + +   tr_ctx->base.winsys = screen->winsys; +   tr_ctx->base.screen = screen; +   tr_ctx->base.destroy = trace_context_destroy; +   tr_ctx->base.set_edgeflags = trace_context_set_edgeflags; +   tr_ctx->base.draw_arrays = trace_context_draw_arrays; +   tr_ctx->base.draw_elements = trace_context_draw_elements; +   tr_ctx->base.draw_range_elements = trace_context_draw_range_elements; +   tr_ctx->base.create_query = trace_context_create_query; +   tr_ctx->base.destroy_query = trace_context_destroy_query; +   tr_ctx->base.begin_query = trace_context_begin_query; +   tr_ctx->base.end_query = trace_context_end_query; +   tr_ctx->base.get_query_result = trace_context_get_query_result; +   tr_ctx->base.create_blend_state = trace_context_create_blend_state; +   tr_ctx->base.bind_blend_state = trace_context_bind_blend_state; +   tr_ctx->base.delete_blend_state = trace_context_delete_blend_state; +   tr_ctx->base.create_sampler_state = trace_context_create_sampler_state; +   tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states; +   tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state; +   tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state; +   tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state; +   tr_ctx->base.delete_rasterizer_state = trace_context_delete_rasterizer_state; +   tr_ctx->base.create_depth_stencil_alpha_state = trace_context_create_depth_stencil_alpha_state; +   tr_ctx->base.bind_depth_stencil_alpha_state = trace_context_bind_depth_stencil_alpha_state; +   tr_ctx->base.delete_depth_stencil_alpha_state = trace_context_delete_depth_stencil_alpha_state; +   tr_ctx->base.create_fs_state = trace_context_create_fs_state; +   tr_ctx->base.bind_fs_state = trace_context_bind_fs_state; +   tr_ctx->base.delete_fs_state = trace_context_delete_fs_state; +   tr_ctx->base.create_vs_state = trace_context_create_vs_state; +   tr_ctx->base.bind_vs_state = trace_context_bind_vs_state; +   tr_ctx->base.delete_vs_state = trace_context_delete_vs_state; +   tr_ctx->base.set_blend_color = trace_context_set_blend_color; +   tr_ctx->base.set_clip_state = trace_context_set_clip_state; +   tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer; +   tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state; +   tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; +   tr_ctx->base.set_scissor_state = trace_context_set_scissor_state; +   tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; +   tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures; +   tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; +   tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements; +   tr_ctx->base.surface_copy = trace_context_surface_copy; +   tr_ctx->base.surface_fill = trace_context_surface_fill; +   tr_ctx->base.clear = trace_context_clear; +   tr_ctx->base.flush = trace_context_flush; + +   tr_ctx->pipe = pipe; +    +   trace_dump_call_begin("", "pipe_context_create"); +   trace_dump_arg_begin("screen"); +   trace_dump_ptr(pipe->screen); +   trace_dump_arg_end(); +   trace_dump_ret(ptr, pipe); +   trace_dump_call_end(); + +   return &tr_ctx->base; +    +error1: +   return pipe; +} diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h new file mode 100644 index 0000000000..7831900ec2 --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.h @@ -0,0 +1,68 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#ifndef TR_CONTEXT_H_ +#define TR_CONTEXT_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_context.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +    +struct trace_context +{ +   struct pipe_context base; +    +   struct pipe_context *pipe; +}; + + +static INLINE struct trace_context * +trace_context(struct pipe_context *pipe) +{ +   assert(pipe); +   return (struct trace_context *)pipe; +} + + + +struct pipe_context * +trace_context_create(struct pipe_screen *screen, +                     struct pipe_context *pipe); + + +#ifdef __cplusplus +} +#endif + +#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c new file mode 100644 index 0000000000..a0ead0ded3 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.c @@ -0,0 +1,404 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + + +/** + * @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  + * representation if/when it becomes justified. + *  + * @author Jose Fonseca <jrfonseca@tungstengraphics.com>    + */ + +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include <stdlib.h> +#endif + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/u_stream.h" + +#include "tr_dump.h" + + +static struct util_stream *stream = NULL; +static unsigned refcount = 0; + + +static INLINE void  +trace_dump_write(const char *buf, size_t size) +{ +   if(stream) +      util_stream_write(stream, buf, size); +} + + +static INLINE void  +trace_dump_writes(const char *s) +{ +   trace_dump_write(s, strlen(s)); +} + + +static INLINE void  +trace_dump_writef(const char *format, ...) +{ +   static char buf[1024]; +   unsigned len; +   va_list ap; +   va_start(ap, format); +   len = util_vsnprintf(buf, sizeof(buf), format, ap); +   va_end(ap); +   trace_dump_write(buf, len); +} + + +static INLINE void  +trace_dump_escape(const char *str)  +{ +   const unsigned char *p = (const unsigned char *)str; +   unsigned char c; +   while((c = *p++) != 0) { +      if(c == '<') +         trace_dump_writes("<"); +      else if(c == '>') +         trace_dump_writes(">"); +      else if(c == '&') +         trace_dump_writes("&"); +      else if(c == '\'') +         trace_dump_writes("'"); +      else if(c == '\"') +         trace_dump_writes("""); +      else if(c >= 0x20 && c <= 0x7e) +         trace_dump_writef("%c", c); +      else +         trace_dump_writef("&#%u;", c); +   } +} + + +static INLINE void  +trace_dump_indent(unsigned level) +{ +   unsigned i; +   for(i = 0; i < level; ++i) +      trace_dump_writes("\t"); +} + + +static INLINE void  +trace_dump_newline(void)  +{ +   trace_dump_writes("\n"); +} + + +static INLINE void  +trace_dump_tag(const char *name) +{ +   trace_dump_writes("<"); +   trace_dump_writes(name); +   trace_dump_writes("/>"); +} + + +static INLINE void  +trace_dump_tag_begin(const char *name) +{ +   trace_dump_writes("<"); +   trace_dump_writes(name); +   trace_dump_writes(">"); +} + +static INLINE void  +trace_dump_tag_begin1(const char *name,  +                      const char *attr1, const char *value1) +{ +   trace_dump_writes("<"); +   trace_dump_writes(name); +   trace_dump_writes(" "); +   trace_dump_writes(attr1); +   trace_dump_writes("='"); +   trace_dump_escape(value1); +   trace_dump_writes("'>"); +} + + +static INLINE void  +trace_dump_tag_begin2(const char *name,  +                      const char *attr1, const char *value1, +                      const char *attr2, const char *value2) +{ +   trace_dump_writes("<"); +   trace_dump_writes(name); +   trace_dump_writes(" "); +   trace_dump_writes(attr1); +   trace_dump_writes("=\'"); +   trace_dump_escape(value1); +   trace_dump_writes("\' "); +   trace_dump_writes(attr2); +   trace_dump_writes("=\'"); +   trace_dump_escape(value2); +   trace_dump_writes("\'>"); +} + + +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) +{ +   trace_dump_writes("<"); +   trace_dump_writes(name); +   trace_dump_writes(" "); +   trace_dump_writes(attr1); +   trace_dump_writes("=\'"); +   trace_dump_escape(value1); +   trace_dump_writes("\' "); +   trace_dump_writes(attr2); +   trace_dump_writes("=\'"); +   trace_dump_escape(value2); +   trace_dump_writes("\' "); +   trace_dump_writes(attr3); +   trace_dump_writes("=\'"); +   trace_dump_escape(value3); +   trace_dump_writes("\'>"); +} + + +static INLINE void +trace_dump_tag_end(const char *name) +{ +   trace_dump_writes("</"); +   trace_dump_writes(name); +   trace_dump_writes(">"); +} + +static void  +trace_dump_trace_close(void) +{ +   if(stream) { +      trace_dump_writes("</trace>\n"); +      util_stream_close(stream); +      stream = NULL; +      refcount = 0; +   } +} + +boolean trace_dump_trace_begin() +{ +   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; +       +      trace_dump_writes("<?xml version='1.0' encoding='UTF-8'?>\n"); +      trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n"); +      trace_dump_writes("<trace version='0.1'>\n"); +       +#if defined(PIPE_OS_LINUX) +      /* 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) +{ +   return stream ? TRUE : FALSE; +} + +void trace_dump_trace_end(void) +{ +   if(stream) +      if(!--refcount) +         trace_dump_trace_close(); +} + +void trace_dump_call_begin(const char *klass, const char *method) +{ +   trace_dump_indent(1); +   trace_dump_tag_begin2("call", "class", klass, "method", method); +   trace_dump_newline(); +} + +void trace_dump_call_end(void) +{ +   trace_dump_indent(1); +   trace_dump_tag_end("call"); +   trace_dump_newline(); +   util_stream_flush(stream); +} + +void trace_dump_arg_begin(const char *name) +{ +   trace_dump_indent(2); +   trace_dump_tag_begin1("arg", "name", name); +} + +void trace_dump_arg_end(void) +{ +   trace_dump_tag_end("arg"); +   trace_dump_newline(); +} + +void trace_dump_ret_begin(void) +{ +   trace_dump_indent(2); +   trace_dump_tag_begin("ret"); +} + +void trace_dump_ret_end(void) +{ +   trace_dump_tag_end("ret"); +   trace_dump_newline(); +} + +void trace_dump_bool(int value) +{ +   trace_dump_writef("<bool>%c</bool>", value ? '1' : '0'); +} + +void trace_dump_int(long long int value) +{ +   trace_dump_writef("<int>%lli</int>", value); +} + +void trace_dump_uint(long long unsigned value) +{ +   trace_dump_writef("<uint>%llu</uint>", value); +} + +void trace_dump_float(double value) +{ +   trace_dump_writef("<float>%g</float>", value); +} + +void trace_dump_bytes(const void *data, +                      long unsigned size) +{ +   static const char hex_table[16] = "0123456789ABCDEF"; +   const uint8_t *p = data; +   long unsigned i; +   trace_dump_writes("<bytes>"); +   for(i = 0; i < size; ++i) { +      uint8_t byte = *p++; +      char hex[2]; +      hex[0] = hex_table[byte >> 4]; +      hex[1] = hex_table[byte & 0xf]; +      trace_dump_write(hex, 2); +   } +   trace_dump_writes("</bytes>"); +} + +void trace_dump_string(const char *str) +{ +   trace_dump_writes("<string>"); +   trace_dump_escape(str); +   trace_dump_writes("</string>"); +} + +void trace_dump_enum(const char *value) +{ +   trace_dump_writes("<enum>"); +   trace_dump_escape(value); +   trace_dump_writes("</enum>"); +} + +void trace_dump_array_begin(void) +{ +   trace_dump_writes("<array>"); +} + +void trace_dump_array_end(void) +{ +   trace_dump_writes("</array>"); +} + +void trace_dump_elem_begin(void) +{ +   trace_dump_writes("<elem>"); +} + +void trace_dump_elem_end(void) +{ +   trace_dump_writes("</elem>"); +} + +void trace_dump_struct_begin(const char *name) +{ +   trace_dump_writef("<struct name='%s'>", name); +} + +void trace_dump_struct_end(void) +{ +   trace_dump_writes("</struct>"); +} + +void trace_dump_member_begin(const char *name) +{ +   trace_dump_writef("<member name='%s'>", name); +} + +void trace_dump_member_end(void) +{ +   trace_dump_writes("</member>"); +} + +void trace_dump_null(void) +{ +   trace_dump_writes("<null/>"); +} + +void trace_dump_ptr(const void *value) +{ +   if(value) +      trace_dump_writef("<ptr>0x%08lx</ptr>", (unsigned long)(uintptr_t)value); +   else +      trace_dump_null(); +} diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h new file mode 100644 index 0000000000..76a53731b3 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.h @@ -0,0 +1,132 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +/** + * @file + * Trace data dumping primitives. + */ + +#ifndef TR_DUMP_H +#define TR_DUMP_H + + +#include "pipe/p_compiler.h" + + +boolean trace_dump_trace_begin(void); +boolean trace_dump_enabled(void); +void trace_dump_trace_end(void); +void trace_dump_call_begin(const char *klass, const char *method); +void trace_dump_call_end(void); +void trace_dump_arg_begin(const char *name); +void trace_dump_arg_end(void); +void trace_dump_ret_begin(void); +void trace_dump_ret_end(void); +void trace_dump_bool(int value); +void trace_dump_int(long long int value); +void trace_dump_uint(long long unsigned value); +void trace_dump_float(double value); +void trace_dump_bytes(const void *data, long unsigned size); +void trace_dump_string(const char *str); +void trace_dump_enum(const char *value); +void trace_dump_array_begin(void); +void trace_dump_array_end(void); +void trace_dump_elem_begin(void); +void trace_dump_elem_end(void); +void trace_dump_struct_begin(const char *name); +void trace_dump_struct_end(void); +void trace_dump_member_begin(const char *name); +void trace_dump_member_end(void); +void trace_dump_null(void); +void trace_dump_ptr(const void *value); + + +/* + * Code saving macros.  + */ + +#define trace_dump_arg(_type, _arg) \ +   do { \ +      trace_dump_arg_begin(#_arg); \ +      trace_dump_##_type(_arg); \ +      trace_dump_arg_end(); \ +   } while(0) + +#define trace_dump_ret(_type, _arg) \ +   do { \ +      trace_dump_ret_begin(); \ +      trace_dump_##_type(_arg); \ +      trace_dump_ret_end(); \ +   } while(0) + +#define trace_dump_array(_type, _obj, _size) \ +   do { \ +      unsigned long idx; \ +      trace_dump_array_begin(); \ +      for(idx = 0; idx < (_size); ++idx) { \ +         trace_dump_elem_begin(); \ +         trace_dump_##_type((_obj)[idx]); \ +         trace_dump_elem_end(); \ +      } \ +      trace_dump_array_end(); \ +   } while(0) + +#define trace_dump_struct_array(_type, _obj, _size) \ +   do { \ +      unsigned long idx; \ +      trace_dump_array_begin(); \ +      for(idx = 0; idx < (_size); ++idx) { \ +         trace_dump_elem_begin(); \ +         trace_dump_##_type(&(_obj)[idx]); \ +         trace_dump_elem_end(); \ +      } \ +      trace_dump_array_end(); \ +   } while(0) + +#define trace_dump_member(_type, _obj, _member) \ +   do { \ +      trace_dump_member_begin(#_member); \ +      trace_dump_##_type((_obj)->_member); \ +      trace_dump_member_end(); \ +   } while(0) + +#define trace_dump_arg_array(_type, _arg, _size) \ +   do { \ +      trace_dump_arg_begin(#_arg); \ +      trace_dump_array(_type, _arg, _size); \ +      trace_dump_arg_end(); \ +   } while(0) + +#define trace_dump_member_array(_type, _obj, _member) \ +   do { \ +      trace_dump_member_begin(#_member); \ +      trace_dump_array(_type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ +      trace_dump_member_end(); \ +   } while(0) + + +#endif /* TR_DUMP_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c new file mode 100644 index 0000000000..8789f86b1a --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.c @@ -0,0 +1,469 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#include "util/u_memory.h" + +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_winsys.h" +#include "tr_texture.h" +#include "tr_screen.h" + + +static const char * +trace_screen_get_name(struct pipe_screen *_screen) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   const char *result; +    +   trace_dump_call_begin("pipe_screen", "get_name"); +    +   trace_dump_arg(ptr, screen); + +   result = screen->get_name(screen); +    +   trace_dump_ret(string, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static const char * +trace_screen_get_vendor(struct pipe_screen *_screen) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   const char *result; +    +   trace_dump_call_begin("pipe_screen", "get_vendor"); +    +   trace_dump_arg(ptr, screen); +   +   result = screen->get_vendor(screen); +    +   trace_dump_ret(string, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static int  +trace_screen_get_param(struct pipe_screen *_screen,  +                       int param) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   int result; +    +   trace_dump_call_begin("pipe_screen", "get_param"); +    +   trace_dump_arg(ptr, screen); +   trace_dump_arg(int, param); + +   result = screen->get_param(screen, param); +    +   trace_dump_ret(int, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static float  +trace_screen_get_paramf(struct pipe_screen *_screen,  +                        int param) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   float result; +    +   trace_dump_call_begin("pipe_screen", "get_paramf"); +    +   trace_dump_arg(ptr, screen); +   trace_dump_arg(int, param); + +   result = screen->get_paramf(screen, param); +    +   trace_dump_ret(float, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static boolean  +trace_screen_is_format_supported(struct pipe_screen *_screen, +                                 enum pipe_format format, +                                 enum pipe_texture_target target, +                                 unsigned tex_usage,  +                                 unsigned geom_flags) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   boolean result; +    +   trace_dump_call_begin("pipe_screen", "is_format_supported"); +    +   trace_dump_arg(ptr, screen); +   trace_dump_arg(format, format); +   trace_dump_arg(int, target); +   trace_dump_arg(uint, tex_usage); +   trace_dump_arg(uint, geom_flags); + +   result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); +    +   trace_dump_ret(bool, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static struct pipe_texture * +trace_screen_texture_create(struct pipe_screen *_screen, +                            const struct pipe_texture *templat) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct pipe_texture *result; +    +   trace_dump_call_begin("pipe_screen", "texture_create"); + +   trace_dump_arg(ptr, screen); +   trace_dump_arg(template, templat); + +   result = screen->texture_create(screen, templat); +    +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   result = trace_texture_create(tr_scr, result); +    +   return result; +} + + +static struct pipe_texture * +trace_screen_texture_blanket(struct pipe_screen *_screen, +                             const struct pipe_texture *templat, +                             const unsigned *ppitch, +                             struct pipe_buffer *buffer) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   unsigned pitch = *ppitch; +   struct pipe_texture *result; + +   trace_dump_call_begin("pipe_screen", "texture_blanket"); + +   trace_dump_arg(ptr, screen); +   trace_dump_arg(template, templat); +   trace_dump_arg(uint, pitch); +   trace_dump_arg(ptr, buffer); + +   result = screen->texture_blanket(screen, templat, ppitch, buffer); +    +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   result = trace_texture_create(tr_scr, result); +    +   return result; +} + + +static void  +trace_screen_texture_release(struct pipe_screen *_screen, +                             struct pipe_texture **ptexture) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct trace_texture *tr_tex; +   struct pipe_texture *texture; +    +   assert(ptexture); +   if(*ptexture) { +      tr_tex = trace_texture(tr_scr, *ptexture); +      texture = tr_tex->texture; +      assert(texture->screen == screen); +   } +   else +      texture = NULL; +    +   if (*ptexture) { +      if (!--(*ptexture)->refcount) { +         trace_dump_call_begin("pipe_screen", "texture_destroy"); +          +         trace_dump_arg(ptr, screen); +         trace_dump_arg(ptr, texture); +          +         trace_texture_destroy(tr_scr, *ptexture); +          +         trace_dump_call_end(); +      } +    +      *ptexture = NULL; +   } +} + + +static struct pipe_surface * +trace_screen_get_tex_surface(struct pipe_screen *_screen, +                             struct pipe_texture *texture, +                             unsigned face, unsigned level, +                             unsigned zslice, +                             unsigned usage) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct trace_texture *tr_tex; +   struct pipe_surface *result; +    +   assert(texture); +   tr_tex = trace_texture(tr_scr, texture); +   texture = tr_tex->texture; +   assert(texture->screen == screen); +    +   trace_dump_call_begin("pipe_screen", "get_tex_surface"); +    +   trace_dump_arg(ptr, screen); +   trace_dump_arg(ptr, texture); +   trace_dump_arg(uint, face); +   trace_dump_arg(uint, level); +   trace_dump_arg(uint, zslice); +   trace_dump_arg(uint, usage); + +   result = screen->get_tex_surface(screen, texture, face, level, zslice, usage); + +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   result = trace_surface_create(tr_tex, result); + +   return result; +} + + +static void  +trace_screen_tex_surface_release(struct pipe_screen *_screen, +                                 struct pipe_surface **psurface) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct trace_texture *tr_tex; +   struct trace_surface *tr_surf; +   struct pipe_surface *surface; +    +   assert(psurface); +   if(*psurface) { +      tr_tex = trace_texture(tr_scr, (*psurface)->texture); +      tr_surf = trace_surface(tr_tex, *psurface); +      surface = tr_surf->surface; +   } +   else +      surface = NULL; +    +   if (*psurface) { +      if (!--(*psurface)->refcount) { +         trace_dump_call_begin("pipe_screen", "tex_surface_destroy"); +          +         trace_dump_arg(ptr, screen); +         trace_dump_arg(ptr, surface); + +         trace_surface_destroy(tr_tex, *psurface); + +         trace_dump_call_end(); +      } +    +      *psurface = NULL; +   } +} + + +static void * +trace_screen_surface_map(struct pipe_screen *_screen, +                         struct pipe_surface *surface, +                         unsigned flags) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct trace_texture *tr_tex; +   struct trace_surface *tr_surf; +   void *map; +    +   tr_tex = trace_texture(tr_scr, surface->texture); +   tr_surf = trace_surface(tr_tex, surface); +   surface = tr_surf->surface; + +   map = screen->surface_map(screen, surface, flags); +   if(map) { +      if(flags & PIPE_BUFFER_USAGE_CPU_WRITE) { +         assert(!tr_surf->map); +         tr_surf->map = map; +      } +   } +    +   return map; +} + + +static void  +trace_screen_surface_unmap(struct pipe_screen *_screen, +                           struct pipe_surface *surface) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +   struct trace_texture *tr_tex; +   struct trace_surface *tr_surf; +    +   tr_tex = trace_texture(tr_scr, surface->texture); +   tr_surf = trace_surface(tr_tex, surface); +   surface = tr_surf->surface; +    +   if(tr_surf->map) { +      size_t size = surface->nblocksy * surface->stride; +       +      trace_dump_call_begin("pipe_winsys", "surface_write"); +       +      trace_dump_arg(ptr, screen); +       +      trace_dump_arg(ptr, surface); +       +      trace_dump_arg_begin("data"); +      trace_dump_bytes(tr_surf->map, size); +      trace_dump_arg_end(); + +      trace_dump_arg_begin("stride"); +      trace_dump_uint(surface->stride); +      trace_dump_arg_end(); + +      trace_dump_arg_begin("size"); +      trace_dump_uint(size); +      trace_dump_arg_end(); +    +      trace_dump_call_end(); + +      tr_surf->map = NULL; +   } + +   screen->surface_unmap(screen, surface); +} + + +static void +trace_screen_destroy(struct pipe_screen *_screen) +{ +   struct trace_screen *tr_scr = trace_screen(_screen); +   struct pipe_screen *screen = tr_scr->screen; +    +   trace_dump_call_begin("pipe_screen", "destroy"); +    +   trace_dump_arg(ptr, screen); + +   screen->destroy(screen); +    +   trace_dump_call_end(); + +   trace_dump_trace_end(); + +   FREE(tr_scr); +} + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ +   struct trace_screen *tr_scr; +   struct pipe_winsys *winsys; +    +   if(!screen) +      goto error1; + +   if(!trace_dump_trace_begin()) +      goto error1; + +   tr_scr = CALLOC_STRUCT(trace_screen); +   if(!tr_scr) +      goto error2; + +   winsys = trace_winsys_create(screen->winsys); +   if(!winsys) +      goto error3; +    +   tr_scr->base.winsys = winsys; +   tr_scr->base.destroy = trace_screen_destroy; +   tr_scr->base.get_name = trace_screen_get_name; +   tr_scr->base.get_vendor = trace_screen_get_vendor; +   tr_scr->base.get_param = trace_screen_get_param; +   tr_scr->base.get_paramf = trace_screen_get_paramf; +   tr_scr->base.is_format_supported = trace_screen_is_format_supported; +   tr_scr->base.texture_create = trace_screen_texture_create; +   tr_scr->base.texture_blanket = trace_screen_texture_blanket; +   tr_scr->base.texture_release = trace_screen_texture_release; +   tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; +   tr_scr->base.tex_surface_release = trace_screen_tex_surface_release; +   tr_scr->base.surface_map = trace_screen_surface_map; +   tr_scr->base.surface_unmap = trace_screen_surface_unmap; +    +   tr_scr->screen = screen; + +   trace_dump_call_begin("", "pipe_screen_create"); +   trace_dump_arg_begin("winsys"); +   trace_dump_ptr(screen->winsys); +   trace_dump_arg_end(); +   trace_dump_ret(ptr, screen); +   trace_dump_call_end(); + +   return &tr_scr->base; + +error3: +   FREE(tr_scr); +error2: +   trace_dump_trace_end(); +error1: +   return screen; +} + + +struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ +   assert(screen); +   assert(screen->destroy == trace_screen_destroy); +   return (struct trace_screen *)screen; +} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h new file mode 100644 index 0000000000..93fefdb9a5 --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#ifndef TR_SCREEN_H_ +#define TR_SCREEN_H_ + + +#include "pipe/p_screen.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +    +struct trace_screen +{ +   struct pipe_screen base; +    +   struct pipe_screen *screen; +}; + + +struct trace_screen * +trace_screen(struct pipe_screen *screen); + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen); + + +#ifdef __cplusplus +} +#endif + +#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c new file mode 100644 index 0000000000..986d939e0c --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.c @@ -0,0 +1,464 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_dump.h" + +#include "tr_dump.h" +#include "tr_state.h" + + +void trace_dump_format(enum pipe_format format) +{ +   trace_dump_enum(pf_name(format) ); +} + + +void trace_dump_block(const struct pipe_format_block *block) +{ +   trace_dump_struct_begin("pipe_format_block"); +   trace_dump_member(uint, block, size); +   trace_dump_member(uint, block, width); +   trace_dump_member(uint, block, height); +   trace_dump_struct_end(); +} + + +void trace_dump_template(const struct pipe_texture *templat) +{ +   if(!templat) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_texture"); +    +   trace_dump_member(int, templat, target); +   trace_dump_member(format, templat, format); +    +   trace_dump_member_begin("width"); +   trace_dump_array(uint, templat->width, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("height"); +   trace_dump_array(uint, templat->height, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("depth"); +   trace_dump_array(uint, templat->depth, 1); +   trace_dump_member_end(); + +   trace_dump_member_begin("block"); +   trace_dump_block(&templat->block); +   trace_dump_member_end(); +    +   trace_dump_member(uint, templat, last_level); +   trace_dump_member(uint, templat, tex_usage); +    +   trace_dump_struct_end(); +} + + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_rasterizer_state"); + +   trace_dump_member(bool, state, flatshade); +   trace_dump_member(bool, state, light_twoside); +   trace_dump_member(uint, state, front_winding); +   trace_dump_member(uint, state, cull_mode); +   trace_dump_member(uint, state, fill_cw); +   trace_dump_member(uint, state, fill_ccw); +   trace_dump_member(bool, state, offset_cw); +   trace_dump_member(bool, state, offset_ccw); +   trace_dump_member(bool, state, scissor); +   trace_dump_member(bool, state, poly_smooth); +   trace_dump_member(bool, state, poly_stipple_enable); +   trace_dump_member(bool, state, point_smooth); +   trace_dump_member(bool, state, point_sprite); +   trace_dump_member(bool, state, point_size_per_vertex); +   trace_dump_member(bool, state, multisample); +   trace_dump_member(bool, state, line_smooth); +   trace_dump_member(bool, state, line_stipple_enable); +   trace_dump_member(uint, state, line_stipple_factor); +   trace_dump_member(uint, state, line_stipple_pattern); +   trace_dump_member(bool, state, line_last_pixel); +   trace_dump_member(bool, state, bypass_clipping); +   trace_dump_member(bool, state, bypass_vs); +   trace_dump_member(bool, state, origin_lower_left); +   trace_dump_member(bool, state, flatshade_first); +   trace_dump_member(bool, state, gl_rasterization_rules); + +   trace_dump_member(float, state, line_width); +   trace_dump_member(float, state, point_size); +   trace_dump_member(float, state, point_size_min); +   trace_dump_member(float, state, point_size_max); +   trace_dump_member(float, state, offset_units); +   trace_dump_member(float, state, offset_scale); +    +   trace_dump_member_array(uint, state, sprite_coord_mode); +    +   trace_dump_struct_end(); +} + + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_poly_stipple"); + +   trace_dump_member_begin("stipple"); +   trace_dump_array(uint, +                    state->stipple,  +                    Elements(state->stipple)); +   trace_dump_member_end(); +    +   trace_dump_struct_end(); +} + + +void trace_dump_viewport_state(const struct pipe_viewport_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_viewport_state"); + +   trace_dump_member_array(float, state, scale); +   trace_dump_member_array(float, state, translate); +    +   trace_dump_struct_end(); +} + + +void trace_dump_scissor_state(const struct pipe_scissor_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_scissor_state"); + +   trace_dump_member(uint, state, minx); +   trace_dump_member(uint, state, miny); +   trace_dump_member(uint, state, maxx); +   trace_dump_member(uint, state, maxy); + +   trace_dump_struct_end(); +} + + +void trace_dump_clip_state(const struct pipe_clip_state *state) +{ +   unsigned i; +    +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_clip_state"); + +   trace_dump_member_begin("ucp"); +   trace_dump_array_begin(); +   for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { +      trace_dump_elem_begin(); +      trace_dump_array(float, state->ucp[i], 4); +      trace_dump_elem_end(); +   } +   trace_dump_array_end(); +   trace_dump_member_end(); + +   trace_dump_member(uint, state, nr); + +   trace_dump_struct_end(); +} + + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_constant_buffer"); + +   trace_dump_member(ptr, state, buffer); +   trace_dump_member(uint, state, size); + +   trace_dump_struct_end(); +} + + +void trace_dump_shader_state(const struct pipe_shader_state *state) +{ +   static char str[8192]; + +   if(!state) { +      trace_dump_null(); +      return; +   } + +   tgsi_dump_str(state->tokens, 0, str, sizeof(str)); +    +   trace_dump_struct_begin("pipe_shader_state"); + +   trace_dump_member_begin("tokens"); +   trace_dump_string(str); +   trace_dump_member_end(); + +   trace_dump_struct_end(); +} + + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) +{ +   unsigned i; +    +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); + +   trace_dump_member_begin("depth"); +   trace_dump_struct_begin("pipe_depth_state"); +   trace_dump_member(bool, &state->depth, enabled); +   trace_dump_member(bool, &state->depth, writemask); +   trace_dump_member(uint, &state->depth, func); +   trace_dump_member(bool, &state->depth, occlusion_count); +   trace_dump_struct_end(); +   trace_dump_member_end(); +    +   trace_dump_member_begin("stencil"); +   trace_dump_array_begin(); +   for(i = 0; i < Elements(state->stencil); ++i) { +      trace_dump_elem_begin(); +      trace_dump_struct_begin("pipe_stencil_state"); +      trace_dump_member(bool, &state->stencil[i], enabled); +      trace_dump_member(uint, &state->stencil[i], func); +      trace_dump_member(uint, &state->stencil[i], fail_op); +      trace_dump_member(uint, &state->stencil[i], zpass_op); +      trace_dump_member(uint, &state->stencil[i], zfail_op); +      trace_dump_member(uint, &state->stencil[i], ref_value);     +      trace_dump_member(uint, &state->stencil[i], value_mask); +      trace_dump_member(uint, &state->stencil[i], write_mask); +      trace_dump_struct_end(); +      trace_dump_elem_end(); +   } +   trace_dump_array_end(); +   trace_dump_member_end(); + +   trace_dump_member_begin("alpha"); +   trace_dump_struct_begin("pipe_alpha_state"); +   trace_dump_member(bool, &state->alpha, enabled); +   trace_dump_member(uint, &state->alpha, func); +   trace_dump_member(float, &state->alpha, ref); +   trace_dump_struct_end(); +   trace_dump_member_end(); + +   trace_dump_struct_end(); +} + + +void trace_dump_blend_state(const struct pipe_blend_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_blend_state"); + +   trace_dump_member(bool, state, blend_enable); + +   trace_dump_member(uint, state, rgb_func); +   trace_dump_member(uint, state, rgb_src_factor); +   trace_dump_member(uint, state, rgb_dst_factor); + +   trace_dump_member(uint, state, alpha_func); +   trace_dump_member(uint, state, alpha_src_factor); +   trace_dump_member(uint, state, alpha_dst_factor); + +   trace_dump_member(bool, state, logicop_enable); +   trace_dump_member(uint, state, logicop_func); + +   trace_dump_member(uint, state, colormask); +   trace_dump_member(bool, state, dither); + +   trace_dump_struct_end(); +} + + +void trace_dump_blend_color(const struct pipe_blend_color *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_blend_color"); + +   trace_dump_member_array(float, state, color); + +   trace_dump_struct_end(); +} + + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) +{ +   trace_dump_struct_begin("pipe_framebuffer_state"); + +   trace_dump_member(uint, state, width); +   trace_dump_member(uint, state, height); +   trace_dump_member(uint, state, num_cbufs); +   trace_dump_member_array(ptr, state, cbufs); +   trace_dump_member(ptr, state, zsbuf); + +   trace_dump_struct_end(); +} + + +void trace_dump_sampler_state(const struct pipe_sampler_state *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_sampler_state"); + +   trace_dump_member(uint, state, wrap_s); +   trace_dump_member(uint, state, wrap_t); +   trace_dump_member(uint, state, wrap_r); +   trace_dump_member(uint, state, min_img_filter); +   trace_dump_member(uint, state, min_mip_filter); +   trace_dump_member(uint, state, mag_img_filter); +   trace_dump_member(bool, state, compare_mode); +   trace_dump_member(uint, state, compare_func); +   trace_dump_member(bool, state, normalized_coords); +   trace_dump_member(uint, state, prefilter); +   trace_dump_member(float, state, shadow_ambient); +   trace_dump_member(float, state, lod_bias); +   trace_dump_member(float, state, min_lod); +   trace_dump_member(float, state, max_lod); +   trace_dump_member_array(float, state, border_color); +   trace_dump_member(float, state, max_anisotropy); + +   trace_dump_struct_end(); +} + + +void trace_dump_surface(const struct pipe_surface *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_surface"); + +   trace_dump_member(ptr, state, buffer); +   trace_dump_member(format, state, format); +   trace_dump_member(uint, state, status); +   trace_dump_member(uint, state, clear_value); +   trace_dump_member(uint, state, width); +   trace_dump_member(uint, state, height); + +   trace_dump_member_begin("block"); +   trace_dump_block(&state->block); +   trace_dump_member_end(); +    +   trace_dump_member(uint, state, nblocksx); +   trace_dump_member(uint, state, nblocksy); +   trace_dump_member(uint, state, stride); +   trace_dump_member(uint, state, layout); +   trace_dump_member(uint, state, offset); +   trace_dump_member(uint, state, refcount); +   trace_dump_member(uint, state, usage); + +   trace_dump_member(ptr, state, texture); +   trace_dump_member(uint, state, face); +   trace_dump_member(uint, state, level); +   trace_dump_member(uint, state, zslice); + +   trace_dump_struct_end(); +} + + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_vertex_buffer"); + +   trace_dump_member(uint, state, pitch); +   trace_dump_member(uint, state, max_index); +   trace_dump_member(uint, state, buffer_offset); +   trace_dump_member(ptr, state, buffer); + +   trace_dump_struct_end(); +} + + +void trace_dump_vertex_element(const struct pipe_vertex_element *state) +{ +   if(!state) { +      trace_dump_null(); +      return; +   } + +   trace_dump_struct_begin("pipe_vertex_element"); + +   trace_dump_member(uint, state, src_offset); + +   trace_dump_member(uint, state, vertex_buffer_index); +   trace_dump_member(uint, state, nr_components); +  +   trace_dump_member(format, state, src_format); + +   trace_dump_struct_end(); +} diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h new file mode 100644 index 0000000000..5ae533dc66 --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.h @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#ifndef TR_STATE_H +#define TR_STATE_H + +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + + +void trace_dump_format(enum pipe_format format); + +void trace_dump_block(const struct pipe_format_block *block); + +void trace_dump_template(const struct pipe_texture *templat); + + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); + +void trace_dump_viewport_state(const struct pipe_viewport_state *state); + +void trace_dump_scissor_state(const struct pipe_scissor_state *state); + +void trace_dump_clip_state(const struct pipe_clip_state *state); + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); + +void trace_dump_token(const struct tgsi_token *token); + +void trace_dump_shader_state(const struct pipe_shader_state *state); + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); + +void trace_dump_blend_state(const struct pipe_blend_state *state); + +void trace_dump_blend_color(const struct pipe_blend_color *state); + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); + +void trace_dump_sampler_state(const struct pipe_sampler_state *state); + +void trace_dump_surface(const struct pipe_surface *state); + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); + +void trace_dump_vertex_element(const struct pipe_vertex_element *state); + + +#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c new file mode 100644 index 0000000000..440a78704a --- /dev/null +++ b/src/gallium/drivers/trace/tr_texture.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#include "pipe/p_inlines.h" +#include "util/u_hash_table.h" +#include "util/u_memory.h" + +#include "tr_screen.h" +#include "tr_texture.h" + + +struct pipe_texture * +trace_texture_create(struct trace_screen *tr_scr,  +                     struct pipe_texture *texture) +{ +   struct trace_texture *tr_tex; +    +   if(!texture) +      goto error; +    +   assert(texture->screen == tr_scr->screen); +    +   tr_tex = CALLOC_STRUCT(trace_texture); +   if(!tr_tex) +      goto error; +    +   memcpy(&tr_tex->base, texture, sizeof(struct pipe_texture)); +   tr_tex->base.screen = &tr_scr->base; +   tr_tex->texture = texture; +    +   return &tr_tex->base; +    +error: +   pipe_texture_reference(&texture, NULL); +   return NULL; +} + + +void +trace_texture_destroy(struct trace_screen *tr_scr,  +                      struct pipe_texture *texture) +{ +   struct trace_texture *tr_tex = trace_texture(tr_scr, texture);  +   pipe_texture_reference(&tr_tex->texture, NULL); +   FREE(tr_tex); +} + + +struct pipe_surface * +trace_surface_create(struct trace_texture *tr_tex,  +                     struct pipe_surface *surface) +{ +   struct trace_surface *tr_surf; +    +   if(!surface) +      goto error; +    +   assert(surface->texture == tr_tex->texture); +    +   tr_surf = CALLOC_STRUCT(trace_surface); +   if(!tr_surf) +      goto error; +    +   memcpy(&tr_surf->base, surface, sizeof(struct pipe_surface)); +    +   tr_surf->base.winsys = tr_tex->base.screen->winsys; +   tr_surf->base.texture = NULL; +   pipe_texture_reference(&tr_surf->base.texture, &tr_tex->base); +   tr_surf->surface = surface; + +   return &tr_surf->base; +    +error: +   pipe_surface_reference(&surface, NULL); +   return NULL; +} + + +void +trace_surface_destroy(struct trace_texture *tr_tex,  +                      struct pipe_surface *surface) +{ +   struct trace_surface *tr_surf = trace_surface(tr_tex, surface); +   pipe_texture_reference(&tr_surf->base.texture, NULL); +   pipe_surface_reference(&tr_surf->surface, NULL); +   FREE(tr_surf); +} + diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h new file mode 100644 index 0000000000..9e72edb8a3 --- /dev/null +++ b/src/gallium/drivers/trace/tr_texture.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#ifndef TR_TEXTURE_H_ +#define TR_TEXTURE_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "tr_screen.h" + + +struct trace_texture +{ +   struct pipe_texture base; + +   struct pipe_texture *texture; +}; + + +struct trace_surface +{ +   struct pipe_surface base; + +   struct pipe_surface *surface; +    +   void *map; +}; + + +static INLINE struct trace_texture * +trace_texture(struct trace_screen *tr_scr,  +              struct pipe_texture *texture) +{ +   if(!texture) +      return NULL; +   assert(texture->screen == &tr_scr->base); +   return (struct trace_texture *)texture; +} + + +static INLINE struct trace_surface * +trace_surface(struct trace_texture *tr_tex,  +              struct pipe_surface *surface) +{ +   if(!surface) +      return NULL; +   assert(surface->texture == &tr_tex->base); +   return (struct trace_surface *)surface; +} + + +struct pipe_texture * +trace_texture_create(struct trace_screen *tr_scr,  +                     struct pipe_texture *texture); + +void +trace_texture_destroy(struct trace_screen *tr_scr,  +                      struct pipe_texture *texture); + +struct pipe_surface * +trace_surface_create(struct trace_texture *tr_tex,  +                     struct pipe_surface *surface); + +void +trace_surface_destroy(struct trace_texture *tr_tex, +                      struct pipe_surface *surface); + + +#endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c new file mode 100644 index 0000000000..177835854e --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -0,0 +1,497 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#include "util/u_memory.h" +#include "util/u_hash_table.h" + +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_screen.h" +#include "tr_texture.h" +#include "tr_winsys.h" + + +static unsigned trace_buffer_hash(void *buffer) +{ +   return (unsigned)(uintptr_t)buffer; +} + + +static int trace_buffer_compare(void *buffer1, void *buffer2) +{ +   return (char *)buffer2 - (char *)buffer1; +} + +                   +static const char * +trace_winsys_get_name(struct pipe_winsys *_winsys) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   const char *result; +    +   trace_dump_call_begin("pipe_winsys", "get_name"); +    +   trace_dump_arg(ptr, winsys); + +   result = winsys->get_name(winsys); +    +   trace_dump_ret(string, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static void  +trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, +                               struct pipe_surface *surface, +                               void *context_private) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; + +   assert(surface); +   if(surface->texture) { +      struct trace_screen *tr_scr = trace_screen(surface->texture->screen); +      struct trace_texture *tr_tex = trace_texture(tr_scr, surface->texture); +      struct trace_surface *tr_surf = trace_surface(tr_tex, surface); +      surface = tr_surf->surface; +   } +    +   trace_dump_call_begin("pipe_winsys", "flush_frontbuffer"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, surface); +   /* XXX: hide, as there is nothing we can do with this +   trace_dump_arg(ptr, context_private); +   */ + +   winsys->flush_frontbuffer(winsys, surface, context_private); +    +   trace_dump_call_end(); +} + + +static struct pipe_surface * +trace_winsys_surface_alloc(struct pipe_winsys *_winsys) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   struct pipe_surface *result; +    +   trace_dump_call_begin("pipe_winsys", "surface_alloc"); +    +   trace_dump_arg(ptr, winsys); + +   result = winsys->surface_alloc(winsys); +    +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   assert(!result || !result->texture); + +   return result; +} + + +static int +trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, +                                   struct pipe_surface *surface, +                                   unsigned width, unsigned height, +                                   enum pipe_format format, +                                   unsigned flags, +                                   unsigned tex_usage) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   int result; +    +   assert(surface && !surface->texture); + +   trace_dump_call_begin("pipe_winsys", "surface_alloc_storage"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, surface); +   trace_dump_arg(uint, width); +   trace_dump_arg(uint, height); +   trace_dump_arg(format, format); +   trace_dump_arg(uint, flags); +   trace_dump_arg(uint, tex_usage); + +   result = winsys->surface_alloc_storage(winsys, +                                          surface, +                                          width, height, +                                          format, +                                          flags, +                                          tex_usage); +    +   trace_dump_ret(int, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static void +trace_winsys_surface_release(struct pipe_winsys *_winsys,  +                             struct pipe_surface **psurface) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   struct pipe_surface *surface = *psurface; +    +   assert(psurface && *psurface && !(*psurface)->texture); +    +   trace_dump_call_begin("pipe_winsys", "surface_release"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, surface); + +   winsys->surface_release(winsys, psurface); +    +   trace_dump_call_end(); +} + + +static struct pipe_buffer * +trace_winsys_buffer_create(struct pipe_winsys *_winsys,  +                           unsigned alignment,  +                           unsigned usage, +                           unsigned size) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   struct pipe_buffer *buffer; +    +   trace_dump_call_begin("pipe_winsys", "buffer_create"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(uint, alignment); +   trace_dump_arg(uint, usage); +   trace_dump_arg(uint, size); + +   buffer = winsys->buffer_create(winsys, alignment, usage, size); +    +   trace_dump_ret(ptr, buffer); +    +   trace_dump_call_end(); + +   /* Zero the buffer to avoid dumping uninitialized memory */ +   if(buffer->usage & PIPE_BUFFER_USAGE_CPU_WRITE) { +      void *map; +      map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_WRITE); +      if(map) { +         memset(map, 0, buffer->size); +         winsys->buffer_unmap(winsys, buffer); +      } +   } +    +   return buffer; +} + + +static struct pipe_buffer * +trace_winsys_user_buffer_create(struct pipe_winsys *_winsys,  +                                void *data, +                                unsigned size) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   struct pipe_buffer *result; +    +   trace_dump_call_begin("pipe_winsys", "user_buffer_create"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg_begin("data"); +   trace_dump_bytes(data, size); +   trace_dump_arg_end(); +   trace_dump_arg(uint, size); + +   result = winsys->user_buffer_create(winsys, data, size); +    +   trace_dump_ret(ptr, result); +    +   trace_dump_call_end(); +    +   /* XXX: Mark the user buffers. (we should wrap pipe_buffers, but is is  +    * impossible to do so while texture-less surfaces are still around */ +   if(result) { +      assert(!(result->usage & TRACE_BUFFER_USAGE_USER)); +      result->usage |= TRACE_BUFFER_USAGE_USER; +   } +    +   return result; +} + + +void +trace_winsys_user_buffer_update(struct pipe_winsys *_winsys,  +                                struct pipe_buffer *buffer) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   const void *map; +    +   if(buffer && buffer->usage & TRACE_BUFFER_USAGE_USER) { +      map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_READ); +      if(map) { +         trace_dump_call_begin("pipe_winsys", "buffer_write"); +          +         trace_dump_arg(ptr, winsys); +          +         trace_dump_arg(ptr, buffer); +          +         trace_dump_arg_begin("data"); +         trace_dump_bytes(map, buffer->size); +         trace_dump_arg_end(); +       +         trace_dump_arg_begin("size"); +         trace_dump_uint(buffer->size); +         trace_dump_arg_end(); +       +         trace_dump_call_end(); +          +         winsys->buffer_unmap(winsys, buffer); +      } +   } +} + + +static void * +trace_winsys_buffer_map(struct pipe_winsys *_winsys,  +                        struct pipe_buffer *buffer, +                        unsigned usage) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   void *map; +    +   map = winsys->buffer_map(winsys, buffer, usage); +   if(map) { +      if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { +         assert(!hash_table_get(tr_ws->buffer_maps, buffer)); +         hash_table_set(tr_ws->buffer_maps, buffer, map); +      } +   } +    +   return map; +} + + +static void +trace_winsys_buffer_unmap(struct pipe_winsys *_winsys,  +                          struct pipe_buffer *buffer) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   const void *map; +    +   map = hash_table_get(tr_ws->buffer_maps, buffer); +   if(map) { +      trace_dump_call_begin("pipe_winsys", "buffer_write"); +       +      trace_dump_arg(ptr, winsys); +       +      trace_dump_arg(ptr, buffer); +       +      trace_dump_arg_begin("data"); +      trace_dump_bytes(map, buffer->size); +      trace_dump_arg_end(); + +      trace_dump_arg_begin("size"); +      trace_dump_uint(buffer->size); +      trace_dump_arg_end(); +    +      trace_dump_call_end(); + +      hash_table_remove(tr_ws->buffer_maps, buffer); +   } +    +   winsys->buffer_unmap(winsys, buffer); +} + + +static void +trace_winsys_buffer_destroy(struct pipe_winsys *_winsys, +                            struct pipe_buffer *buffer) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +    +   trace_dump_call_begin("pipe_winsys", "buffer_destroy"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, buffer); + +   winsys->buffer_destroy(winsys, buffer); +    +   trace_dump_call_end(); +} + + +static void +trace_winsys_fence_reference(struct pipe_winsys *_winsys, +                             struct pipe_fence_handle **pdst, +                             struct pipe_fence_handle *src) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   struct pipe_fence_handle *dst = *pdst; +    +   trace_dump_call_begin("pipe_winsys", "fence_reference"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, dst); +   trace_dump_arg(ptr, src); + +   winsys->fence_reference(winsys, pdst, src); +    +   trace_dump_call_end(); +} + + +static int +trace_winsys_fence_signalled(struct pipe_winsys *_winsys, +                             struct pipe_fence_handle *fence, +                             unsigned flag) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   int result; +    +   trace_dump_call_begin("pipe_winsys", "fence_signalled"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, fence); +   trace_dump_arg(uint, flag); + +   result = winsys->fence_signalled(winsys, fence, flag); +    +   trace_dump_ret(int, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static int +trace_winsys_fence_finish(struct pipe_winsys *_winsys, +                          struct pipe_fence_handle *fence, +                          unsigned flag) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +   int result; +    +   trace_dump_call_begin("pipe_winsys", "fence_finish"); +    +   trace_dump_arg(ptr, winsys); +   trace_dump_arg(ptr, fence); +   trace_dump_arg(uint, flag); + +   result = winsys->fence_finish(winsys, fence, flag); +    +   trace_dump_ret(int, result); +    +   trace_dump_call_end(); +    +   return result; +} + + +static void +trace_winsys_destroy(struct pipe_winsys *_winsys) +{ +   struct trace_winsys *tr_ws = trace_winsys(_winsys); +   struct pipe_winsys *winsys = tr_ws->winsys; +    +   trace_dump_call_begin("pipe_winsys", "destroy"); +    +   trace_dump_arg(ptr, winsys); + +   /*  +   winsys->destroy(winsys);  +   */ +    +   trace_dump_call_end(); +    +   hash_table_destroy(tr_ws->buffer_maps); + +   FREE(tr_ws); +} + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys) +{ +   struct trace_winsys *tr_ws; +    +   if(!winsys) +      goto error1; +    +   tr_ws = CALLOC_STRUCT(trace_winsys); +   if(!tr_ws) +      goto error1; + +   tr_ws->base.destroy = trace_winsys_destroy; +   tr_ws->base.get_name = trace_winsys_get_name; +   tr_ws->base.flush_frontbuffer = trace_winsys_flush_frontbuffer; +   tr_ws->base.surface_alloc = trace_winsys_surface_alloc; +   tr_ws->base.surface_alloc_storage = trace_winsys_surface_alloc_storage; +   tr_ws->base.surface_release = trace_winsys_surface_release; +   tr_ws->base.buffer_create = trace_winsys_buffer_create; +   tr_ws->base.user_buffer_create = trace_winsys_user_buffer_create; +   tr_ws->base.buffer_map = trace_winsys_buffer_map; +   tr_ws->base.buffer_unmap = trace_winsys_buffer_unmap; +   tr_ws->base.buffer_destroy = trace_winsys_buffer_destroy; +   tr_ws->base.fence_reference = trace_winsys_fence_reference; +   tr_ws->base.fence_signalled = trace_winsys_fence_signalled; +   tr_ws->base.fence_finish = trace_winsys_fence_finish; +    +   tr_ws->winsys = winsys; + +   tr_ws->buffer_maps = hash_table_create(trace_buffer_hash,  +                                          trace_buffer_compare); +   if(!tr_ws->buffer_maps) +      goto error2; +    +   trace_dump_call_begin("", "pipe_winsys_create"); +   trace_dump_ret(ptr, winsys); +   trace_dump_call_end(); + +   return &tr_ws->base; +    +error2: +   FREE(tr_ws); +error1: +   return winsys; +} diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h new file mode 100644 index 0000000000..062ddf66a0 --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * 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 + * 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. + * + **************************************************************************/ + +#ifndef TR_WINSYS_H_ +#define TR_WINSYS_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" + + +/** + * It often happens that new data is written directly to the user buffers  + * without mapping/unmapping. This flag marks user buffers, so that their  + * contents can be dumpped before being used by the pipe context. + */ +#define TRACE_BUFFER_USAGE_USER  (1 << 31) + + +struct hash_table; + + +struct trace_winsys +{ +   struct pipe_winsys base; +    +   struct pipe_winsys *winsys; +    +   struct hash_table *buffer_maps; +}; + + +static INLINE struct trace_winsys * +trace_winsys(struct pipe_winsys *winsys) +{ +   assert(winsys); +   return (struct trace_winsys *)winsys; +} + + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys); + + +void +trace_winsys_user_buffer_update(struct pipe_winsys *winsys,  +                                struct pipe_buffer *buffer); + + +#endif /* TR_WINSYS_H_ */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl new file mode 100644 index 0000000000..9cd621e7ab --- /dev/null +++ b/src/gallium/drivers/trace/trace.xsl @@ -0,0 +1,185 @@ +<?xml version="1.0"?> + +<!-- + +Copyright 2008 Tungsten Graphics, Inc. + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. + +!--> + +<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +	<xsl:output method="html" /> + +	<xsl:strip-space elements="*" /> + +	<xsl:template match="/trace"> +		<html> +			<head> +				<title>Gallium Trace</title> +			</head> +			<style> +				body { +					font-family: verdana, sans-serif; +					font-size: 11px; +					font-weight: normal; +					text-align : left; +				} + +				.fun { +					font-weight: bold; +				} + +				.var { +					font-style: italic; +				} + +				.typ { +					display: none; +				} + +				.lit { +					color: #0000ff; +				} + +				.ptr { +					color: #008000; +				} +			</style> +			<body> +				<ol class="calls"> +					<xsl:apply-templates/> +				</ol> +			</body> +		</html> +	</xsl:template> + +	<xsl:template match="call"> +		<li> +			<span class="fun"> +				<xsl:value-of select="@class"/> +				<xsl:text>::</xsl:text> +				<xsl:value-of select="@method"/> +			</span> +			<xsl:text>(</xsl:text> +			<xsl:apply-templates select="arg"/> +			<xsl:text>)</xsl:text> +			<xsl:apply-templates select="ret"/> +		</li> +	</xsl:template> + +	<xsl:template match="arg|member"> +			<xsl:apply-templates select="@name"/> +			<xsl:text> = </xsl:text> +			<xsl:apply-templates /> +			<xsl:if test="position() != last()"> +				<xsl:text>, </xsl:text> +			</xsl:if> +	</xsl:template> + +	<xsl:template match="ret"> +		<xsl:text> = </xsl:text> +		<xsl:apply-templates /> +	</xsl:template> + +	<xsl:template match="bool|int|uint|float|enum"> +		<span class="lit"> +			<xsl:value-of select="text()"/> +		</span> +	</xsl:template> + +	<xsl:template match="bytes"> +		<span class="lit"> +			<xsl:text>...</xsl:text> +		</span> +	</xsl:template> + +	<xsl:template match="string"> +		<span class="lit"> +			<xsl:text>"</xsl:text> +			<xsl:call-template name="break"> +				<xsl:with-param name="text" select="text()"/> +			</xsl:call-template> +			<xsl:text>"</xsl:text> +		</span> +	</xsl:template> + +	<xsl:template match="array|struct"> +		<xsl:text>{</xsl:text> +		<xsl:apply-templates /> +		<xsl:text>}</xsl:text> +	</xsl:template> + +	<xsl:template match="elem"> +		<xsl:apply-templates /> +		<xsl:if test="position() != last()"> +			<xsl:text>, </xsl:text> +		</xsl:if> +	</xsl:template> + +	<xsl:template match="null"> +		<span class="ptr"> +			<xsl:text>NULL</xsl:text> +		</span> +	</xsl:template> + +	<xsl:template match="ptr"> +		<span class="ptr"> +			<xsl:value-of select="text()"/> +		</span> +	</xsl:template> + +	<xsl:template match="@name"> +		<span class="var"> +			<xsl:value-of select="."/> +		</span> +	</xsl:template> +	 +	<xsl:template name="break"> +		<xsl:param name="text" select="."/> +		<xsl:choose> +			<xsl:when test="contains($text, '
')"> +				<xsl:value-of select="substring-before($text, '
')"/> +				<br/> +				<xsl:call-template name="break"> +					 <xsl:with-param name="text" select="substring-after($text, '
')"/> +				</xsl:call-template> +			</xsl:when> +			<xsl:otherwise> +				<xsl:value-of select="$text"/> +			</xsl:otherwise> +		</xsl:choose> +	</xsl:template> + +	<xsl:template name="replace"> +		<xsl:param name="text"/> +		<xsl:param name="from"/> +		<xsl:param name="to"/> +		<xsl:choose> +			<xsl:when test="contains($text,$from)"> +				<xsl:value-of select="concat(substring-before($text,$from),$to)"/> +				<xsl:call-template name="replace"> +					<xsl:with-param name="text" select="substring-after($text,$from)"/> +					<xsl:with-param name="from" select="$from"/> +					<xsl:with-param name="to" select="$to"/> +				</xsl:call-template> +			</xsl:when> +			<xsl:otherwise> +				<xsl:value-of select="$text"/> +			</xsl:otherwise> +		</xsl:choose> +	</xsl:template> + +</xsl:transform> | 
