llvmpipe: add a simple resource tracking/debug feature
authorBrian Paul <brianp@vmware.com>
Tue, 11 May 2010 17:50:43 +0000 (11:50 -0600)
committerBrian Paul <brianp@vmware.com>
Tue, 11 May 2010 17:52:06 +0000 (11:52 -0600)
If debug build, keep a linked list of all allocated resources (textures).
The llvmipe_print_resources() function can be called from a debugger to
print a list of all resources, their sizes, total size, etc.

src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h

index 930be3596fd87f929b8cddc28a6f6a06d18b38e7..9129fa46baf1d6998dc1f405c04dce19eab1d469 100644 (file)
@@ -39,6 +39,7 @@
 #include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
+#include "util/u_simple_list.h"
 #include "util/u_transfer.h"
 
 #include "lp_context.h"
 #include "state_tracker/sw_winsys.h"
 
 
+#ifdef DEBUG
+static struct llvmpipe_resource resource_list;
+#endif
+
+
 static INLINE boolean
 resource_is_texture(const struct pipe_resource *resource)
 {
@@ -245,6 +251,10 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
 
    lpr->id = id_counter++;
 
+#ifdef DEBUG
+   insert_at_tail(&resource_list, lpr);
+#endif
+
    return &lpr->base;
 
  fail:
@@ -303,6 +313,11 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
       align_free(lpr->data);
    }
 
+#ifdef DEBUG
+   if (lpr->next)
+      remove_from_list(lpr);
+#endif
+
    FREE(lpr);
 }
 
@@ -1208,9 +1223,43 @@ llvmpipe_resource_size(const struct pipe_resource *resource)
 }
 
 
+#ifdef DEBUG
+void
+llvmpipe_print_resources(void)
+{
+   struct llvmpipe_resource *lpr;
+   unsigned n = 0, total = 0;
+
+   debug_printf("LLVMPIPE: current resources:\n");
+   foreach(lpr, &resource_list) {
+      unsigned size = llvmpipe_resource_size(&lpr->base);
+      debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n",
+                   lpr->id, (void *) lpr,
+                   lpr->base.width0, lpr->base.height0, lpr->base.depth0,
+                   size, lpr->base.reference.count);
+      total += size;
+      n++;
+   }
+   debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total);
+}
+#endif
+
+
 void
 llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
 {
+#ifdef DEBUG
+   /* init linked list for tracking resources */
+   {
+      static boolean first_call = TRUE;
+      if (first_call) {
+         memset(&resource_list, 0, sizeof(resource_list));
+         make_empty_list(&resource_list);
+         first_call = FALSE;
+      }
+   }
+#endif
+
    screen->resource_create = llvmpipe_resource_create;
    screen->resource_destroy = llvmpipe_resource_destroy;
    screen->resource_from_handle = llvmpipe_resource_from_handle;
index a8d08d6247f0011aa587bde030d3cc8eeeec0f27..503b6a19a8d57aeb86577f49ce4bd76ffe4c3a69 100644 (file)
@@ -119,6 +119,11 @@ struct llvmpipe_resource
    unsigned timestamp;
 
    unsigned id;  /**< temporary, for debugging */
+
+#ifdef DEBUG
+   /** for linked list */
+   struct llvmpipe_resource *prev, *next;
+#endif
 };
 
 
@@ -219,6 +224,10 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
 
 
 
+extern void
+llvmpipe_print_resources(void);
+
+
 extern void
 llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);