draw: add map/unmap directives for swtnl driver interface
authorKeith Whitwell <keithw@vmware.com>
Tue, 17 Feb 2009 12:07:09 +0000 (12:07 +0000)
committerKeith Whitwell <keithw@vmware.com>
Tue, 17 Feb 2009 12:07:09 +0000 (12:07 +0000)
Previously draw module asked for a pointer into (mapped) vertex data,
which it would incrementally fill and emit draw commands against.  This
was hard for the drivers to deal with, especially in the case where a
draw command would force a flush and thus an unmap of the vertex data.

With this change, the draw module explicitly maps & then unmaps vertex
data prior to emitting draw commands.

src/gallium/auxiliary/draw/draw_pipe_vbuf.c
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_vbuf.h

index 9153bc2f8652b81959722b112989e74390577f5c..b08341145870843c8eb53ac529d958848a7f7024 100644 (file)
@@ -93,7 +93,6 @@ vbuf_stage( struct draw_stage *stage )
 }
 
 
-static void vbuf_flush_indices( struct vbuf_stage *vbuf );
 static void vbuf_flush_vertices( struct vbuf_stage *vbuf );
 static void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
 
@@ -109,13 +108,12 @@ 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);
-      vbuf_alloc_vertices(vbuf);
+   if (vbuf->nr_vertices + nr > vbuf->max_vertices ||
+       vbuf->nr_indices + nr > vbuf->max_indices)
+   {
+      vbuf_flush_vertices( vbuf );
+      vbuf_alloc_vertices( vbuf );
    }
-
-   if (vbuf->nr_indices + nr > vbuf->max_indices )
-      vbuf_flush_indices(vbuf);
 }
 
 
@@ -202,7 +200,7 @@ vbuf_point( struct draw_stage *stage,
  * will be flushed if needed and a new one allocated.
  */
 static void
-vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
+vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
 {
    struct translate_key hw_key;
    unsigned dst_offset;
@@ -217,11 +215,7 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
     * state change.
     */
    vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
-
-   if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) {
-      vbuf_flush_vertices(vbuf);
-      vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
-   }
+   vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
 
    /* Translate from pipeline vertices to hw vertices.
     */
@@ -294,8 +288,8 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
 
    /* Allocate new buffer?
     */
-   if (!vbuf->vertices)
-      vbuf_alloc_vertices(vbuf);
+   assert(vbuf->vertices == NULL);
+   vbuf_alloc_vertices(vbuf);
 }
 
 
@@ -305,9 +299,9 @@ vbuf_first_tri( struct draw_stage *stage,
 {
    struct vbuf_stage *vbuf = vbuf_stage( stage );
 
-   vbuf_flush_indices( vbuf );   
+   vbuf_flush_vertices( vbuf );
+   vbuf_start_prim(vbuf, PIPE_PRIM_TRIANGLES);
    stage->tri = vbuf_tri;
-   vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);
    stage->tri( stage, prim );
 }
 
@@ -318,9 +312,9 @@ vbuf_first_line( struct draw_stage *stage,
 {
    struct vbuf_stage *vbuf = vbuf_stage( stage );
 
-   vbuf_flush_indices( vbuf );
+   vbuf_flush_vertices( vbuf );
+   vbuf_start_prim(vbuf, PIPE_PRIM_LINES);
    stage->line = vbuf_line;
-   vbuf_set_prim(vbuf, PIPE_PRIM_LINES);
    stage->line( stage, prim );
 }
 
@@ -331,53 +325,42 @@ vbuf_first_point( struct draw_stage *stage,
 {
    struct vbuf_stage *vbuf = vbuf_stage( stage );
 
-   vbuf_flush_indices( vbuf );
+   vbuf_flush_vertices(vbuf);
+   vbuf_start_prim(vbuf, PIPE_PRIM_POINTS);
    stage->point = vbuf_point;
-   vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);
    stage->point( stage, prim );
 }
 
 
-static void 
-vbuf_flush_indices( struct vbuf_stage *vbuf ) 
-{
-   if(!vbuf->nr_indices)
-      return;
-   
-   assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == 
-          vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
-
-   vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
-   
-   vbuf->nr_indices = 0;
-}
-
 
 /**
  * Flush existing vertex buffer and allocate a new one.
- * 
- * XXX: We separate flush-on-index-full and flush-on-vb-full, but may 
- * raise issues uploading vertices if the hardware wants to flush when
- * we flush.
  */
 static void 
 vbuf_flush_vertices( struct vbuf_stage *vbuf )
 {
-   if(vbuf->vertices) {      
-      vbuf_flush_indices(vbuf);
-      
+   if(vbuf->vertices) {
+
+      vbuf->render->unmap_vertices( vbuf->render, 0, vbuf->nr_vertices );
+
+      if (vbuf->nr_indices) 
+      {
+         vbuf->render->draw(vbuf->render, 
+                            vbuf->indices, 
+                            vbuf->nr_indices );
+   
+         vbuf->nr_indices = 0;
+      }
+     
       /* Reset temporary vertices ids */
       if(vbuf->nr_vertices)
         draw_reset_vertex_ids( vbuf->stage.draw );
       
       /* Free the vertex buffer */
-      vbuf->render->release_vertices(vbuf->render,
-                                     vbuf->vertices,
-                                     vbuf->vertex_size,
-                                     vbuf->nr_vertices);
+      vbuf->render->release_vertices( vbuf->render );
+
       vbuf->max_vertices = vbuf->nr_vertices = 0;
       vbuf->vertex_ptr = vbuf->vertices = NULL;
-      
    }
 }
    
@@ -402,9 +385,12 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf )
     * and it will flush itself if necessary to do so.  If this does
     * fail, we are basically without usable hardware.
     */
-   vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
-                                                            (ushort) vbuf->vertex_size,
-                                                            (ushort) vbuf->max_vertices);
+   vbuf->render->allocate_vertices(vbuf->render,
+                                   (ushort) vbuf->vertex_size,
+                                   (ushort) vbuf->max_vertices);
+
+   vbuf->vertices = (uint *) vbuf->render->map_vertices( vbuf->render );
+   
    vbuf->vertex_ptr = vbuf->vertices;
 }
 
@@ -415,14 +401,11 @@ vbuf_flush( struct draw_stage *stage, unsigned flags )
 {
    struct vbuf_stage *vbuf = vbuf_stage( stage );
 
-   vbuf_flush_indices( vbuf );
+   vbuf_flush_vertices( vbuf );
 
    stage->point = vbuf_first_point;
    stage->line = vbuf_first_line;
    stage->tri = vbuf_first_tri;
-
-   if (flags & DRAW_FLUSH_BACKEND)
-      vbuf_flush_vertices( vbuf );
 }
 
 
index c02f229110ade71949ddcd9ef4a7f37da4559dae..aecaeee5b9e85b13b42378c054599e6331f3cc9e 100644 (file)
@@ -173,9 +173,7 @@ void draw_pt_emit( struct pt_emit *emit,
 
 void draw_pt_emit_linear( struct pt_emit *emit,
                           const float (*vertex_data)[4],
-                          unsigned vertex_count,
                           unsigned stride,
-                          unsigned start,
                           unsigned count );
 
 void draw_pt_emit_destroy( struct pt_emit *emit );
index 232dfdaed2d71e23a65dd1b6d94599148f5e08e3..8a6e01809e4c4efaf10c902b1010c82994d0aa71 100644 (file)
@@ -178,9 +178,11 @@ void draw_pt_emit( struct pt_emit *emit,
       return;
    }
 
-   hw_verts = render->allocate_vertices(render,
-                                       (ushort)translate->key.output_stride,
-                                       (ushort)vertex_count);
+   render->allocate_vertices(render,
+                             (ushort)translate->key.output_stride,
+                             (ushort)vertex_count);
+
+   hw_verts = render->map_vertices( render );
    if (!hw_verts) {
       assert(0);
       return;
@@ -201,22 +203,21 @@ void draw_pt_emit( struct pt_emit *emit,
                   vertex_count,
                   hw_verts );
 
+   render->unmap_vertices( render, 
+                           0, 
+                           vertex_count );
+
    render->draw(render,
                elts,
                count);
 
-   render->release_vertices(render,
-                           hw_verts,
-                           translate->key.output_stride,
-                           vertex_count);
+   render->release_vertices(render);
 }
 
 
 void draw_pt_emit_linear(struct pt_emit *emit,
                          const float (*vertex_data)[4],
-                         unsigned vertex_count,
                          unsigned stride,
-                         unsigned start,
                          unsigned count)
 {
    struct draw_context *draw = emit->draw;
@@ -231,26 +232,23 @@ void draw_pt_emit_linear(struct pt_emit *emit,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (count >= UNDEFINED_VERTEX_ID) {
-      assert(0);
-      return;
-   }
+   if (count >= UNDEFINED_VERTEX_ID)
+      goto fail;
 
    /* XXX: and work out some way to coordinate the render primitive
     * between vbuf.c and here...
     */
-   if (!draw->render->set_primitive(draw->render, emit->prim)) {
-      assert(0);
-      return;
-   }
+   if (!draw->render->set_primitive(draw->render, emit->prim)) 
+      goto fail;
 
-   hw_verts = render->allocate_vertices(render,
-                                       (ushort)translate->key.output_stride,
-                                       (ushort)count);
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   if (!render->allocate_vertices(render,
+                                  (ushort)translate->key.output_stride,
+                                  (ushort)count))
+      goto fail;
+
+   hw_verts = render->map_vertices( render );
+   if (!hw_verts)
+      goto fail;
 
    translate->set_buffer(translate, 0,
                         vertex_data, stride);
@@ -261,12 +259,12 @@ void draw_pt_emit_linear(struct pt_emit *emit,
 
    translate->run(translate,
                   0,
-                  vertex_count,
+                  count,
                   hw_verts);
 
    if (0) {
       unsigned i;
-      for (i = 0; i < vertex_count; i++) {
+      for (i = 0; i < count; i++) {
          debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
          draw_dump_emitted_vertex( emit->vinfo, 
                                    (const uint8_t *)hw_verts + 
@@ -274,13 +272,17 @@ void draw_pt_emit_linear(struct pt_emit *emit,
       }
    }
 
+   render->unmap_vertices( render, 0, count );
+
+   render->draw_arrays(render, 0, count);
+
+   render->release_vertices(render);
 
-   render->draw_arrays(render, start, count);
+   return;
 
-   render->release_vertices(render,
-                           hw_verts,
-                           translate->key.output_stride,
-                           vertex_count);
+fail:
+   assert(0);
+   return;
 }
 
 struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
index dcb7744b177fa8316bc18afea768c2c7f21e4c18..c71228a71cc970b0840c6a4fbfe17302f519f479 100644 (file)
@@ -234,9 +234,11 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
       return;
    }
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)fetch_count );
+   draw->render->allocate_vertices( draw->render,
+                                    (ushort)feme->translate->key.output_stride,
+                                    (ushort)fetch_count );
+
+   hw_verts = draw->render->map_vertices( draw->render );
    if (!hw_verts) {
       assert(0);
       return;
@@ -259,6 +261,10 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 
+                                 0, 
+                                 (ushort)fetch_count );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
@@ -268,10 +274,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
 
    /* Done -- that was easy, wasn't it: 
     */
-   draw->render->release_vertices( draw->render, 
-                                   hw_verts, 
-                                   feme->translate->key.output_stride, 
-                                   fetch_count );
+   draw->render->release_vertices( draw->render );
 
 }
 
@@ -288,18 +291,17 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (count >= UNDEFINED_VERTEX_ID) {
-      assert(0);
-      return;
-   }
+   if (count >= UNDEFINED_VERTEX_ID) 
+      goto fail;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)count );
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)feme->translate->key.output_stride,
+                                         (ushort)count )) 
+      goto fail;
+
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts) 
+      goto fail;
 
    /* Single routine to fetch vertices and emit HW verts.
     */
@@ -317,20 +319,21 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 0, count );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
-   draw->render->draw_arrays( draw->render,
-                              0, /*start*/
-                              count );
+   draw->render->draw_arrays( draw->render, 0, count );
 
    /* Done -- that was easy, wasn't it:
     */
-   draw->render->release_vertices( draw->render,
-                                   hw_verts,
-                                   feme->translate->key.output_stride,
-                                   count );
+   draw->render->release_vertices( draw->render );
+   return;
 
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -351,9 +354,12 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
    if (count >= UNDEFINED_VERTEX_ID)
       return FALSE;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)count );
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)feme->translate->key.output_stride,
+                                         (ushort)count ))
+      return FALSE;
+
+   hw_verts = draw->render->map_vertices( draw->render );
    if (!hw_verts) 
       return FALSE;
 
@@ -364,6 +370,8 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
                          count,
                          hw_verts );
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort)count );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
@@ -373,10 +381,7 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
 
    /* Done -- that was easy, wasn't it:
     */
-   draw->render->release_vertices( draw->render,
-                                   hw_verts,
-                                   feme->translate->key.output_stride,
-                                   count );
+   draw->render->release_vertices( draw->render );
 
    return TRUE;
 }
index 84ffe3296af3e31577430f8afb679ac1dfed321c..183ce1a833d883394b5da849c3c5e566d67bd4a8 100644 (file)
@@ -234,19 +234,17 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (count >= UNDEFINED_VERTEX_ID) {
-      assert(0);
-      return;
-   }
+   if (count >= UNDEFINED_VERTEX_ID) 
+      goto fail;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)count );
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)count ))
+      goto fail;
 
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts)
+      goto fail;
 
    /* Single routine to fetch vertices, run shader and emit HW verts.
     * Clipping is done elsewhere -- either by the API or on hardware,
@@ -256,13 +254,7 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
                             start, count,
                             hw_verts );
 
-   /* Draw arrays path to avoid re-emitting index list again and
-    * again.
-    */
-   draw->render->draw_arrays( draw->render,
-                              0,
-                              count );
-   
+
    if (0) {
       unsigned i;
       for (i = 0; i < count; i++) {
@@ -274,12 +266,24 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
                                    (const uint8_t *)hw_verts + fse->key.output_stride * i );
       }
    }
+   
+   draw->render->unmap_vertices( draw->render, 0, (ushort)count );
 
+   /* Draw arrays path to avoid re-emitting index list again and
+    * again.
+    */
+   draw->render->draw_arrays( draw->render,
+                              0,
+                              count );
+   
+
+   draw->render->release_vertices( draw->render );
+
+   return;
 
-   draw->render->release_vertices( draw->render, 
-                                  hw_verts, 
-                                  fse->key.output_stride, 
-                                  count );
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -298,18 +302,17 @@ fse_run(struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (fetch_count >= UNDEFINED_VERTEX_ID) {
-      assert(0);
-      return;
-   }
+   if (fetch_count >= UNDEFINED_VERTEX_ID) 
+      goto fail;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)fetch_count );
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)fetch_count ))
+      goto fail;
+
+   hw_verts = draw->render->map_vertices( draw->render ); 
+   if (!hw_verts) 
+      goto fail;
          
                                        
    /* Single routine to fetch vertices, run shader and emit HW verts.
@@ -319,9 +322,6 @@ fse_run(struct draw_pt_middle_end *middle,
                           fetch_count,
                           hw_verts );
 
-   draw->render->draw( draw->render, 
-                       draw_elts, 
-                       draw_count );
 
    if (0) {
       unsigned i;
@@ -333,12 +333,19 @@ fse_run(struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort)fetch_count );
+   
+   draw->render->draw( draw->render, 
+                       draw_elts, 
+                       draw_count );
+
 
-   draw->render->release_vertices( draw->render, 
-                                   hw_verts, 
-                                   fse->key.output_stride, 
-                                   fetch_count );
+   draw->render->release_vertices( draw->render );
+   return;
 
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -360,13 +367,14 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,
    if (count >= UNDEFINED_VERTEX_ID)
       return FALSE;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)count );
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)count ))
+      return FALSE;
 
-   if (!hw_verts) {
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts) 
       return FALSE;
-   }
 
    /* Single routine to fetch vertices, run shader and emit HW verts.
     * Clipping is done elsewhere -- either by the API or on hardware,
@@ -382,11 +390,9 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,
                        draw_count );
    
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort) count );
 
-   draw->render->release_vertices( draw->render, 
-                                  hw_verts, 
-                                  fse->key.output_stride, 
-                                  count );
+   draw->render->release_vertices( draw->render );
 
    return TRUE;
 }
index ec3b41c320a1b7b6e06bb643b5088ce035e56b8e..38f9b604d37d6e9c47b2c69298f856b8b1ee9c84 100644 (file)
@@ -251,9 +251,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
    else {
       draw_pt_emit_linear( fpme->emit,
                            (const float (*)[4])pipeline_verts->data,
-                           count,
                            fpme->vertex_size,
-                           0, /*start*/
                            count );
    }
 
index a1c4c14445b44267c4494130d492b1948619b020..cccd3bf4358d4ac5e97c21cfd1daf80829a0ebb5 100644 (file)
@@ -80,9 +80,14 @@ struct vbuf_render {
     * Hardware renderers will use ttm memory, others will just malloc
     * something.
     */
-   void *(*allocate_vertices)( struct vbuf_render *,
-                              ushort vertex_size,
-                              ushort nr_vertices );
+   boolean (*allocate_vertices)( struct vbuf_render *,
+                                 ushort vertex_size,
+                                 ushort nr_vertices );
+   
+   void *(*map_vertices)( struct vbuf_render * );
+   void (*unmap_vertices)( struct vbuf_render *, 
+                           ushort min_index,
+                           ushort max_index );
 
    /**
     * Notify the renderer of the current primitive when it changes.
@@ -109,10 +114,7 @@ struct vbuf_render {
    /**
     * Called when vbuf is done with this set of vertices:
     */
-   void (*release_vertices)( struct vbuf_render *,
-                            void *vertices, 
-                            unsigned vertex_size,
-                            unsigned vertices_used );
+   void (*release_vertices)( struct vbuf_render * );
 
    void (*destroy)( struct vbuf_render * );
 };