gallium: replace prim pipeline begin/end() functions with flush()
authorBrian <brian.paul@tungstengraphics.com>
Fri, 25 Jan 2008 22:59:27 +0000 (15:59 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Sat, 26 Jan 2008 00:22:56 +0000 (17:22 -0700)
This is basically half of Keith's draw/flush patch.

The stage->point/line/tri() functions are now self-validating, the validator
functions are installed by the flush() function.

There were excessive calls to validate_pipeline(), however.  This was caused
by draw_prim_queue_flush() keeping a local 'first' variable that always pointed
to the validate functions.  Replaced 'first' with 'draw->pipeline.first'.

Performance in gears is up just slightly with this patch.

19 files changed:
src/mesa/pipe/cell/ppu/cell_draw_arrays.c
src/mesa/pipe/draw/draw_clip.c
src/mesa/pipe/draw/draw_cull.c
src/mesa/pipe/draw/draw_flatshade.c
src/mesa/pipe/draw/draw_offset.c
src/mesa/pipe/draw/draw_prim.c
src/mesa/pipe/draw/draw_private.h
src/mesa/pipe/draw/draw_stipple.c
src/mesa/pipe/draw/draw_twoside.c
src/mesa/pipe/draw/draw_unfilled.c
src/mesa/pipe/draw/draw_validate.c
src/mesa/pipe/draw/draw_vbuf.c
src/mesa/pipe/draw/draw_wide_prims.c
src/mesa/pipe/i915simple/i915_prim_emit.c
src/mesa/pipe/softpipe/sp_draw_arrays.c
src/mesa/pipe/softpipe/sp_prim_setup.c
src/mesa/pipe/softpipe/sp_prim_vbuf.c
src/mesa/state_tracker/st_cb_feedback.c
src/mesa/state_tracker/st_cb_rasterpos.c

index 8286da7..9c41b4a 100644 (file)
@@ -143,21 +143,18 @@ cell_draw_elements(struct pipe_context *pipe,
    /* draw! */
    draw_arrays(draw, mode, start, count);
 
-   /* always flush for now */
-   draw_flush(draw);
-
    /*
-    * unmap vertex/index buffers
+    * unmap vertex/index buffers - will cause draw module to flush
     */
    for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
       if (sp->vertex_buffer[i].buffer) {
-         pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
          draw_set_mapped_vertex_buffer(draw, i, NULL);
+         pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
       }
    }
    if (indexBuffer) {
-      pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
       draw_set_mapped_element_buffer(draw, 0, NULL);
+      pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
    }
 
    /* Note: leave drawing surfaces mapped */
index e0eb656..2d410e3 100644 (file)
@@ -346,15 +346,6 @@ do_clip_line( struct draw_stage *stage,
 }
 
 
-static void clip_begin( struct draw_stage *stage )
-{
-   /* should always have position, at least */
-   assert(stage->draw->num_vs_outputs > 0);
-
-   stage->next->begin( stage->next );
-}
-
-
 static void
 clip_point( struct draw_stage *stage, 
            struct prim_header *header )
@@ -402,10 +393,9 @@ clip_tri( struct draw_stage *stage,
    }
 }
 
-
-static void clip_end( struct draw_stage *stage )
+static void clip_flush( struct draw_stage *stage, unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -433,11 +423,10 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )
    draw_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES );
 
    clipper->stage.draw = draw;
-   clipper->stage.begin = clip_begin;
    clipper->stage.point = clip_point;
    clipper->stage.line = clip_line;
    clipper->stage.tri = clip_tri;
-   clipper->stage.end = clip_end;
+   clipper->stage.flush = clip_flush;
    clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
    clipper->stage.destroy = clip_destroy;
 
index 9bd53f4..05c274e 100644 (file)
@@ -50,14 +50,6 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
 }
 
 
-static void cull_begin( struct draw_stage *stage )
-{
-   struct cull_stage *cull = cull_stage(stage);
-
-   cull->winding = stage->draw->rasterizer->cull_mode;
-
-   stage->next->begin( stage->next );
-}
 
 
 static void cull_tri( struct draw_stage *stage,
@@ -90,6 +82,18 @@ static void cull_tri( struct draw_stage *stage,
    }
 }
 
+static void cull_first_tri( struct draw_stage *stage, 
+                           struct prim_header *header )
+{
+   struct cull_stage *cull = cull_stage(stage);
+
+   cull->winding = stage->draw->rasterizer->cull_mode;
+
+   stage->tri = cull_tri;
+   stage->tri( stage, header );
+}
+
+
 
 static void cull_line( struct draw_stage *stage,
                       struct prim_header *header )
@@ -105,12 +109,12 @@ static void cull_point( struct draw_stage *stage,
 }
 
 
-static void cull_end( struct draw_stage *stage )
+static void cull_flush( struct draw_stage *stage, unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->tri = cull_first_tri;
+   stage->next->flush( stage->next, flags );
 }
 
-
 static void cull_reset_stipple_counter( struct draw_stage *stage )
 {
    stage->next->reset_stipple_counter( stage->next );
@@ -135,11 +139,10 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
 
    cull->stage.draw = draw;
    cull->stage.next = NULL;
-   cull->stage.begin = cull_begin;
    cull->stage.point = cull_point;
    cull->stage.line = cull_line;
-   cull->stage.tri = cull_tri;
-   cull->stage.end = cull_end;
+   cull->stage.tri = cull_first_tri;
+   cull->stage.flush = cull_flush;
    cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
    cull->stage.destroy = cull_destroy;
 
index 8444c53..1419f28 100644 (file)
@@ -50,25 +50,6 @@ flat_stage(struct draw_stage *stage)
 }
 
 
-static void flatshade_begin( struct draw_stage *stage )
-{
-   struct flat_stage *flat = flat_stage(stage);
-   const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
-   uint i;
-
-   /* Find which vertex shader outputs are colors, make a list */
-   flat->num_color_attribs = 0;
-   for (i = 0; i < vs->num_outputs; i++) {
-      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
-          vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         flat->color_attribs[flat->num_color_attribs++] = i;
-      }
-   }
-
-   stage->next->begin( stage->next );
-}
-
-
 /** Copy all the color attributes from 'src' vertex to 'dst' vertex */
 static INLINE void copy_colors( struct draw_stage *stage,
                                 struct vertex_header *dst,
@@ -144,9 +125,46 @@ static void flatshade_point( struct draw_stage *stage,
 }
 
 
-static void flatshade_end( struct draw_stage *stage )
+static void flatshade_init_state( struct draw_stage *stage )
+{
+   struct flat_stage *flat = flat_stage(stage);
+   const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
+   uint i;
+
+   /* Find which vertex shader outputs are colors, make a list */
+   flat->num_color_attribs = 0;
+   for (i = 0; i < vs->num_outputs; i++) {
+      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+          vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         flat->color_attribs[flat->num_color_attribs++] = i;
+      }
+   }
+
+   stage->line = flatshade_line;
+   stage->tri = flatshade_tri;
+}
+
+static void flatshade_first_tri( struct draw_stage *stage,
+                                struct prim_header *header )
+{
+   flatshade_init_state( stage );
+   stage->tri( stage, header );
+}
+
+static void flatshade_first_line( struct draw_stage *stage,
+                                 struct prim_header *header )
+{
+   flatshade_init_state( stage );
+   stage->line( stage, header );
+}
+
+
+static void flatshade_flush( struct draw_stage *stage, 
+                            unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->tri = flatshade_first_tri;
+   stage->line = flatshade_first_line;
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -174,11 +192,10 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
 
    flatshade->stage.draw = draw;
    flatshade->stage.next = NULL;
-   flatshade->stage.begin = flatshade_begin;
    flatshade->stage.point = flatshade_point;
-   flatshade->stage.line = flatshade_line;
-   flatshade->stage.tri = flatshade_tri;
-   flatshade->stage.end = flatshade_end;
+   flatshade->stage.line = flatshade_first_line;
+   flatshade->stage.tri = flatshade_first_tri;
+   flatshade->stage.flush = flatshade_flush;
    flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
    flatshade->stage.destroy = flatshade_destroy;
 
index f8a01db..a2990ee 100644 (file)
@@ -52,16 +52,7 @@ static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
 }
 
 
-static void offset_begin( struct draw_stage *stage )
-{
-   struct offset_stage *offset = offset_stage(stage);
-   float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
 
-   offset->units = stage->draw->rasterizer->offset_units * mrd;
-   offset->scale = stage->draw->rasterizer->offset_scale;
-
-   stage->next->begin( stage->next );
-}
 
 
 /**
@@ -124,24 +115,39 @@ static void offset_tri( struct draw_stage *stage,
 }
 
 
+static void offset_first_tri( struct draw_stage *stage, 
+                             struct prim_header *header )
+{
+   struct offset_stage *offset = offset_stage(stage);
+   float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
+
+   offset->units = stage->draw->rasterizer->offset_units * mrd;
+   offset->scale = stage->draw->rasterizer->offset_scale;
+
+   stage->tri = offset_tri;
+   stage->tri( stage, header );
+}
+
 
 static void offset_line( struct draw_stage *stage,
-                      struct prim_header *header )
+                        struct prim_header *header )
 {
    stage->next->line( stage->next, header );
 }
 
 
 static void offset_point( struct draw_stage *stage,
-                       struct prim_header *header )
+                         struct prim_header *header )
 {
    stage->next->point( stage->next, header );
 }
 
 
-static void offset_end( struct draw_stage *stage )
+static void offset_flush( struct draw_stage *stage,
+                         unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->tri = offset_first_tri;
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -169,11 +175,10 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw )
 
    offset->stage.draw = draw;
    offset->stage.next = NULL;
-   offset->stage.begin = offset_begin;
    offset->stage.point = offset_point;
    offset->stage.line = offset_line;
-   offset->stage.tri = offset_tri;
-   offset->stage.end = offset_end;
+   offset->stage.tri = offset_first_tri;
+   offset->stage.flush = offset_flush;
    offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
    offset->stage.destroy = offset_destroy;
 
index f8fc23b..5703f5f 100644 (file)
@@ -57,7 +57,7 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
 
 static void draw_prim_queue_flush( struct draw_context *draw )
 {
-   struct draw_stage *first = draw->pipeline.first;
+   //   struct draw_stage *first = draw->pipeline.first;
    unsigned i;
 
    if (0)
@@ -69,27 +69,31 @@ static void draw_prim_queue_flush( struct draw_context *draw )
    if (draw->vs.queue_nr)
       draw_vertex_shader_queue_flush(draw);
 
+   /* NOTE: we cannot save draw->pipeline->first in a local var because
+    * draw->pipeline->first is often changed by the first call to tri(),
+    * line(), etc.
+    */
    switch (draw->reduced_prim) {
    case RP_TRI:
       for (i = 0; i < draw->pq.queue_nr; i++) {
         if (draw->pq.queue[i].reset_line_stipple)
-           first->reset_stipple_counter( first );
+           draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
 
-        first->tri( first, &draw->pq.queue[i] );
+        draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] );
       }
       break;
    case RP_LINE:
       for (i = 0; i < draw->pq.queue_nr; i++) {
         if (draw->pq.queue[i].reset_line_stipple)
-           first->reset_stipple_counter( first );
+           draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
 
-        first->line( first, &draw->pq.queue[i] );
+        draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] );
       }
       break;
    case RP_POINT:
-      first->reset_stipple_counter( first );
+      draw->pipeline.first->reset_stipple_counter( draw->pipeline.first );
       for (i = 0; i < draw->pq.queue_nr; i++)
-        first->point( first, &draw->pq.queue[i] );
+        draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] );
       break;
    }
 
@@ -119,7 +123,7 @@ void draw_do_flush( struct draw_context *draw,
    if ((flush & DRAW_FLUSH_DRAW) && 
        draw->drawing)
    {
-      draw->pipeline.first->end( draw->pipeline.first );
+      draw->pipeline.first->flush( draw->pipeline.first, ~0 );
       draw->drawing = FALSE;
       draw->prim = ~0;
       draw->pipeline.first = draw->pipeline.validate;
@@ -415,9 +419,6 @@ draw_arrays(struct draw_context *draw, unsigned prim,
 {
    if (!draw->drawing) {
       draw->drawing = TRUE;
-
-      /* tell drawing pipeline we're beginning drawing */
-      draw->pipeline.first->begin( draw->pipeline.first );
    }
 
    if (draw->prim != prim) {
index 685ec4a..e393fa5 100644 (file)
@@ -101,8 +101,6 @@ struct draw_stage
    struct vertex_header **tmp;  /**< temp vert storage, such as for clipping */
    unsigned nr_tmps;
 
-   void (*begin)( struct draw_stage * );
-
    void (*point)( struct draw_stage *,
                  struct prim_header * );
 
@@ -112,7 +110,8 @@ struct draw_stage
    void (*tri)( struct draw_stage *,
                struct prim_header * );
 
-   void (*end)( struct draw_stage * );
+   void (*flush)( struct draw_stage *,
+                  unsigned flags );
 
    void (*reset_stipple_counter)( struct draw_stage * );
 
index 2a47eb7..9029101 100644 (file)
@@ -173,7 +173,8 @@ reset_stipple_counter(struct draw_stage *stage)
 
 
 static void
-stipple_begin(struct draw_stage *stage)
+stipple_first_line(struct draw_stage *stage, 
+                  struct prim_header *header)
 {
    struct stipple_stage *stipple = stipple_stage(stage);
    struct draw_context *draw = stage->draw;
@@ -181,14 +182,16 @@ stipple_begin(struct draw_stage *stage)
    stipple->pattern = draw->rasterizer->line_stipple_pattern;
    stipple->factor = draw->rasterizer->line_stipple_factor + 1;
 
-   stage->next->begin( stage->next );
+   stage->line = stipple_line;
+   stage->line( stage, header );
 }
 
 
 static void
-stipple_end(struct draw_stage *stage)
+stipple_flush(struct draw_stage *stage, unsigned flags)
 {
-   stage->next->end( stage->next );
+   stage->line = stipple_first_line;
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -224,12 +227,11 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw )
 
    stipple->stage.draw = draw;
    stipple->stage.next = NULL;
-   stipple->stage.begin = stipple_begin;
    stipple->stage.point = passthrough_point;
-   stipple->stage.line = stipple_line;
+   stipple->stage.line = stipple_first_line;
    stipple->stage.tri = passthrough_tri;
    stipple->stage.reset_stipple_counter = reset_stipple_counter;
-   stipple->stage.end = stipple_end;
+   stipple->stage.flush = stipple_flush;
    stipple->stage.destroy = stipple_destroy;
 
    return &stipple->stage;
index 75c51ec..ad2aaf1 100644 (file)
@@ -48,48 +48,6 @@ static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage )
 }
 
 
-static void twoside_begin( struct draw_stage *stage )
-{
-   struct twoside_stage *twoside = twoside_stage(stage);
-   const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
-   uint i;
-
-   twoside->attrib_front0 = 0;
-   twoside->attrib_front1 = 0;
-   twoside->attrib_back0 = 0;
-   twoside->attrib_back1 = 0;
-
-   /* Find which vertex shader outputs are front/back colors */
-   for (i = 0; i < vs->num_outputs; i++) {
-      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
-         if (vs->output_semantic_index[i] == 0)
-            twoside->attrib_front0 = i;
-         else
-            twoside->attrib_front1 = i;
-      }
-      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         if (vs->output_semantic_index[i] == 0)
-            twoside->attrib_back0 = i;
-         else
-            twoside->attrib_back1 = i;
-      }
-   }
-
-   if (!twoside->attrib_back0)
-      twoside->attrib_front0 = 0;
-
-   if (!twoside->attrib_back1)
-      twoside->attrib_front1 = 0;
-
-   /*
-    * We'll multiply the primitive's determinant by this sign to determine
-    * if the triangle is back-facing (negative).
-    * sign = -1 for CCW, +1 for CW
-    */
-   twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
-
-   stage->next->begin( stage->next );
-}
 
 
 /**
@@ -157,10 +115,56 @@ static void twoside_point( struct draw_stage *stage,
 }
 
 
-static void twoside_end( struct draw_stage *stage )
+static void twoside_first_tri( struct draw_stage *stage, 
+                              struct prim_header *header )
 {
-   /* pass-through */
-   stage->next->end( stage->next );
+   struct twoside_stage *twoside = twoside_stage(stage);
+   const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
+   uint i;
+
+   twoside->attrib_front0 = 0;
+   twoside->attrib_front1 = 0;
+   twoside->attrib_back0 = 0;
+   twoside->attrib_back1 = 0;
+
+   /* Find which vertex shader outputs are front/back colors */
+   for (i = 0; i < vs->num_outputs; i++) {
+      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
+         if (vs->output_semantic_index[i] == 0)
+            twoside->attrib_front0 = i;
+         else
+            twoside->attrib_front1 = i;
+      }
+      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         if (vs->output_semantic_index[i] == 0)
+            twoside->attrib_back0 = i;
+         else
+            twoside->attrib_back1 = i;
+      }
+   }
+
+   if (!twoside->attrib_back0)
+      twoside->attrib_front0 = 0;
+
+   if (!twoside->attrib_back1)
+      twoside->attrib_front1 = 0;
+
+   /*
+    * We'll multiply the primitive's determinant by this sign to determine
+    * if the triangle is back-facing (negative).
+    * sign = -1 for CCW, +1 for CW
+    */
+   twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
+
+   stage->tri = twoside_tri;
+   stage->tri( stage, header );
+}
+
+
+static void twoside_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->tri = twoside_first_tri;
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -188,11 +192,10 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw )
 
    twoside->stage.draw = draw;
    twoside->stage.next = NULL;
-   twoside->stage.begin = twoside_begin;
    twoside->stage.point = twoside_point;
    twoside->stage.line = twoside_line;
-   twoside->stage.tri = twoside_tri;
-   twoside->stage.end = twoside_end;
+   twoside->stage.tri = twoside_first_tri;
+   twoside->stage.flush = twoside_flush;
    twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
    twoside->stage.destroy = twoside_destroy;
 
index 786826b..364bda8 100644 (file)
@@ -55,15 +55,6 @@ static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage )
 }
 
 
-static void unfilled_begin( struct draw_stage *stage )
-{
-   struct unfilled_stage *unfilled = unfilled_stage(stage);
-
-   unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
-   unfilled->mode[1] = stage->draw->rasterizer->fill_cw;  /* back */
-
-   stage->next->begin( stage->next );
-}
 
 static void point( struct draw_stage *stage,
                   struct vertex_header *v0 )
@@ -142,6 +133,20 @@ static void unfilled_tri( struct draw_stage *stage,
    }   
 }
 
+
+static void unfilled_first_tri( struct draw_stage *stage, 
+                               struct prim_header *header )
+{
+   struct unfilled_stage *unfilled = unfilled_stage(stage);
+
+   unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
+   unfilled->mode[1] = stage->draw->rasterizer->fill_cw;  /* back */
+
+   stage->tri = unfilled_tri;
+   stage->tri( stage, header );
+}
+
+
 static void unfilled_line( struct draw_stage *stage,
                            struct prim_header *header )
 {
@@ -156,9 +161,10 @@ static void unfilled_point( struct draw_stage *stage,
 }
 
 
-static void unfilled_end( struct draw_stage *stage )
+static void unfilled_flush( struct draw_stage *stage,
+                           unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -187,11 +193,10 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
    unfilled->stage.draw = draw;
    unfilled->stage.next = NULL;
    unfilled->stage.tmp = NULL;
-   unfilled->stage.begin = unfilled_begin;
    unfilled->stage.point = unfilled_point;
    unfilled->stage.line = unfilled_line;
-   unfilled->stage.tri = unfilled_tri;
-   unfilled->stage.end = unfilled_end;
+   unfilled->stage.tri = unfilled_first_tri;
+   unfilled->stage.flush = unfilled_flush;
    unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
    unfilled->stage.destroy = unfilled_destroy;
 
index 3b1f517..a626fb1 100644 (file)
@@ -39,7 +39,7 @@
 /**
  * Rebuild the rendering pipeline.
  */
-static void validate_begin( struct draw_stage *stage )
+static struct draw_stage *validate_pipeline( struct draw_stage *stage )
 {
    struct draw_context *draw = stage->draw;
    struct draw_stage *next = draw->pipeline.rasterize;
@@ -106,7 +106,45 @@ static void validate_begin( struct draw_stage *stage )
    }
 
    draw->pipeline.first = next;
-   draw->pipeline.first->begin( draw->pipeline.first );
+   //BP draw->pipeline.first->begin( draw->pipeline.first );
+   return next;
+}
+
+
+static void validate_tri( struct draw_stage *stage, 
+                         struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->tri( pipeline, header );
+}
+
+static void validate_line( struct draw_stage *stage, 
+                          struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->line( pipeline, header );
+}
+
+static void validate_point( struct draw_stage *stage, 
+                           struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->point( pipeline, header );
+}
+
+static void validate_reset_stipple_counter( struct draw_stage *stage )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->reset_stipple_counter( pipeline );
+}
+
+static void validate_flush( struct draw_stage *stage, 
+                           unsigned flags )
+{
+   /* May need to pass a backend flush on to the rasterize stage.
+    */
+   if (stage->next)
+      stage->next->flush( stage->next, flags );
 }
 
 
@@ -124,13 +162,13 @@ struct draw_stage *draw_validate_stage( struct draw_context *draw )
    struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
 
    stage->draw = draw;
+
    stage->next = NULL;
-   stage->begin = validate_begin;
-   stage->point = NULL;
-   stage->line = NULL;
-   stage->tri = NULL;
-   stage->end = NULL;
-   stage->reset_stipple_counter = NULL;
+   stage->point = validate_point;
+   stage->line = validate_line;
+   stage->tri = validate_tri;
+   stage->flush = validate_flush;
+   stage->reset_stipple_counter = validate_reset_stipple_counter;
    stage->destroy = validate_destroy;
 
    return stage;
index 82051d2..d827f51 100644 (file)
@@ -395,7 +395,7 @@ vbuf_begin( struct draw_stage *stage )
 
 
 static void 
-vbuf_end( struct draw_stage *stage )
+vbuf_flush( struct draw_stage *stage, unsigned flags )
 {
 //   vbuf_flush_indices( stage );
    /* XXX: Overkill */
@@ -432,11 +432,10 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
    struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
 
    vbuf->stage.draw = draw;
-   vbuf->stage.begin = vbuf_begin;
    vbuf->stage.point = vbuf_first_point;
    vbuf->stage.line = vbuf_first_line;
    vbuf->stage.tri = vbuf_first_tri;
-   vbuf->stage.end = vbuf_end;
+   vbuf->stage.flush = vbuf_flush;
    vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
    vbuf->stage.destroy = vbuf_destroy;
    
index f71a38e..26f5d10 100644 (file)
@@ -262,26 +262,19 @@ static void wide_point( struct draw_stage *stage,
 }
 
 
-static void wide_begin( struct draw_stage *stage )
+static void wide_first_point( struct draw_stage *stage, 
+                             struct prim_header *header )
 {
    struct wide_stage *wide = wide_stage(stage);
    struct draw_context *draw = stage->draw;
 
    wide->half_point_size = 0.5f * draw->rasterizer->point_size;
-   wide->half_line_width = 0.5f * draw->rasterizer->line_width;
-
-   if (draw->rasterizer->line_width != 1.0) {
-      wide->stage.line = wide_line;
-   }
-   else {
-      wide->stage.line = passthrough_line;
-   }
 
    if (draw->rasterizer->point_size != 1.0) {
-      wide->stage.point = wide_point;
+      stage->point = wide_point;
    }
    else {
-      wide->stage.point = passthrough_point;
+      stage->point = passthrough_point;
    }
 
    if (draw->rasterizer->point_sprite) {
@@ -299,6 +292,7 @@ static void wide_begin( struct draw_stage *stage )
    }
 
    wide->psize_slot = -1;
+
    if (draw->rasterizer->point_size_per_vertex) {
       /* find PSIZ vertex output */
       const struct draw_vertex_shader *vs = draw->vertex_shader;
@@ -311,13 +305,35 @@ static void wide_begin( struct draw_stage *stage )
       }
    }
    
-   stage->next->begin( stage->next );
+   stage->point( stage, header );
+}
+
+
+
+static void wide_first_line( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   struct wide_stage *wide = wide_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   wide->half_line_width = 0.5f * draw->rasterizer->line_width;
+
+   if (draw->rasterizer->line_width != 1.0) {
+      wide->stage.line = wide_line;
+   }
+   else {
+      wide->stage.line = passthrough_line;
+   }
+   
+   stage->line( stage, header );
 }
 
 
-static void wide_end( struct draw_stage *stage )
+static void wide_flush( struct draw_stage *stage, unsigned flags )
 {
-   stage->next->end( stage->next );
+   stage->line = wide_first_line;
+   stage->point = wide_first_point;
+   stage->next->flush( stage->next, flags );
 }
 
 
@@ -342,11 +358,10 @@ struct draw_stage *draw_wide_stage( struct draw_context *draw )
 
    wide->stage.draw = draw;
    wide->stage.next = NULL;
-   wide->stage.begin = wide_begin;
-   wide->stage.point = wide_point;
-   wide->stage.line = wide_line;
+   wide->stage.point = wide_first_point;
+   wide->stage.line = wide_first_line;
    wide->stage.tri = passthrough_tri;
-   wide->stage.end = wide_end;
+   wide->stage.flush = wide_flush;
    wide->stage.reset_stipple_counter = draw_reset_stipple_counter;
    wide->stage.destroy = wide_destroy;
 
index f74671b..c4a706c 100644 (file)
@@ -180,13 +180,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
 }
 
 
-
-static void setup_begin( struct draw_stage *stage )
-{
-}
-
-
-static void setup_end( struct draw_stage *stage )
+static void setup_flush( struct draw_stage *stage, unsigned flags )
 {
 }
 
@@ -210,11 +204,10 @@ struct draw_stage *i915_draw_render_stage( struct i915_context *i915 )
 
    setup->i915 = i915;
    setup->stage.draw = i915->draw;
-   setup->stage.begin = setup_begin;
    setup->stage.point = setup_point;
    setup->stage.line = setup_line;
    setup->stage.tri = setup_tri;
-   setup->stage.end = setup_end;
+   setup->stage.flush = setup_flush;
    setup->stage.reset_stipple_counter = reset_stipple_counter;
    setup->stage.destroy = render_destroy;
 
index 423c91d..71a303a 100644 (file)
@@ -142,21 +142,18 @@ softpipe_draw_elements(struct pipe_context *pipe,
    /* draw! */
    draw_arrays(draw, mode, start, count);
 
-   /* always flush for now */
-   draw_flush(draw);
-
    /*
-    * unmap vertex/index buffers
+    * unmap vertex/index buffers - will cause draw module to flush
     */
    for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
       if (sp->vertex_buffer[i].buffer) {
-         pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
          draw_set_mapped_vertex_buffer(draw, i, NULL);
+         pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
       }
    }
    if (indexBuffer) {
-      pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
       draw_set_mapped_element_buffer(draw, 0, NULL);
+      pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
    }
 
 
index 478ecff..088d8a4 100644 (file)
@@ -1170,11 +1170,43 @@ static void setup_begin( struct draw_stage *stage )
    setup->quad.nr_attrs = fs->num_inputs;
 
    sp->quad.first->begin(sp->quad.first);
+
+   stage->point = setup_point;
+   stage->line = setup_line;
+   stage->tri = setup_tri;
 }
 
 
-static void setup_end( struct draw_stage *stage )
+static void setup_first_point( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   setup_begin(stage);
+   stage->point( stage, header );
+}
+
+static void setup_first_line( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   setup_begin(stage);
+   stage->line( stage, header );
+}
+
+
+static void setup_first_tri( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   setup_begin(stage);
+   stage->tri( stage, header );
+}
+
+
+
+static void setup_flush( struct draw_stage *stage,
+                        unsigned flags )
 {
+   stage->point = setup_first_point;
+   stage->line = setup_first_line;
+   stage->tri = setup_first_tri;
 }
 
 
@@ -1198,11 +1230,10 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
 
    setup->softpipe = softpipe;
    setup->stage.draw = softpipe->draw;
-   setup->stage.begin = setup_begin;
-   setup->stage.point = setup_point;
-   setup->stage.line = setup_line;
-   setup->stage.tri = setup_tri;
-   setup->stage.end = setup_end;
+   setup->stage.point = setup_first_point;
+   setup->stage.line = setup_first_line;
+   setup->stage.tri = setup_first_tri;
+   setup->stage.flush = setup_flush;
    setup->stage.reset_stipple_counter = reset_stipple_counter;
    setup->stage.destroy = render_destroy;
 
index dfabae8..c9089e7 100644 (file)
@@ -149,8 +149,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
    prim.edgeflags = 0;
    prim.pad = 0;
 
-   setup->begin( setup );
-
    switch (cvbr->prim) {
    case PIPE_PRIM_TRIANGLES:
       for (i = 0; i < nr_indices; i += 3) {
@@ -182,7 +180,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices)
       break;
    }
 
-   setup->end( setup );
+   setup->flush( setup, 0 );
 }
 
 
index 43543df..3174415 100644 (file)
@@ -159,14 +159,7 @@ feedback_point( struct draw_stage *stage, struct prim_header *prim )
 
 
 static void
-feedback_end( struct draw_stage *stage )
-{
-   /* no-op */
-}
-
-
-static void
-feedback_begin( struct draw_stage *stage )
+feedback_flush( struct draw_stage *stage, unsigned flags )
 {
    /* no-op */
 }
@@ -190,11 +183,10 @@ draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
 
    fs->stage.draw = draw;
    fs->stage.next = NULL;
-   fs->stage.begin = feedback_begin;
    fs->stage.point = feedback_point;
    fs->stage.line = feedback_line;
    fs->stage.tri = feedback_tri;
-   fs->stage.end = feedback_end;
+   fs->stage.flush = feedback_flush;
    fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
    fs->ctx = ctx;
 
@@ -234,14 +226,7 @@ select_point( struct draw_stage *stage, struct prim_header *prim )
 
 
 static void
-select_begin( struct draw_stage *stage )
-{
-   /* no-op */
-}
-
-
-static void
-select_end( struct draw_stage *stage )
+select_flush( struct draw_stage *stage, unsigned flags )
 {
    /* no-op */
 }
@@ -264,11 +249,10 @@ draw_glselect_stage(GLcontext *ctx, struct draw_context *draw)
 
    fs->stage.draw = draw;
    fs->stage.next = NULL;
-   fs->stage.begin = select_begin;
    fs->stage.point = select_point;
    fs->stage.line = select_line;
    fs->stage.tri = select_tri;
-   fs->stage.end = select_end;
+   fs->stage.flush = select_flush;
    fs->stage.reset_stipple_counter = select_reset_stipple_counter;
    fs->ctx = ctx;
 
index 9e20e94..7e347c4 100644 (file)
@@ -73,13 +73,7 @@ rastpos_stage( struct draw_stage *stage )
 }
 
 static void
-rastpos_begin( struct draw_stage *stage )
-{
-   /* no-op */
-}
-
-static void
-rastpos_end( struct draw_stage *stage )
+rastpos_flush( struct draw_stage *stage, unsigned flags )
 {
    /* no-op */
 }
@@ -183,11 +177,10 @@ new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw)
 
    rs->stage.draw = draw;
    rs->stage.next = NULL;
-   rs->stage.begin = rastpos_begin;
    rs->stage.point = rastpos_point;
    rs->stage.line = rastpos_line;
    rs->stage.tri = rastpos_tri;
-   rs->stage.end = rastpos_end;
+   rs->stage.flush = rastpos_flush;
    rs->stage.destroy = rastpos_destroy;
    rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
    rs->stage.destroy = rastpos_destroy;