gallium: rename pipe_buffer_handle to pipe_buffer, rework pipebuffer/ code
[mesa.git] / src / mesa / pipe / draw / draw_vbuf.c
index 3f6606de86f660653b01d563e2d85b9096a8f609..82051d2e65bf010f32842e1ad82cb165ce638260 100644 (file)
@@ -83,7 +83,8 @@ vbuf_stage( struct draw_stage *stage )
 
 
 static void vbuf_flush_indices( struct draw_stage *stage );
-static void vbuf_flush_vertices( struct draw_stage *stage,
+static void vbuf_flush_vertices( struct draw_stage *stage );
+static void vbuf_alloc_vertices( struct draw_stage *stage,
                                  unsigned new_vertex_size );
 
 
@@ -98,8 +99,10 @@ overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )
 static INLINE void 
 check_space( struct vbuf_stage *vbuf, unsigned nr )
 {
-   if (vbuf->nr_vertices + nr > vbuf->max_vertices ) 
-      vbuf_flush_vertices(&vbuf->stage, vbuf->vertex_size );
+   if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
+      vbuf_flush_vertices(&vbuf->stage);
+      vbuf_alloc_vertices(&vbuf->stage, vbuf->vertex_size);
+   }
 
    if (vbuf->nr_indices + nr > vbuf->max_indices )
       vbuf_flush_indices(&vbuf->stage);
@@ -107,10 +110,11 @@ check_space( struct vbuf_stage *vbuf, unsigned nr )
 
 
 /**
- * Extract the needed fields from vertex_header and emit i915 dwords.
+ * Extract the needed fields from post-transformed vertex and emit
+ * a hardware(driver) vertex.
  * Recall that the vertices are constructed by the 'draw' module and
  * have a couple of slots at the beginning (1-dword header, 4-dword
- * clip pos) that we ignore here.
+ * clip pos) that we ignore here.  We only use the vertex->data[] fields.
  */
 static INLINE void 
 emit_vertex( struct vbuf_stage *vbuf,
@@ -136,37 +140,48 @@ emit_vertex( struct vbuf_stage *vbuf,
    vertex->vertex_id = vbuf->nr_vertices++;
 
    for (i = 0; i < vinfo->num_attribs; i++) {
-      switch (vinfo->format[i]) {
-      case FORMAT_OMIT:
+      uint j = vinfo->src_index[i];
+      switch (vinfo->emit[i]) {
+      case EMIT_OMIT:
          /* no-op */
          break;
-      case FORMAT_1F:
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
+      case EMIT_ALL:
+         /* just copy the whole vertex as-is to the vbuf */
+         assert(i == 0);
+         memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4);
+         vbuf->vertex_ptr += vinfo->size;
+         return;
+      case EMIT_1F:
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+         count++;
+         break;
+      case EMIT_1F_PSIZE:
+         *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size);
          count++;
          break;
-      case FORMAT_2F:
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
+      case EMIT_2F:
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
          count += 2;
          break;
-      case FORMAT_3F:
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][2]);
+      case EMIT_3F:
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
          count += 3;
          break;
-      case FORMAT_4F:
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][2]);
-         *vbuf->vertex_ptr++ = fui(vertex->data[i][3]);
+      case EMIT_4F:
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
+         *vbuf->vertex_ptr++ = fui(vertex->data[j][3]);
          count += 4;
          break;
-      case FORMAT_4UB:
-        *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[i][2] ),
-                                        float_to_ubyte( vertex->data[i][1] ),
-                                        float_to_ubyte( vertex->data[i][0] ),
-                                        float_to_ubyte( vertex->data[i][3] ));
+      case EMIT_4UB:
+        *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ),
+                                        float_to_ubyte( vertex->data[j][1] ),
+                                        float_to_ubyte( vertex->data[j][0] ),
+                                        float_to_ubyte( vertex->data[j][3] ));
          count += 1;
          break;
       default:
@@ -225,17 +240,44 @@ vbuf_point( struct draw_stage *stage,
 }
 
 
+/**
+ * Set the prim type for subsequent vertices.
+ * This may result in a new vertex size.  The existing vbuffer (if any)
+ * will be flushed if needed and a new one allocated.
+ */
+static void
+vbuf_set_prim( struct draw_stage *stage, uint newprim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage(stage);
+   const struct vertex_info *vinfo;
+   unsigned vertex_size;
+
+   assert(newprim == PIPE_PRIM_POINTS ||
+          newprim == PIPE_PRIM_LINES ||
+          newprim == PIPE_PRIM_TRIANGLES);
+
+   vbuf->prim = newprim;
+   vbuf->render->set_primitive(vbuf->render, newprim);
+
+   vinfo = vbuf->render->get_vertex_info(vbuf->render);
+   vertex_size = vinfo->size * sizeof(float);
+
+   if (vertex_size != vbuf->vertex_size)
+      vbuf_flush_vertices(stage);
+
+   if (!vbuf->vertices)
+      vbuf_alloc_vertices(stage, vertex_size);
+}
+
+
 static void 
 vbuf_first_tri( struct draw_stage *stage,
                 struct prim_header *prim )
 {
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
    vbuf_flush_indices( stage );   
    stage->tri = vbuf_tri;
+   vbuf_set_prim(stage, PIPE_PRIM_TRIANGLES);
    stage->tri( stage, prim );
-   vbuf->prim = PIPE_PRIM_TRIANGLES;
-   vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_TRIANGLES);
 }
 
 
@@ -243,13 +285,10 @@ static void
 vbuf_first_line( struct draw_stage *stage,
                  struct prim_header *prim )
 {
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
    vbuf_flush_indices( stage );
    stage->line = vbuf_line;
+   vbuf_set_prim(stage, PIPE_PRIM_LINES);
    stage->line( stage, prim );
-   vbuf->prim = PIPE_PRIM_LINES;
-   vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_LINES);
 }
 
 
@@ -257,13 +296,10 @@ static void
 vbuf_first_point( struct draw_stage *stage,
                   struct prim_header *prim )
 {
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
    vbuf_flush_indices( stage );
    stage->point = vbuf_point;
+   vbuf_set_prim(stage, PIPE_PRIM_POINTS);
    stage->point( stage, prim );
-   vbuf->prim = PIPE_PRIM_POINTS;
-   vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_POINTS);
 }
 
 
@@ -275,7 +311,7 @@ vbuf_flush_indices( struct draw_stage *stage )
    if(!vbuf->nr_indices)
       return;
    
-   assert(vbuf->vertex_ptr - vbuf->vertices == 
+   assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == 
           vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
 
    switch(vbuf->prim) {
@@ -291,15 +327,13 @@ vbuf_flush_indices( struct draw_stage *stage )
       assert(0);
    }
    
-   vbuf->render->draw( vbuf->render,
-                       vbuf->prim,
-                       vbuf->indices,
-                       vbuf->nr_indices,
-                       vbuf->vertices,
-                       vbuf->nr_vertices,
-                       vbuf->vertex_size );
-
+   vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
+   
    vbuf->nr_indices = 0;
+
+   stage->point = vbuf_first_point;
+   stage->line = vbuf_first_line;
+   stage->tri = vbuf_first_tri;
 }
 
 
@@ -311,8 +345,7 @@ vbuf_flush_indices( struct draw_stage *stage )
  * we flush.
  */
 static void 
-vbuf_flush_vertices( struct draw_stage *stage,
-                     unsigned new_vertex_size )
+vbuf_flush_vertices( struct draw_stage *stage )
 {
    struct vbuf_stage *vbuf = vbuf_stage( stage );
 
@@ -332,15 +365,24 @@ vbuf_flush_vertices( struct draw_stage *stage,
       vbuf->vertex_ptr = vbuf->vertices = NULL;
       
    }
+}
    
+
+static void 
+vbuf_alloc_vertices( struct draw_stage *stage,
+                    unsigned new_vertex_size )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
    assert(!vbuf->nr_indices);
+   assert(!vbuf->vertices);
    
    /* Allocate a new vertex buffer */
    vbuf->vertex_size = new_vertex_size;
    vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
-   vbuf->vertices = vbuf->render->allocate_vertices(vbuf->render,
-                                                      vbuf->vertex_size,
-                                                      vbuf->max_vertices) ;
+   vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
+                                                    (ushort) vbuf->vertex_size,
+                                                    (ushort) vbuf->max_vertices);
    vbuf->vertex_ptr = vbuf->vertices;
 }
 
@@ -348,20 +390,16 @@ vbuf_flush_vertices( struct draw_stage *stage,
 static void 
 vbuf_begin( struct draw_stage *stage )
 {
-   struct vbuf_stage *vbuf = vbuf_stage(stage);
-   const struct vertex_info *vinfo = vbuf->render->get_vertex_info(vbuf->render);
-   unsigned vertex_size = vinfo->size * sizeof(float);
-
-   if(vbuf->vertex_size != vertex_size)
-      vbuf_flush_vertices(&vbuf->stage, vertex_size);
+   /* no-op, vbuffer allocated by first point/line/tri */
 }
 
 
 static void 
 vbuf_end( struct draw_stage *stage )
 {
+//   vbuf_flush_indices( stage );
    /* XXX: Overkill */
-   vbuf_flush_indices( stage );
+   vbuf_flush_vertices( stage );
    
    stage->point = vbuf_first_point;
    stage->line = vbuf_first_line;
@@ -372,6 +410,7 @@ vbuf_end( struct draw_stage *stage )
 static void 
 vbuf_reset_stipple_counter( struct draw_stage *stage )
 {
+   (void) stage;
 }
 
 
@@ -405,10 +444,13 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
 
    assert(render->max_indices < UNDEFINED_VERTEX_ID);
    vbuf->max_indices = render->max_indices;
-   vbuf->indices = align_malloc( vbuf->max_indices, 16 );
+   vbuf->indices = (ushort *)
+      align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 );
    
    vbuf->vertices = NULL;
    vbuf->vertex_ptr = vbuf->vertices;
+
+   vbuf->prim = ~0;
    
    return &vbuf->stage;
 }