Cell: checkpoint: draw_vbuf code in place and works, but not enabled by default yet.
authorBrian <brian.paul@tungstengraphics.com>
Fri, 11 Jan 2008 00:01:52 +0000 (17:01 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 11 Jan 2008 00:01:52 +0000 (17:01 -0700)
src/mesa/pipe/cell/common.h
src/mesa/pipe/cell/ppu/cell_vbuf.c
src/mesa/pipe/cell/spu/main.c
src/mesa/pipe/cell/spu/main.h

index d7de0beece23d41cf2a94b68893f9cf82302f726..dc2db299c4894a5a5707321a90d3779fb388e23e 100644 (file)
@@ -52,6 +52,7 @@
 #define CELL_CMD_CLEAR_SURFACE 3
 #define CELL_CMD_FINISH        4
 #define CELL_CMD_RENDER        5
+#define CELL_CMD_RENDER_VBUF   6
 
 
 /**
@@ -84,12 +85,26 @@ struct cell_command_render
 } ALIGN16_ATTRIB;
 
 
+#define CELL_MAX_VBUF_SIZE    (16 * 1024)
+#define CELL_MAX_VBUF_INDEXES 1024
+struct cell_command_render_vbuf
+{
+   uint prim_type;
+   uint num_verts, num_attribs;
+   uint num_indexes;
+   const void *vertex_data;
+   const ushort *index_data;
+   float xmin, ymin, xmax, ymax;
+} ALIGN16_ATTRIB;
+
+
 /** XXX unions don't seem to work */
 struct cell_command
 {
    struct cell_command_framebuffer fb;
    struct cell_command_clear_surface clear;
    struct cell_command_render render;
+   struct cell_command_render_vbuf render_vbuf;
 } ALIGN16_ATTRIB;
 
 
index 1a43d237d90769ea428ecf2d9d329b3d9d056075..cf468204bb1865ebf5f478a3cb23ebd3ff8f0e8a 100644 (file)
@@ -32,6 +32,7 @@
 
 
 #include "cell_context.h"
+#include "cell_spu.h"
 #include "cell_vbuf.h"
 #include "pipe/draw/draw_vbuf.h"
 
@@ -69,7 +70,7 @@ static void *
 cell_vbuf_allocate_vertices(struct vbuf_render *vbr,
                             ushort vertex_size, ushort nr_vertices)
 {
-   printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);
+   /*printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);*/
    return align_malloc(vertex_size * nr_vertices, 16);
 }
 
@@ -79,23 +80,63 @@ cell_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
 {
    struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
    cvbr->prim = prim;
-   printf("cell_set_prim %u\n", prim);
+   /*printf("cell_set_prim %u\n", prim);*/
 }
 
 
+#if 0
 static void
 cell_vbuf_draw(struct vbuf_render *vbr,
-               const ushort *indices, unsigned nr_indices)
+               uint prim,
+              const ushort *indices,
+               uint nr_indices,
+               const void *vertices,
+               uint nr_vertices,
+               uint vertex_size)
 {
-   printf("cell_vbuf_draw nr_indices = %u\n", nr_indices);
+   struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr);
+   struct cell_context *cell = cvbr->cell;
+   uint i;
+
+   /*printf("cell_vbuf_draw nr_indices = %u\n", nr_indices);*/
+
+   if (prim != PIPE_PRIM_TRIANGLES)
+      return; /* only render tris for now */
+
+   for (i = 0; i < cell->num_spus; i++) {
+      struct cell_command_render_vbuf *render = &cell_global.command[i].render_vbuf;
+      render->prim_type = prim;
+      render->num_verts = nr_vertices;
+      render->num_attribs = CELL_MAX_ATTRIBS; /* XXX fix */
+      render->vertex_data = vertices;
+      render->index_data = indices;
+      render->num_indexes = nr_indices;
+#if 0
+      render->xmin = cell->prim_buffer.xmin;
+      render->ymin = cell->prim_buffer.ymin;
+      render->xmax = cell->prim_buffer.xmax;
+      render->ymax = cell->prim_buffer.ymax;
+#else
+      render->xmin = -100;
+      render->ymin = -100;
+      render->xmax =  100;
+      render->ymax =  100;
+#endif
+
+      ASSERT_ALIGN16(render->vertex_data);
+      ASSERT_ALIGN16(render->index_data);
+      send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_RENDER_VBUF);
+   }
+
+   cell_flush(&cell->pipe, 0x0);
 }
-
+#endif
 
 static void
 cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, 
                            unsigned vertex_size, unsigned vertices_used)
 {
-   printf("Free verts %u * %u\n", vertex_size, vertices_used);
+   /*printf("Free verts %u * %u\n", vertex_size, vertices_used);*/
    align_free(vertices);
 }
 
@@ -120,13 +161,15 @@ cell_init_vbuf(struct cell_context *cell)
 
    cell->vbuf_render = CALLOC_STRUCT(cell_vbuf_render);
 
-   cell->vbuf_render->base.max_indices = 100;
-   cell->vbuf_render->base.max_vertex_buffer_bytes = 16 * 1024;
+   cell->vbuf_render->base.max_indices = CELL_MAX_VBUF_INDEXES;
+   cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_MAX_VBUF_SIZE;
 
    cell->vbuf_render->base.get_vertex_info = cell_vbuf_get_vertex_info;
    cell->vbuf_render->base.allocate_vertices = cell_vbuf_allocate_vertices;
    cell->vbuf_render->base.set_primitive = cell_vbuf_set_primitive;
+#if 0
    cell->vbuf_render->base.draw = cell_vbuf_draw;
+#endif
    cell->vbuf_render->base.release_vertices = cell_vbuf_release_vertices;
    cell->vbuf_render->base.destroy = cell_vbuf_destroy;
 
index 5d47ca85d3cb5f04d534fa961afeca5cb9fbe2e1..6dbd93f5305bc0a3d62bcdfe5fd606315bcd8010 100644 (file)
@@ -382,6 +382,143 @@ render(const struct cell_command_render *render)
 }
 
 
+static void
+render_vbuf(const struct cell_command_render_vbuf *render)
+{
+   /* we'll DMA into these buffers */
+   ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB;
+   ushort indexes[CELL_MAX_VBUF_INDEXES] ALIGN16_ATTRIB;
+   uint i, j, vertex_bytes, index_bytes;
+
+   ASSERT_ALIGN16(render->vertex_data);
+   ASSERT_ALIGN16(render->index_data);
+
+   /* how much vertex data */
+   vertex_bytes = render->num_verts * render->num_attribs * 4 * sizeof(float);
+   index_bytes = render->num_indexes * sizeof(ushort);
+   if (index_bytes < 8)
+      index_bytes = 8;
+   else
+      index_bytes = (index_bytes + 15) & ~0xf; /* multiple of 16 */
+
+   /*
+   printf("VBUF: indices at %p,  vertices at %p  vertex_bytes %u  ind_bytes %u\n",
+          render->index_data, render->vertex_data, vertex_bytes, index_bytes);
+   */
+
+   /* get vertex data from main memory */
+   mfc_get(vertex_data,  /* dest */
+           (unsigned int) render->vertex_data,  /* src */
+           vertex_bytes,  /* size */
+           TAG_VERTEX_BUFFER,
+           0, /* tid */
+           0  /* rid */);
+
+   /* get index data from main memory */
+   mfc_get(indexes,  /* dest */
+           (unsigned int) render->index_data,  /* src */
+           index_bytes,
+           TAG_INDEX_BUFFER,
+           0, /* tid */
+           0  /* rid */);
+
+   wait_on_mask(1 << TAG_VERTEX_BUFFER);
+   wait_on_mask(1 << TAG_INDEX_BUFFER);
+
+   /* find tiles which intersect the prim bounding box */
+   uint txmin, tymin, box_width_tiles, box_num_tiles;
+#if 0
+   tile_bounding_box(render, &txmin, &tymin,
+                     &box_num_tiles, &box_width_tiles);
+#else
+   txmin = 0;
+   tymin = 0;
+   box_num_tiles = fb.width_tiles * fb.height_tiles;
+   box_width_tiles = fb.width_tiles;
+#endif
+
+   /* make sure any pending clears have completed */
+   wait_on_mask(1 << TAG_SURFACE_CLEAR);
+
+   /* loop over tiles */
+   for (i = init.id; i < box_num_tiles; i += init.num_spus) {
+      const uint tx = txmin + i % box_width_tiles;
+      const uint ty = tymin + i / box_width_tiles;
+
+      assert(tx < fb.width_tiles);
+      assert(ty < fb.height_tiles);
+
+      /* Start fetching color/z tiles.  We'll wait for completion when
+       * we need read/write to them later in triangle rasterization.
+       */
+      if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+         if (tile_status_z[ty][tx] != TILE_STATUS_CLEAR) {
+            get_tile(&fb, tx, ty, (uint *) ztile, TAG_READ_TILE_Z, 1);
+         }
+      }
+
+      if (tile_status[ty][tx] != TILE_STATUS_CLEAR) {
+         get_tile(&fb, tx, ty, (uint *) ctile, TAG_READ_TILE_COLOR, 0);
+      }
+
+      assert(render->prim_type == PIPE_PRIM_TRIANGLES);
+
+      /* loop over tris */
+      for (j = 0; j < render->num_indexes; j += 3) {
+         struct prim_header prim;
+         const float *vbuf = (const float *) vertex_data;
+         const float *v0, *v1, *v2;
+
+         v0 = vbuf + indexes[j] * render->num_attribs * 4;
+         v1 = vbuf + indexes[j+1] * render->num_attribs * 4;
+         v2 = vbuf + indexes[j+2] * render->num_attribs * 4;
+
+         /*
+         printf("  %u: Triangle %g,%g  %g,%g  %g,%g\n",
+                init.id,
+                prim_buffer.vertex[j*3+0][0][0],
+                prim_buffer.vertex[j*3+0][0][1],
+                prim_buffer.vertex[j*3+1][0][0],
+                prim_buffer.vertex[j*3+1][0][1],
+                prim_buffer.vertex[j*3+2][0][0],
+                prim_buffer.vertex[j*3+2][0][1]);
+         */
+
+         /* pos */
+         COPY_4V(prim.v[0].data[0], v0);
+         COPY_4V(prim.v[1].data[0], v1);
+         COPY_4V(prim.v[2].data[0], v2);
+
+         /* color */
+         COPY_4V(prim.v[0].data[1], v0 + 4);
+         COPY_4V(prim.v[1].data[1], v1 + 4);
+         COPY_4V(prim.v[2].data[1], v2 + 4);
+
+         tri_draw(&prim, tx, ty);
+      }
+
+      /* write color/z tiles back to main framebuffer, if dirtied */
+      if (tile_status[ty][tx] == TILE_STATUS_DIRTY) {
+         put_tile(&fb, tx, ty, (uint *) ctile, TAG_WRITE_TILE_COLOR, 0);
+         tile_status[ty][tx] = TILE_STATUS_DEFINED;
+      }
+      if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+         if (tile_status_z[ty][tx] == TILE_STATUS_DIRTY) {
+            put_tile(&fb, tx, ty, (uint *) ztile, TAG_WRITE_TILE_Z, 1);
+            tile_status_z[ty][tx] = TILE_STATUS_DEFINED;
+         }
+      }
+
+      /* XXX move these... */
+      wait_on_mask(1 << TAG_WRITE_TILE_COLOR);
+      if (fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
+         wait_on_mask(1 << TAG_WRITE_TILE_Z);
+      }
+   }
+}
+
+
+
 /**
  * Temporary/simple main loop for SPEs: Get a command, execute it, repeat.
  */
@@ -459,6 +596,15 @@ main_loop(void)
                    init.id, cmd.render.num_verts, cmd.render.prim_type);
          render(&cmd.render);
          break;
+      case CELL_CMD_RENDER_VBUF:
+         if (Debug)
+            printf("SPU %u: RENDER_VBUF prim %u, indices: %u, nr_vert: %u\n",
+                   init.id,
+                   cmd.render_vbuf.prim_type,
+                   cmd.render_vbuf.num_verts,
+                   cmd.render_vbuf.num_indexes);
+         render_vbuf(&cmd.render_vbuf);
+         break;
 
       case CELL_CMD_FINISH:
          if (Debug)
index ee4248ead648f4679696cd9eafc5ad1959d55aa6..fce113b77db4a6824401107da4d6d143935a4187 100644 (file)
@@ -64,6 +64,7 @@ extern ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB;
 
 #define TAG_SURFACE_CLEAR     10
 #define TAG_VERTEX_BUFFER     11
+#define TAG_INDEX_BUFFER      16
 #define TAG_READ_TILE_COLOR   12
 #define TAG_READ_TILE_Z       13
 #define TAG_WRITE_TILE_COLOR  14