OSDN Git Service

Cell: added support for inlined vertex buffers.
authorBrian <brian.paul@tungstengraphics.com>
Sun, 27 Jan 2008 02:38:16 +0000 (19:38 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Sun, 27 Jan 2008 02:38:16 +0000 (19:38 -0700)
Small prims are now self-contained in batch buffers when space allows.

src/mesa/pipe/cell/common.h
src/mesa/pipe/cell/ppu/cell_vbuf.c
src/mesa/pipe/cell/spu/spu_main.c

index bdde166..0b63ed3 100644 (file)
@@ -128,6 +128,7 @@ struct cell_command_render
    const ushort *index_data;
    float xmin, ymin, xmax, ymax;
    boolean inline_indexes;
+   boolean inline_verts;
 } ALIGN16_ATTRIB;
 
 
index 59a4a2b..ee572b3 100644 (file)
@@ -39,8 +39,9 @@
 #include "pipe/draw/draw_vbuf.h"
 
 
-/** Allow render indexes to be inlined after RENDER command */
-#define ALLOW_INLINING 1
+/** Allow prim indexes, verts to be inlined after RENDER command */
+#define ALLOW_INLINE_INDEXES 1
+#define ALLOW_INLINE_VERTS 1
 
 
 /**
@@ -127,8 +128,10 @@ cell_vbuf_draw(struct vbuf_render *vbr,
    printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u  indexes = [%u %u %u ...]\n",
           nr_indices, nr_vertices,
           indices[0], indices[1], indices[2]);
-   printf("ind space = %u,  space = %u\n",
-          nr_indices * 2, cell_batch_free_space(cell));
+   printf("ind space = %u, vert space = %u, space = %u\n",
+          nr_indices * 2,
+          nr_vertices * 4 * cell->vertex_info.size,
+          cell_batch_free_space(cell));
 #endif
 
    /* compute x/y bounding box */
@@ -151,7 +154,8 @@ cell_vbuf_draw(struct vbuf_render *vbr,
 
    /* build/insert batch RENDER command */
    {
-      const uint index_bytes = (nr_indices * 2 + 3) & ~0x3;
+      const uint index_bytes = ROUNDUP4(nr_indices * 2);
+      const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size;
 
       struct cell_command_render *render
          = (struct cell_command_render *)
@@ -159,14 +163,8 @@ cell_vbuf_draw(struct vbuf_render *vbr,
       render->opcode = CELL_CMD_RENDER;
       render->prim_type = cvbr->prim;
 
-      render->num_verts = nr_vertices;
-      render->vertex_size = 4 * cell->vertex_info.size;
-      render->vertex_data = vertices;
-      ASSERT_ALIGN16(render->vertex_data);
-
       render->num_indexes = nr_indices;
-
-      if (ALLOW_INLINING &&
+      if (ALLOW_INLINE_INDEXES &&
           index_bytes <= cell_batch_free_space(cell)) {
          /* indices inlined, right after render cmd */
          void *dst = cell_batch_alloc(cell, index_bytes);
@@ -181,6 +179,24 @@ cell_vbuf_draw(struct vbuf_render *vbr,
          ASSERT_ALIGN16(render->index_data);
       }
 
+      render->vertex_size = 4 * cell->vertex_info.size;
+      render->num_verts = nr_vertices;
+      if (ALLOW_INLINE_VERTS &&
+         render->inline_indexes &&
+          vertex_bytes <= cell_batch_free_space(cell)) {
+         /* vertex data inlined, after indices */
+         void *dst = cell_batch_alloc(cell, vertex_bytes);
+         memcpy(dst, vertices, vertex_bytes);
+         render->inline_verts = TRUE;
+         render->vertex_data = NULL;
+      }
+      else {
+         render->inline_verts = FALSE;
+         render->vertex_data = vertices;
+         ASSERT_ALIGN16(render->vertex_data);
+      }
+
+
       render->xmin = xmin;
       render->ymin = ymin;
       render->xmax = xmax;
index 92be0b4..0c83900 100644 (file)
@@ -216,16 +216,21 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
    ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB;
    ushort index_data[CELL_MAX_VBUF_INDEXES] ALIGN16_ATTRIB;
    const uint vertex_size = render->vertex_size; /* in bytes */
+   const uint total_vertex_bytes = render->num_verts * vertex_size;
+   const ubyte *vertices;
    const ushort *indexes;
+   uint mask;
    uint i, j;
 
 
    if (Debug) {
-      printf("SPU %u: RENDER prim %u, num_vert=%u  num_ind=%u  inlined=%u\n",
+      printf("SPU %u: RENDER prim %u, num_vert=%u  num_ind=%u  "
+             "inline_vert=%u  inline_ind=%u\n",
              spu.init.id,
              render->prim_type,
              render->num_verts,
              render->num_indexes,
+             render->inline_verts,
              render->inline_indexes);
 
       /*
@@ -237,43 +242,28 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
              render->index_data, render->vertex_data);
    }
 
+   ASSERT(sizeof(*render) % 4 == 0);
    ASSERT_ALIGN16(render->vertex_data);
    ASSERT_ALIGN16(render->index_data);
 
 
    /**
-    ** Get vertices
+    ** Get vertex, index buffers if not inlined
     **/
-   {
-      const uint total_vertex_bytes = render->num_verts * vertex_size;
-
+   if (!render->inline_verts) {
       ASSERT(total_vertex_bytes % 16 == 0);
 
-      /* get vertex data from main memory */
       mfc_get(vertex_data,  /* dest */
               (unsigned int) render->vertex_data,  /* src */
               total_vertex_bytes,  /* size */
               TAG_VERTEX_BUFFER,
               0, /* tid */
               0  /* rid */);
-   }
 
-
-   /**
-    ** Get indexes
-    **/
-   if (render->inline_indexes) {
-      /* indexes are right after the render command in the batch buffer */
-      ASSERT(sizeof(*render) % 4 == 0);
-      indexes = (ushort *) (render + 1);
-
-      *pos_incr = (render->num_indexes * 2 + 3) / 4;
-
-      /* wait for vertex data */
-      wait_on_mask_all(1 << TAG_VERTEX_BUFFER);
+      vertices = vertex_data;
    }
-   else {
-      /* indexes are in separate buffer */
+
+   if (!render->inline_indexes) {
       uint total_index_bytes;
 
       *pos_incr = 0;
@@ -293,12 +283,34 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
               TAG_INDEX_BUFFER,
               0, /* tid */
               0  /* rid */);
+   }
+
+
+   /**
+    ** Get pointers to inlined indexes, verts, if present
+    **/
+   if (render->inline_indexes) {
+      /* indexes are right after the render command in the batch buffer */
+      indexes = (ushort *) (render + 1);
+      *pos_incr = (render->num_indexes * 2 + 3) / 4;
 
-      wait_on_mask_all((1 << TAG_VERTEX_BUFFER) |
-                       (1 << TAG_INDEX_BUFFER));
+      if (render->inline_verts) {
+         /* vertices are after indexes, if inlined */
+         vertices = (const ubyte *) (render + 1) + *pos_incr * 4;
+         *pos_incr = *pos_incr + total_vertex_bytes / 4;
+      }
    }
 
 
+   /* wait for vertex and/or index buffers if not inlined */
+   mask = 0x0;
+   if (!render->inline_verts)
+      mask |= (1 << TAG_VERTEX_BUFFER);
+   if (!render->inline_indexes)
+      mask |= (1 << TAG_INDEX_BUFFER);
+   wait_on_mask_all(mask);
+
+
    /**
     ** find tiles which intersect the prim bounding box
     **/
@@ -347,9 +359,9 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
       for (j = 0; j < render->num_indexes; j += 3) {
          const float *v0, *v1, *v2;
 
-         v0 = (const float *) (vertex_data + indexes[j+0] * vertex_size);
-         v1 = (const float *) (vertex_data + indexes[j+1] * vertex_size);
-         v2 = (const float *) (vertex_data + indexes[j+2] * vertex_size);
+         v0 = (const float *) (vertices + indexes[j+0] * vertex_size);
+         v1 = (const float *) (vertices + indexes[j+1] * vertex_size);
+         v2 = (const float *) (vertices + indexes[j+2] * vertex_size);
 
          tri_draw(v0, v1, v2, tx, ty);
       }