trace: Hack to detect writes to user buffers.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 21 Aug 2008 12:57:59 +0000 (13:57 +0100)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 21 Aug 2008 17:46:04 +0000 (18:46 +0100)
It often happens that new data is written directly to the user buffers
without mapping/unmapping. This hack marks user buffers and dumps them
before passing them to pipe context.

src/gallium/drivers/trace/tr_context.c
src/gallium/drivers/trace/tr_winsys.c
src/gallium/drivers/trace/tr_winsys.h

index 529bed3..f16359e 100644 (file)
@@ -32,6 +32,7 @@
 #include "tr_state.h"
 #include "tr_screen.h"
 #include "tr_texture.h"
+#include "tr_winsys.h"
 #include "tr_context.h"
 
 
@@ -131,6 +132,8 @@ trace_context_draw_elements(struct pipe_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);
@@ -164,6 +167,8 @@ trace_context_draw_range_elements(struct pipe_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);
@@ -691,6 +696,8 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe,
    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);
@@ -820,6 +827,10 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
 {
    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");
 
index 120006e..2c7a6f8 100644 (file)
@@ -242,10 +242,50 @@ trace_winsys_user_buffer_create(struct pipe_winsys *_winsys,
    
    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,
index 2218117..062ddf6 100644 (file)
 #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;
 
 
@@ -60,4 +68,9 @@ 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_ */