Cell: implemement basic Z testing
authorBrian <brian.paul@tungstengraphics.com>
Wed, 9 Jan 2008 21:10:59 +0000 (14:10 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 10 Jan 2008 00:50:37 +0000 (17:50 -0700)
Also, improve some surface clearing code

src/mesa/pipe/cell/common.h
src/mesa/pipe/cell/ppu/cell_spu.c
src/mesa/pipe/cell/ppu/cell_surface.c
src/mesa/pipe/cell/spu/main.c
src/mesa/pipe/cell/spu/main.h
src/mesa/pipe/cell/spu/tri.c

index dff0b1f..4c770f5 100644 (file)
 #define TILE_SIZE 32
 
 
-#define CELL_CMD_EXIT         1
-#define CELL_CMD_FRAMEBUFFER  2
-#define CELL_CMD_CLEAR_TILES  3
-#define CELL_CMD_FINISH       5
-#define CELL_CMD_RENDER       6
+#define CELL_CMD_EXIT          1
+#define CELL_CMD_FRAMEBUFFER   2
+#define CELL_CMD_CLEAR_SURFACE 3
+#define CELL_CMD_FINISH        4
+#define CELL_CMD_RENDER        5
 
 
 /**
@@ -66,10 +66,11 @@ struct cell_command_framebuffer
 
 
 /**
- * Clear framebuffer tiles to given value/color.
+ * Clear framebuffer to the given value/color.
  */
-struct cell_command_clear_tiles
+struct cell_command_clear_surface
 {
+   uint surface; /**< Temporary: 0=color, 1=Z */
    uint value;
 } ALIGN16_ATTRIB;
 
@@ -87,7 +88,7 @@ struct cell_command_render
 struct cell_command
 {
    struct cell_command_framebuffer fb;
-   struct cell_command_clear_tiles clear;
+   struct cell_command_clear_surface clear;
    struct cell_command_render render;
 } ALIGN16_ATTRIB;
 
index 15b8968..a7dbf24 100644 (file)
@@ -176,7 +176,8 @@ test_spus(struct cell_context *cell)
 
    for (i = 0; i < cell->num_spus; i++) {
       cell_global.command[i].clear.value = 0xff880044; /* XXX */
-      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_TILES);
+      cell_global.command[i].clear.surface = 0;
+      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
    }
 
    finish_all(cell->num_spus);
index 62e0feb..1e1548c 100644 (file)
@@ -47,42 +47,43 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
 {
    struct cell_context *cell = cell_context(pipe);
    uint i;
+   uint surfIndex;
 
    if (!ps->map)
       pipe_surface_map(ps);
 
-   if (pf_get_size(ps->format) != 4) {
-      printf("Cell: Skipping non 32bpp clear_surface\n");
-      return;
+   if (ps == cell->framebuffer.zbuf) {
+      surfIndex = 1;
    }
-#if 0
-   for (i = 0; i < cell->num_spus; i++) {
-      struct cell_command_framebuffer *fb = &cell_global.command[i].fb;
-      printf("%s %u start = 0x%x\n", __FUNCTION__, i, ps->map);
-      fb->color_start = ps->map;
-      fb->width = ps->width;
-      fb->height = ps->height;
-      fb->color_format = ps->format;
-      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FRAMEBUFFER);
+   else {
+      surfIndex = 0;
    }
-#endif
+
+   printf("Clear surf %u\n", surfIndex);
 
    for (i = 0; i < cell->num_spus; i++) {
 #if 1
       uint clr = clearValue;
-      /* XXX debug: clear color varied per-SPU to visualize tiles */
-      if ((clr & 0xff) == 0)
-         clr |= 64 + i * 8;
-      if ((clr & 0xff00) == 0)
-         clr |= (64 + i * 8) << 8;
-      if ((clr & 0xff0000) == 0)
-         clr |= (64 + i * 8) << 16;
-      if ((clr & 0xff000000) == 0)
-         clr |= (64 + i * 8) << 24;
+      if (surfIndex == 0) {
+         /* XXX debug: clear color varied per-SPU to visualize tiles */
+         if ((clr & 0xff) == 0)
+            clr |= 64 + i * 8;
+         if ((clr & 0xff00) == 0)
+            clr |= (64 + i * 8) << 8;
+         if ((clr & 0xff0000) == 0)
+            clr |= (64 + i * 8) << 16;
+         if ((clr & 0xff000000) == 0)
+            clr |= (64 + i * 8) << 24;
+      }
       cell_global.command[i].clear.value = clr;
 #else
       cell_global.command[i].clear.value = clearValue;
 #endif
-      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_TILES);
+      cell_global.command[i].clear.surface = surfIndex;
+      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
    }
+
+   /* XXX temporary */
+   cell_flush(&cell->pipe, 0x0);
+
 }
index 9580281..1552452 100644 (file)
@@ -50,7 +50,7 @@ volatile struct cell_init_info init;
 struct framebuffer fb;
 
 uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
+ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
 
 int DefaultTag;
 
@@ -70,7 +70,7 @@ get_tile(const struct framebuffer *fb, uint tx, uint ty, uint *tile,
          int tag, int zBuf)
 {
    const uint offset = ty * fb->width_tiles + tx;
-   const uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
+   const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4);
    const ubyte *src = zBuf ? fb->depth_start : fb->color_start;
 
    src += offset * bytesPerTile;
@@ -96,7 +96,7 @@ put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
          int tag, int zBuf)
 {
    const uint offset = ty * fb->width_tiles + tx;
-   const uint bytesPerTile = TILE_SIZE * TILE_SIZE * 4;
+   const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4);
    ubyte *dst = zBuf ? fb->depth_start : fb->color_start;
 
    dst += offset * bytesPerTile;
@@ -119,15 +119,22 @@ put_tile(const struct framebuffer *fb, uint tx, uint ty, const uint *tile,
 
 
 static void
-clear_tiles(const struct cell_command_clear_tiles *clear)
+clear_surface(const struct cell_command_clear_surface *clear)
 {
    uint num_tiles = fb.width_tiles * fb.height_tiles;
    uint i, j;
    int tag = init.id;
 
-   for (i = 0; i < TILE_SIZE; i++)
-      for (j = 0; j < TILE_SIZE; j++)
-         ctile[i][j] = clear->value;
+   if (clear->surface == 0) {
+      for (i = 0; i < TILE_SIZE; i++)
+         for (j = 0; j < TILE_SIZE; j++)
+            ctile[i][j] = clear->value;
+   }
+   else {
+      for (i = 0; i < TILE_SIZE; i++)
+         for (j = 0; j < TILE_SIZE; j++)
+            ztile[i][j] = clear->value;
+   }
 
    /*
    printf("SPU: %s num=%d w=%d h=%d\n",
@@ -137,7 +144,10 @@ clear_tiles(const struct cell_command_clear_tiles *clear)
    for (i = init.id; i < num_tiles; i += init.num_spus) {
       uint tx = i % fb.width_tiles;
       uint ty = i / fb.width_tiles;
-      put_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
+      if (clear->surface == 0)
+         put_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
+      else
+         put_tile(&fb, tx, ty, (uint *) ztile, tag, 1);
       /* XXX we don't want this here, but it fixes bad tile results */
       wait_on_mask(1 << tag);
    }
@@ -227,7 +237,7 @@ render(const struct cell_command_render *render)
       get_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
       wait_on_mask(1 << tag);  /* XXX temporary */
 
-      if (fb.depth_format == PIPE_FORMAT_Z32_UNORM) {
+      if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
          get_tile(&fb, tx, ty, (uint *) ztile, tag+1, 1);
          wait_on_mask(1 << (tag+1));  /* XXX temporary */
       }
@@ -265,7 +275,7 @@ render(const struct cell_command_render *render)
       put_tile(&fb, tx, ty, (uint *) ctile, tag, 0);
       wait_on_mask(1 << tag); /* XXX temp */
 
-      if (fb.depth_format == PIPE_FORMAT_Z32_UNORM) {
+      if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
          put_tile(&fb, tx, ty, (uint *) ztile, tag+1, 1);
          wait_on_mask(1 << (tag+1));  /* XXX temporary */
       }
@@ -313,11 +323,14 @@ main_loop(void)
          exitFlag = 1;
          break;
       case CELL_CMD_FRAMEBUFFER:
-         printf("SPU %u: FRAMEBUFFER: %d x %d at %p, format 0x%x\n", init.id,
+         printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x  zformat 0x%x\n",
+                init.id,
                 cmd.fb.width,
                 cmd.fb.height,
                 cmd.fb.color_start,
-                cmd.fb.color_format);
+                cmd.fb.color_format,
+                cmd.fb.depth_format);
+         printf("Z16 = 0x%x\n", PIPE_FORMAT_Z16_UNORM);
          fb.color_start = cmd.fb.color_start;
          fb.depth_start = cmd.fb.depth_start;
          fb.color_format = cmd.fb.color_format;
@@ -331,9 +344,10 @@ main_loop(void)
                 init.id, fb.width_tiles, fb.height_tiles);
          */
          break;
-      case CELL_CMD_CLEAR_TILES:
-         printf("SPU %u: CLEAR to 0x%08x\n", init.id, cmd.clear.value);
-         clear_tiles(&cmd.clear);
+      case CELL_CMD_CLEAR_SURFACE:
+         printf("SPU %u: CLEAR SURF %u to 0x%08x\n", init.id,
+                cmd.clear.surface, cmd.clear.value);
+         clear_surface(&cmd.clear);
          break;
       case CELL_CMD_RENDER:
          printf("SPU %u: RENDER %u verts, prim %u\n",
index c22679c..5e0516d 100644 (file)
@@ -50,7 +50,7 @@ struct framebuffer {
 extern struct framebuffer fb;
 
 extern uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
-extern uint ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
+extern ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
 
 extern int DefaultTag;
 
index 3659929..58fca2e 100644 (file)
@@ -227,6 +227,22 @@ eval_coeff( struct setup_stage *setup, uint slot,
 }
 
 
+static INLINE void
+eval_z( struct setup_stage *setup,
+        float x, float y, float result[4])
+{
+   uint slot = 0;
+   uint i = 2;
+   const float *dadx = setup->coef[slot].dadx;
+   const float *dady = setup->coef[slot].dady;
+
+   result[QUAD_TOP_LEFT] = setup->coef[slot].a0[i] + x * dadx[i] + y * dady[i];
+   result[QUAD_TOP_RIGHT] = result[0] + dadx[i];
+   result[QUAD_BOTTOM_LEFT] = result[0] + dady[i];
+   result[QUAD_BOTTOM_RIGHT] = result[0] + dadx[i] + dady[i];
+}
+
+
 static INLINE uint
 pack_color(const float color[4])
 {
@@ -263,9 +279,48 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask )
    int ix = x - cliprect_minx;
    int iy = y - cliprect_miny;
    float colors[4][4];
+   uint z;
 
    eval_coeff(setup, 1, (float) x, (float) y, colors);
 
+
+   if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+      float zvals[4];
+      eval_z(setup, (float) x, (float) y, zvals);
+
+      if (mask & MASK_TOP_LEFT) {
+         z = (uint) (zvals[0] * 65535.0);
+         if (z < ztile[iy][ix])
+            ztile[iy][ix] = z;
+         else
+            mask &= ~MASK_TOP_LEFT;
+      }
+
+      if (mask & MASK_TOP_RIGHT) {
+         z = (uint) (zvals[1] * 65535.0);
+         if (z < ztile[iy][ix+1])
+            ztile[iy][ix+1] = z;
+         else
+            mask &= ~MASK_TOP_RIGHT;
+      }
+
+      if (mask & MASK_BOTTOM_LEFT) {
+         z = (uint) (zvals[2] * 65535.0);
+         if (z < ztile[iy+1][ix])
+            ztile[iy+1][ix] = z;
+         else
+            mask &= ~MASK_BOTTOM_LEFT;
+      }
+
+      if (mask & MASK_BOTTOM_RIGHT) {
+         z = (uint) (zvals[3] * 65535.0);
+         if (z < ztile[iy+1][ix+1])
+            ztile[iy+1][ix+1] = z;
+         else
+            mask &= ~MASK_BOTTOM_RIGHT;
+      }
+   }
+
    if (mask & MASK_TOP_LEFT)
       ctile[iy][ix] = pack_color(colors[QUAD_TOP_LEFT]);
    if (mask & MASK_TOP_RIGHT)
@@ -512,10 +567,10 @@ static void const_coeff( struct setup_stage *setup,
  * for a triangle.
  */
 static void tri_linear_coeff( struct setup_stage *setup,
-                              unsigned slot )
+                              uint slot, uint firstComp, uint lastComp )
 {
    uint i;
-   for (i = 0; i < 4; i++) {
+   for (i = firstComp; i < lastComp; i++) {
       float botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
       float majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
       float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
@@ -637,7 +692,8 @@ static void setup_tri_coefficients( struct setup_stage *setup )
       }
    }
 #else
-   tri_linear_coeff(setup, 1);  /* slot 1 = color */
+   tri_linear_coeff(setup, 0, 2, 3);  /* slot 0, z */
+   tri_linear_coeff(setup, 1, 0, 4);  /* slot 1, color */
 #endif
 }