cell: implement CELL_DEBUG env/options var
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 5 Sep 2008 00:36:22 +0000 (18:36 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 5 Sep 2008 00:36:22 +0000 (18:36 -0600)
Options so far:
  "checker"  module tile clear color by SPU ID to see where the tiles are
  "sync"  to do synchronous DMA (only partially implemented)

src/gallium/drivers/cell/common.h
src/gallium/drivers/cell/ppu/cell_context.c
src/gallium/drivers/cell/ppu/cell_context.h
src/gallium/drivers/cell/ppu/cell_spu.c
src/gallium/drivers/cell/spu/spu_main.c

index 6bace0bb11ae0c6809f078aaa88f887aa7ea04a7..c0ca201e1d1c6c8bf9f3ddbff2bf0113b7f0ce25 100644 (file)
 #define CELL_BUFFER_STATUS_USED 20
 
 
+#define CELL_DEBUG_CHECKER  (1 << 0)
+#define CELL_DEBUG_SYNC     (1 << 1)
+
 
 /**
  */
@@ -263,6 +266,7 @@ struct cell_init_info
 {
    unsigned id;
    unsigned num_spus;
+   unsigned debug_flags;  /**< mask of CELL_DEBUG_x flags */
    struct cell_command *cmd;
 
    /** Buffers for command batches, vertex/index data */
index 9ff4e86943b4b65e6e1b871723a4b7f6b89289bd..c8828e644c91fef0132ff86ca1543644ec1b181a 100644 (file)
@@ -85,6 +85,15 @@ cell_draw_create(struct cell_context *cell)
 }
 
 
+#ifdef DEBUG
+static const struct debug_named_value cell_debug_flags[] = {
+   {"checker", CELL_DEBUG_CHECKER},/**< modulate tile clear color by SPU ID */
+   {"sync", CELL_DEBUG_SYNC},      /**< SPUs do synchronous DMA */
+   {NULL, 0}
+};
+#endif
+
+
 struct pipe_context *
 cell_create_context(struct pipe_screen *screen,
                     struct cell_winsys *cws)
@@ -136,6 +145,10 @@ cell_create_context(struct pipe_screen *screen,
    draw_wide_point_threshold(cell->draw, 0.0);
    draw_wide_line_threshold(cell->draw, 0.0);
 
+   cell->debug_flags = debug_get_flags_option("CELL_DEBUG", 
+                                              cell_debug_flags, 
+                                              0 );
+
    /*
     * SPU stuff
     */
index 9ca153d52f2b70d574244f75b2e7f98b78fd3e6b..8cec9f45b2ea71fc0c7a99b64a1465025bb58f4c 100644 (file)
@@ -163,6 +163,8 @@ struct cell_context
 
    struct spe_function attrib_fetch;
    unsigned attrib_fetch_offsets[PIPE_MAX_ATTRIBS];
+
+   unsigned debug_flags;
 };
 
 
index 5e75f409a3bb896322f3155ab95f7aeae09e317c..2df90fdcb771ddaa485f22a747e4c69b616db023 100644 (file)
@@ -131,6 +131,7 @@ cell_start_spus(struct cell_context *cell)
    for (i = 0; i < cell->num_spus; i++) {
       cell_global.inits[i].id = i;
       cell_global.inits[i].num_spus = cell->num_spus;
+      cell_global.inits[i].debug_flags = cell->debug_flags;
       cell_global.inits[i].cmd = &cell_global.command[i];
       for (j = 0; j < CELL_NUM_BUFFERS; j++) {
          cell_global.inits[i].buffers[j] = cell->buffer[j];
index e04ffeb9b16a5e98fd9d828e147e8d2b551d1533..0d4cdfae85a41e046e03ace4e6475e35600a9d42 100644 (file)
@@ -136,54 +136,75 @@ really_clear_tiles(uint surfaceIndex)
 static void
 cmd_clear_surface(const struct cell_command_clear_surface *clear)
 {
-   const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
-   uint i;
-
    if (Debug)
       printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id,
              clear->surface, clear->value);
 
-#define CLEAR_OPT 1
-#if CLEAR_OPT
-   /* set all tile's status to CLEAR */
    if (clear->surface == 0) {
-      memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status));
       spu.fb.color_clear_value = clear->value;
+      if (spu.init.debug_flags & CELL_DEBUG_CHECKER) {
+         uint x = (spu.init.id << 4) | (spu.init.id << 12) |
+            (spu.init.id << 20) | (spu.init.id << 28);
+         spu.fb.color_clear_value ^= x;
+      }
    }
    else {
-      memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status));
       spu.fb.depth_clear_value = clear->value;
    }
-   return;
-#endif
 
+#define CLEAR_OPT 1
+#if CLEAR_OPT
+
+   /* Simply set all tiles' status to CLEAR.
+    * When we actually begin rendering into a tile, we'll initialize it to
+    * the clear value.  If any tiles go untouched during the frame,
+    * really_clear_tiles() will set them to the clear value.
+    */
    if (clear->surface == 0) {
-      spu.fb.color_clear_value = clear->value;
-      clear_c_tile(&spu.ctile);
+      memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status));
    }
    else {
-      spu.fb.depth_clear_value = clear->value;
-      clear_z_tile(&spu.ztile);
+      memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status));
    }
 
+#else
+
+   /*
+    * This path clears the whole framebuffer to the clear color right now.
+    */
+
    /*
    printf("SPU: %s num=%d w=%d h=%d\n",
           __FUNCTION__, num_tiles, spu.fb.width_tiles, spu.fb.height_tiles);
    */
 
-   for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
-      uint tx = i % spu.fb.width_tiles;
-      uint ty = i / spu.fb.width_tiles;
-      if (clear->surface == 0)
-         put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
-      else
-         put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1);
-      /* XXX we don't want this here, but it fixes bad tile results */
+   /* init a single tile to the clear value */
+   if (clear->surface == 0) {
+      clear_c_tile(&spu.ctile);
+   }
+   else {
+      clear_z_tile(&spu.ztile);
    }
 
-#if 0
-   wait_on_mask(1 << TAG_SURFACE_CLEAR);
-#endif
+   /* walk over my tiles, writing the 'clear' tile's data */
+   {
+      const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
+      uint i;
+      for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
+         uint tx = i % spu.fb.width_tiles;
+         uint ty = i / spu.fb.width_tiles;
+         if (clear->surface == 0)
+            put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
+         else
+            put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1);
+      }
+   }
+
+   if (spu.init.debug_flags & CELL_DEBUG_SYNC) {
+      wait_on_mask(1 << TAG_SURFACE_CLEAR);
+   }
+
+#endif /* CLEAR_OPT */
 
    if (Debug)
       printf("SPU %u: CLEAR SURF done\n", spu.init.id);