Make flushing more lazy in the draw module.
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 26 Sep 2007 10:56:17 +0000 (11:56 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 27 Sep 2007 06:56:23 +0000 (07:56 +0100)
16 files changed:
src/mesa/pipe/draw/draw_arrays.c [deleted file]
src/mesa/pipe/draw/draw_clip.c
src/mesa/pipe/draw/draw_context.c
src/mesa/pipe/draw/draw_context.h
src/mesa/pipe/draw/draw_debug.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_feedback.c
src/mesa/pipe/draw/draw_prim.c
src/mesa/pipe/draw/draw_prim.h
src/mesa/pipe/draw/draw_private.h
src/mesa/pipe/draw/draw_validate.c [new file with mode: 0644]
src/mesa/pipe/draw/draw_vertex_cache.c
src/mesa/pipe/draw/draw_vertex_fetch.c
src/mesa/pipe/draw/draw_vertex_shader.c
src/mesa/pipe/softpipe/sp_draw_arrays.c
src/mesa/pipe/softpipe/sp_prim_setup.c
src/mesa/sources

diff --git a/src/mesa/pipe/draw/draw_arrays.c b/src/mesa/pipe/draw/draw_arrays.c
deleted file mode 100644 (file)
index bbb243c..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Author:
- *    Brian Paul
- *    Keith Whitwell
- */
-
-
-#include "pipe/p_defines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_winsys.h"
-#include "pipe/p_util.h"
-
-#include "pipe/draw/draw_private.h"
-#include "pipe/draw/draw_context.h"
-#include "pipe/draw/draw_prim.h"
-
-
-/**
- * Draw vertex arrays
- * This is the main entrypoint into the drawing module.
- * \param prim  one of PIPE_PRIM_x
- * \param start  index of first vertex to draw
- * \param count  number of vertices to draw
- */
-void
-draw_arrays(struct draw_context *draw, unsigned prim,
-            unsigned start, unsigned count)
-{
-   /* tell drawing pipeline we're beginning drawing */
-   draw->pipeline.first->begin( draw->pipeline.first );
-
-   /* XXX: Shouldn't really be needed - cache should be invalidated
-    * after setting new vertex buffers, vertex elements, but not
-    * between draws.
-    */
-   draw_vertex_cache_invalidate( draw );
-
-   draw_set_prim( draw, prim );
-
-   /* drawing done here: */
-   draw_prim(draw, start, count);
-
-   /* draw any left-over buffered prims */
-   draw_flush(draw);
-
-   /* tell drawing pipeline we're done drawing */
-   draw->pipeline.first->end( draw->pipeline.first );
-}
-
-
index 3ccc408bc0b3e2ee50f8c0d4a0d747e3561326ea..a5051460479d1b027bf81aad433a9762721e74ff 100644 (file)
@@ -248,8 +248,6 @@ do_clip_tri( struct draw_stage *stage,
    inlist[1] = header->v[1];
    inlist[2] = header->v[2];
 
-   clipmask &= ~CLIP_CULL_BIT;
-
    while (clipmask && n >= 3) {
       const unsigned plane_idx = ffs(clipmask)-1;
       const float *plane = clipper->plane[plane_idx];
@@ -331,8 +329,6 @@ do_clip_line( struct draw_stage *stage,
    float t1 = 0.0F;
    struct prim_header newprim;
 
-   clipmask &= ~CLIP_CULL_BIT;
-
    while (clipmask) {
       const unsigned plane_idx = ffs(clipmask)-1;
       const float *plane = clipper->plane[plane_idx];
index 9acbc53742b357d1e3e70afcbb6c55651324855c..66c66ff698e86ba9bc405e4226ed5b8231191390 100644 (file)
@@ -49,6 +49,8 @@ struct draw_context *draw_create( void )
    draw->pipeline.flatshade = draw_flatshade_stage( draw );
    draw->pipeline.cull      = draw_cull_stage( draw );
    draw->pipeline.feedback  = draw_feedback_stage( draw );
+   draw->pipeline.validate  = draw_validate_stage( draw );
+   draw->pipeline.first     = draw->pipeline.validate;
 
    ASSIGN_4V( draw->plane[0], -1,  0,  0, 1 );
    ASSIGN_4V( draw->plane[1],  1,  0,  0, 1 );
@@ -73,6 +75,8 @@ struct draw_context *draw_create( void )
    draw->attrib_front1 = -1;
    draw->attrib_back1 = -1;
 
+   draw_vertex_cache_invalidate( draw );
+
    return draw;
 }
 
@@ -84,75 +88,19 @@ void draw_destroy( struct draw_context *draw )
 }
 
 
-/**
- * Rebuild the rendering pipeline.
- */
-static void validate_pipeline( struct draw_context *draw )
-{
-   struct draw_stage *next = draw->pipeline.rasterize;
-
-   /*
-    * NOTE: we build up the pipeline in end-to-start order.
-    *
-    * TODO: make the current primitive part of the state and build
-    * shorter pipelines for lines & points.
-    */
-
-   if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
-       draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
-      draw->pipeline.unfilled->next = next;
-      next = draw->pipeline.unfilled;
-   }
-        
-   if (draw->rasterizer->offset_cw ||
-       draw->rasterizer->offset_ccw) {
-      draw->pipeline.offset->next = next;
-      next = draw->pipeline.offset;
-   }
-
-   if (draw->rasterizer->light_twoside) {
-      draw->pipeline.twoside->next = next;
-      next = draw->pipeline.twoside;
-   }
-
-   /* Always run the cull stage as we calculate determinant there
-    * also.  Fix this..
-    */
-   {
-      draw->pipeline.cull->next = next;
-      next = draw->pipeline.cull;
-   }
-
-   /* Clip stage
-    */
-   {
-      draw->pipeline.clip->next = next;
-      next = draw->pipeline.clip;
-   }
-
-   /* Do software flatshading prior to clipping.  XXX: should only do
-    * this for clipped primitives, ie it is a part of the clip
-    * routine.
-    */
-   if (draw->rasterizer->flatshade) {
-      draw->pipeline.flatshade->next = next;
-      next = draw->pipeline.flatshade;
-   }
-
-   if (draw->feedback.enabled || draw->feedback.discard) {
-      draw->pipeline.feedback->next = next;
-      next = draw->pipeline.feedback;
-   }
 
-   draw->pipeline.first = next;
+void draw_flush( struct draw_context *draw )
+{
+   if (draw->drawing)
+      draw_do_flush( draw, DRAW_FLUSH_DRAW );
 }
 
 
 void draw_set_feedback_state( struct draw_context *draw,
                               const struct pipe_feedback_state *feedback )
 {
+   draw_flush( draw );
    draw->feedback = *feedback;
-   validate_pipeline( draw );
 }
 
 
@@ -163,8 +111,8 @@ void draw_set_feedback_state( struct draw_context *draw,
 void draw_set_rasterizer_state( struct draw_context *draw,
                                 const struct pipe_rasterizer_state *raster )
 {
+   draw_flush( draw );
    draw->rasterizer = raster;
-   validate_pipeline( draw );
 }
 
 
@@ -175,6 +123,7 @@ void draw_set_rasterizer_state( struct draw_context *draw,
 void draw_set_rasterize_stage( struct draw_context *draw,
                                struct draw_stage *stage )
 {
+   draw_flush( draw );
    draw->pipeline.rasterize = stage;
 }
 
@@ -185,6 +134,8 @@ void draw_set_rasterize_stage( struct draw_context *draw,
 void draw_set_clip_state( struct draw_context *draw,
                           const struct pipe_clip_state *clip )
 {
+   draw_flush( draw );
+
    assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
    memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
    draw->nr_planes = 6 + clip->nr;
@@ -199,6 +150,7 @@ void draw_set_clip_state( struct draw_context *draw,
 void draw_set_viewport_state( struct draw_context *draw,
                               const struct pipe_viewport_state *viewport )
 {
+   draw_flush( draw );
    draw->viewport = *viewport; /* struct copy */
 }
 
@@ -207,6 +159,7 @@ void
 draw_set_vertex_shader(struct draw_context *draw,
                        const struct pipe_shader_state *shader)
 {
+   draw_flush( draw );
    draw->vertex_shader = *shader;
 }
 
@@ -216,6 +169,8 @@ draw_set_vertex_buffer(struct draw_context *draw,
                        unsigned attr,
                        const struct pipe_vertex_buffer *buffer)
 {
+   draw_flush( draw );
+
    assert(attr < PIPE_ATTRIB_MAX);
    draw->vertex_buffer[attr] = *buffer;
 }
@@ -226,6 +181,8 @@ draw_set_vertex_element(struct draw_context *draw,
                         unsigned attr,
                         const struct pipe_vertex_element *element)
 {
+   draw_flush( draw );
+
    assert(attr < PIPE_ATTRIB_MAX);
    draw->vertex_element[attr] = *element;
 }
@@ -238,6 +195,8 @@ void
 draw_set_mapped_vertex_buffer(struct draw_context *draw,
                               unsigned attr, const void *buffer)
 {
+   draw_flush( draw );
+
    draw->mapped_vbuffer[attr] = buffer;
 }
 
@@ -246,6 +205,8 @@ void
 draw_set_mapped_constant_buffer(struct draw_context *draw,
                                 const void *buffer)
 {
+   draw_flush( draw );
+
    draw->mapped_constants = buffer;
 }
 
@@ -254,8 +215,41 @@ void
 draw_set_mapped_feedback_buffer(struct draw_context *draw, uint index,
                                 void *buffer, uint size)
 {
+   draw_flush( draw );
+
    assert(index < PIPE_MAX_FEEDBACK_ATTRIBS);
    draw->mapped_feedback_buffer[index] = buffer;
    draw->mapped_feedback_buffer_size[index] = size; /* in bytes */
 }
 
+
+
+
+
+/**
+ * Allocate space for temporary post-transform vertices, such as for clipping.
+ */
+void draw_alloc_tmps( struct draw_stage *stage, unsigned nr )
+{
+   stage->nr_tmps = nr;
+
+   if (nr) {
+      ubyte *store = (ubyte *) malloc(MAX_VERTEX_SIZE * nr);
+      unsigned i;
+
+      stage->tmp = (struct vertex_header **) malloc(sizeof(struct vertex_header *) * nr);
+      
+      for (i = 0; i < nr; i++)
+        stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE);
+   }
+}
+
+void draw_free_tmps( struct draw_stage *stage )
+{
+   if (stage->tmp) {
+      free(stage->tmp[0]);
+      free(stage->tmp);
+   }
+}
+
+
index 4eb59aab010ce1e80c5c777ed7e8df47ded460aa..0ccf5f60466563fe4287b12d7ca35d8311306046 100644 (file)
@@ -57,7 +57,6 @@ struct draw_stage;
 #define CLIP_BOTTOM_BIT  0x08
 #define CLIP_NEAR_BIT    0x10
 #define CLIP_FAR_BIT     0x20
-#define CLIP_CULL_BIT    (1 << (6 + PIPE_MAX_CLIP_PLANES)) /*unused? */
 /*@}*/
 
 /**
@@ -92,10 +91,6 @@ void draw_set_rasterizer_state( struct draw_context *draw,
 void draw_set_rasterize_stage( struct draw_context *draw,
                                struct draw_stage *stage );
 
-unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr );
-
-unsigned draw_trim( unsigned count, unsigned first, unsigned incr );
-
 
 void
 draw_set_vertex_shader(struct draw_context *draw,
@@ -125,9 +120,22 @@ void
 draw_set_mapped_feedback_buffer(struct draw_context *draw, uint index,
                                 void *buffer, uint size);
 
-void
-draw_arrays(struct draw_context *draw, unsigned prim,
-            unsigned start, unsigned count);
+
+/***********************************************************************
+ * draw_prim.c 
+ */
+
+void draw_arrays(struct draw_context *draw, unsigned prim,
+                unsigned start, unsigned count);
+
+void draw_flush(struct draw_context *draw);
+
+/***********************************************************************
+ * draw_debug.c 
+ */
+boolean draw_validate_prim( unsigned prim, unsigned length );
+unsigned draw_trim_prim( unsigned mode, unsigned count );
+
 
 
 #endif /* DRAW_CONTEXT_H */
diff --git a/src/mesa/pipe/draw/draw_debug.c b/src/mesa/pipe/draw/draw_debug.c
new file mode 100644 (file)
index 0000000..246e20f
--- /dev/null
@@ -0,0 +1,115 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "pipe/p_util.h"
+#include "draw_private.h"
+#include "draw_context.h"
+#include "draw_prim.h"
+
+
+
+static void
+draw_prim_info(unsigned prim, unsigned *first, unsigned *incr)
+{
+   assert(prim >= PIPE_PRIM_POINTS);
+   assert(prim <= PIPE_PRIM_POLYGON);
+
+   switch (prim) {
+   case PIPE_PRIM_POINTS:
+      *first = 1;
+      *incr = 1;
+      break;
+   case PIPE_PRIM_LINES:
+      *first = 2;
+      *incr = 2;
+      break;
+   case PIPE_PRIM_LINE_STRIP:
+      *first = 2;
+      *incr = 1;
+      break;
+   case PIPE_PRIM_LINE_LOOP:
+      *first = 2;
+      *incr = 1;
+      break;
+   case PIPE_PRIM_TRIANGLES:
+      *first = 3;
+      *incr = 3;
+      break;
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      *first = 3;
+      *incr = 1;
+      break;
+   case PIPE_PRIM_TRIANGLE_FAN:
+   case PIPE_PRIM_POLYGON:
+      *first = 3;
+      *incr = 1;
+      break;
+   case PIPE_PRIM_QUADS:
+      *first = 4;
+      *incr = 4;
+      break;
+   case PIPE_PRIM_QUAD_STRIP:
+      *first = 4;
+      *incr = 2;
+      break;
+   default:
+      assert(0);
+      *first = 1;
+      *incr = 1;
+      break;
+   }
+}
+
+
+unsigned 
+draw_trim_prim( unsigned mode, unsigned count )
+{
+   unsigned length, first, incr;
+
+   draw_prim_info( mode, &first, &incr );
+
+   if (count < first)
+      length = 0;
+   else
+      length = count - (count - first) % incr; 
+
+   return length;
+}
+
+
+boolean
+draw_validate_prim( unsigned mode, unsigned count )
+{
+   return (count > 0 &&
+           count == draw_trim_prim( mode, count ));
+}
+
index ee54db0ad5c1cd0121a48697a082b5f55352570b..15fad4da807b9a9b2c3073a7c10ac154c7118014 100644 (file)
@@ -69,6 +69,8 @@ static void
 feedback_vertex(struct draw_stage *stage, const struct vertex_header *vertex)
 {
    struct feedback_stage *fs = (struct feedback_stage *) stage;
+
+#if 0
    const struct pipe_feedback_state *feedback = &stage->draw->feedback;
    const uint select = feedback->interleaved ? 0 : 1;
    uint i;
index be2f987b9a0f9fb2dd2a3bab2703a64db385b160..a497a350f7db92e520ed0851f083a1cc59b38269 100644 (file)
@@ -58,14 +58,15 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
 };
 
 
-void draw_flush( struct draw_context *draw )
+static void draw_prim_queue_flush( struct draw_context *draw )
 {
    struct draw_stage *first = draw->pipeline.first;
    unsigned i;
 
    /* Make sure all vertices are available:
     */
-   draw_vertex_cache_validate(draw);
+   if (draw->vs.queue_nr)
+      draw_vertex_shader_queue_flush(draw);
 
    switch (draw->reduced_prim) {
    case RP_TRI:
@@ -91,12 +92,41 @@ void draw_flush( struct draw_context *draw )
       break;
    }
 
-   draw->pq.queue_nr = 0;
-
+   draw->pq.queue_nr = 0;   
    draw_vertex_cache_unreference( draw );
 }
 
 
+void draw_do_flush( struct draw_context *draw, 
+                    unsigned flush )
+{
+   if ((flush & (DRAW_FLUSH_PRIM_QUEUE |
+                 DRAW_FLUSH_VERTEX_CACHE_INVALIDATE |
+                 DRAW_FLUSH_DRAW)) && 
+        draw->pq.queue_nr)
+   {
+      draw_prim_queue_flush(draw);
+   }
+
+   if ((flush & (DRAW_FLUSH_VERTEX_CACHE_INVALIDATE |
+                 DRAW_FLUSH_DRAW)) && 
+       draw->drawing)
+   {
+      draw_vertex_cache_invalidate(draw);
+   }
+
+   if ((flush & DRAW_FLUSH_DRAW) && 
+       draw->drawing)
+   {
+      draw->pipeline.first->end( draw->pipeline.first );
+      draw->drawing = 0;
+      draw->prim = ~0;
+      draw->pipeline.first = draw->pipeline.validate;
+   }
+
+}
+
+
 
 /* Return a pointer to a freshly queued primitive header.  Ensure that
  * there is room in the vertex cache for a maximum of "nr_verts" new
@@ -106,13 +136,13 @@ void draw_flush( struct draw_context *draw )
 static struct prim_header *get_queued_prim( struct draw_context *draw,
                                            unsigned nr_verts )
 {
-   if (draw->pq.queue_nr + 1 >= PRIM_QUEUE_LENGTH) {
-//      fprintf(stderr, "p");
-      draw_flush( draw );
-   }
-   else if (!draw_vertex_cache_check_space( draw, nr_verts )) {
+   if (!draw_vertex_cache_check_space( draw, nr_verts )) {
 //      fprintf(stderr, "v");
-      draw_flush( draw );
+      draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE_INVALIDATE );
+   }
+   else if (draw->pq.queue_nr + 1 >= PRIM_QUEUE_LENGTH) {
+//      fprintf(stderr, "p");
+      draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE );
    }
 
    return &draw->pq.queue[draw->pq.queue_nr++];
@@ -129,7 +159,7 @@ static void do_point( struct draw_context *draw,
    prim->reset_line_stipple = 0;
    prim->edgeflags = 1;
    prim->pad = 0;
-   prim->v[0] = draw->get_vertex( draw, i0 );
+   prim->v[0] = draw->vcache.get_vertex( draw, i0 );
 }
 
 
@@ -143,8 +173,8 @@ static void do_line( struct draw_context *draw,
    prim->reset_line_stipple = reset_stipple;
    prim->edgeflags = 1;
    prim->pad = 0;
-   prim->v[0] = draw->get_vertex( draw, i0 );
-   prim->v[1] = draw->get_vertex( draw, i1 );
+   prim->v[0] = draw->vcache.get_vertex( draw, i0 );
+   prim->v[1] = draw->vcache.get_vertex( draw, i1 );
 }
 
 static void do_triangle( struct draw_context *draw,
@@ -157,9 +187,9 @@ static void do_triangle( struct draw_context *draw,
    prim->reset_line_stipple = 1;
    prim->edgeflags = ~0;
    prim->pad = 0;
-   prim->v[0] = draw->get_vertex( draw, i0 );
-   prim->v[1] = draw->get_vertex( draw, i1 );
-   prim->v[2] = draw->get_vertex( draw, i2 );
+   prim->v[0] = draw->vcache.get_vertex( draw, i0 );
+   prim->v[1] = draw->vcache.get_vertex( draw, i1 );
+   prim->v[2] = draw->vcache.get_vertex( draw, i2 );
 }
                          
 static void do_ef_triangle( struct draw_context *draw,
@@ -170,9 +200,9 @@ static void do_ef_triangle( struct draw_context *draw,
                            unsigned i2 )
 {
    struct prim_header *prim = get_queued_prim( draw, 3 );
-   struct vertex_header *v0 = draw->get_vertex( draw, i0 );
-   struct vertex_header *v1 = draw->get_vertex( draw, i1 );
-   struct vertex_header *v2 = draw->get_vertex( draw, i2 );
+   struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 );
+   struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 );
+   struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 );
 
    prim->reset_line_stipple = reset_stipple;
 
@@ -202,7 +232,7 @@ static void do_quad( struct draw_context *draw,
 /**
  * Main entrypoint to draw some number of points/lines/triangles
  */
-void
+static void
 draw_prim( struct draw_context *draw, unsigned start, unsigned count )
 {
    unsigned i;
@@ -341,14 +371,15 @@ draw_prim( struct draw_context *draw, unsigned start, unsigned count )
 }
 
 
-void
+static void
 draw_set_prim( struct draw_context *draw, unsigned prim )
 {
+   _mesa_printf("%s %d\n", __FUNCTION__, prim);
    assert(prim >= PIPE_PRIM_POINTS);
    assert(prim <= PIPE_PRIM_POLYGON);
 
    if (reduced_prim[prim] != draw->reduced_prim) {
-      draw_flush( draw );
+      draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE );
       draw->reduced_prim = reduced_prim[prim];
    }
 
@@ -356,91 +387,32 @@ draw_set_prim( struct draw_context *draw, unsigned prim )
 }
 
 
-unsigned
-draw_prim_info(unsigned prim, unsigned *first, unsigned *incr)
-{
-   assert(prim >= PIPE_PRIM_POINTS);
-   assert(prim <= PIPE_PRIM_POLYGON);
-
-   switch (prim) {
-   case PIPE_PRIM_POINTS:
-      *first = 1;
-      *incr = 1;
-      return 0;
-   case PIPE_PRIM_LINES:
-      *first = 2;
-      *incr = 2;
-      return 0;
-   case PIPE_PRIM_LINE_STRIP:
-      *first = 2;
-      *incr = 1;
-      return 0;
-   case PIPE_PRIM_LINE_LOOP:
-      *first = 2;
-      *incr = 1;
-      return 1;
-   case PIPE_PRIM_TRIANGLES:
-      *first = 3;
-      *incr = 3;
-      return 0;
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      *first = 3;
-      *incr = 1;
-      return 0;
-   case PIPE_PRIM_TRIANGLE_FAN:
-   case PIPE_PRIM_POLYGON:
-      *first = 3;
-      *incr = 1;
-      return 1;
-   case PIPE_PRIM_QUADS:
-      *first = 4;
-      *incr = 4;
-      return 0;
-   case PIPE_PRIM_QUAD_STRIP:
-      *first = 4;
-      *incr = 2;
-      return 0;
-   default:
-      assert(0);
-      *first = 1;
-      *incr = 1;
-      return 0;
-   }
-}
-
-
-unsigned
-draw_trim( unsigned count, unsigned first, unsigned incr )
-{
-   if (count < first)
-      return 0;
-   else
-      return count - (count - first) % incr; 
-}
 
 
 /**
- * Allocate space for temporary post-transform vertices, such as for clipping.
+ * Draw vertex arrays
+ * This is the main entrypoint into the drawing module.
+ * \param prim  one of PIPE_PRIM_x
+ * \param start  index of first vertex to draw
+ * \param count  number of vertices to draw
  */
-void draw_alloc_tmps( struct draw_stage *stage, unsigned nr )
+void
+draw_arrays(struct draw_context *draw, unsigned prim,
+            unsigned start, unsigned count)
 {
-   stage->nr_tmps = nr;
-
-   if (nr) {
-      ubyte *store = (ubyte *) malloc(MAX_VERTEX_SIZE * nr);
-      unsigned i;
+   if (!draw->drawing) {
+      draw->drawing = 1;
 
-      stage->tmp = (struct vertex_header **) malloc(sizeof(struct vertex_header *) * nr);
-      
-      for (i = 0; i < nr; i++)
-        stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE);
+      /* tell drawing pipeline we're beginning drawing */
+      draw->pipeline.first->begin( draw->pipeline.first );
    }
-}
 
-void draw_free_tmps( struct draw_stage *stage )
-{
-   if (stage->tmp) {
-      free(stage->tmp[0]);
-      free(stage->tmp);
+   if (draw->prim != prim) {
+      draw_set_prim( draw, prim );
    }
+
+   /* drawing done here: */
+   draw_prim(draw, start, count);
 }
+
+
index 4c55b029786c715b5b684cccbb94046f326a7619..07cd3e2c9f7f28f43808b907560e8aa514e549ad 100644 (file)
@@ -6,11 +6,6 @@
 
 void draw_invalidate_vcache( struct draw_context *draw );
 
-void draw_set_prim( struct draw_context *draw, unsigned prim );
-
-void draw_prim( struct draw_context *draw, unsigned start, unsigned count );
-
-void draw_flush( struct draw_context *draw );
 
 
 #endif /* DRAW_PRIM_H */
index 04d38c4e0c205030d6e31dfdfe8792f7e72446d9..ebef5347ab951660ae32d5880e009b2766e0b4e9 100644 (file)
@@ -126,6 +126,8 @@ struct draw_context
    struct {
       struct draw_stage *first;  /**< one of the following */
 
+      struct draw_stage *validate; 
+
       /* stages (in logical order) */
       struct draw_stage *feedback;
       struct draw_stage *flatshade;
@@ -171,13 +173,10 @@ struct draw_context
    uint attrib_front0, attrib_back0;
    uint attrib_front1, attrib_back1;
 
-   unsigned nr_vertices;
-
+   unsigned drawing;
    unsigned prim;   /**< current prim type: PIPE_PRIM_x */
    unsigned reduced_prim;
 
-   struct vertex_header *(*get_vertex)( struct draw_context *draw,
-                                       unsigned i );
 
    /* Post-tnl vertex cache:
     */
@@ -186,6 +185,9 @@ struct draw_context
       unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW];
       struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW];
       unsigned overflow;
+
+      struct vertex_header *(*get_vertex)( struct draw_context *draw,
+                                           unsigned i );
    } vcache;
 
    /* Vertex shader queue:
@@ -219,6 +221,7 @@ extern struct draw_stage *draw_offset_stage( struct draw_context *context );
 extern struct draw_stage *draw_clip_stage( struct draw_context *context );
 extern struct draw_stage *draw_flatshade_stage( struct draw_context *context );
 extern struct draw_stage *draw_cull_stage( struct draw_context *context );
+extern struct draw_stage *draw_validate_stage( struct draw_context *context );
 
 
 extern void draw_free_tmps( struct draw_stage *stage );
@@ -228,7 +231,6 @@ extern void draw_alloc_tmps( struct draw_stage *stage, unsigned nr );
 extern int draw_vertex_cache_check_space( struct draw_context *draw, 
                                          unsigned nr_verts );
 
-extern void draw_vertex_cache_validate( struct draw_context *draw );
 extern void draw_vertex_cache_invalidate( struct draw_context *draw );
 extern void draw_vertex_cache_unreference( struct draw_context *draw );
 extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw );
@@ -244,6 +246,17 @@ extern void draw_vertex_fetch( struct draw_context *draw,
                               unsigned count );
 
 
+#define DRAW_FLUSH_PRIM_QUEUE                0x1
+#define DRAW_FLUSH_VERTEX_CACHE_INVALIDATE   0x2
+#define DRAW_FLUSH_DRAW                      0x4
+
+
+void draw_do_flush( struct draw_context *draw,
+                    unsigned flags );
+
+
+
+
 /**
  * Get a writeable copy of a vertex.
  * \param stage  drawing stage info
diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c
new file mode 100644 (file)
index 0000000..7c5a9dc
--- /dev/null
@@ -0,0 +1,124 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+
+
+
+/**
+ * Rebuild the rendering pipeline.
+ */
+static void validate_begin( struct draw_stage *stage )
+{
+   struct draw_context *draw = stage->draw;
+   struct draw_stage *next = draw->pipeline.rasterize;
+
+   /*
+    * NOTE: we build up the pipeline in end-to-start order.
+    *
+    * TODO: make the current primitive part of the state and build
+    * shorter pipelines for lines & points.
+    */
+
+   if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+       draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
+      draw->pipeline.unfilled->next = next;
+      next = draw->pipeline.unfilled;
+   }
+        
+   if (draw->rasterizer->offset_cw ||
+       draw->rasterizer->offset_ccw) {
+      draw->pipeline.offset->next = next;
+      next = draw->pipeline.offset;
+   }
+
+   if (draw->rasterizer->light_twoside) {
+      draw->pipeline.twoside->next = next;
+      next = draw->pipeline.twoside;
+   }
+
+   /* Always run the cull stage as we calculate determinant there
+    * also.  Fix this..
+    */
+   {
+      draw->pipeline.cull->next = next;
+      next = draw->pipeline.cull;
+   }
+
+   /* Clip stage
+    */
+   {
+      draw->pipeline.clip->next = next;
+      next = draw->pipeline.clip;
+   }
+
+   /* Do software flatshading prior to clipping.  XXX: should only do
+    * this for clipped primitives, ie it is a part of the clip
+    * routine.
+    */
+   if (draw->rasterizer->flatshade) {
+      draw->pipeline.flatshade->next = next;
+      next = draw->pipeline.flatshade;
+   }
+
+   if (draw->feedback.enabled || draw->feedback.discard) {
+      draw->pipeline.feedback->next = next;
+      next = draw->pipeline.feedback;
+   }
+
+   draw->pipeline.first = next;
+   draw->pipeline.first->begin( draw->pipeline.first );
+}
+
+
+
+
+/**
+ * Create validate pipeline stage.
+ */
+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;
+
+   return stage;
+}
index a226798123c22dd515b24ad4b20d2e00aec67805..1f4adededeed3a11535071f40fd45845a78ddba0 100644 (file)
@@ -90,6 +90,9 @@ static struct vertex_header *get_vertex( struct draw_context *draw,
       draw->vcache.vertex[slot]->pad = 0;
       draw->vcache.vertex[slot]->vertex_id = ~0;
    }
+   else {
+//      fprintf(stderr, "*");
+   }
 
    return draw->vcache.vertex[slot];
 }
@@ -127,10 +130,6 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw )
       draw->vcache.vertex[i]->vertex_id = ~0;
 }
 
-void draw_vertex_cache_validate( struct draw_context *draw )
-{
-   draw_vertex_shader_queue_flush( draw );
-}
 
 void draw_vertex_cache_unreference( struct draw_context *draw )
 {
@@ -168,19 +167,21 @@ void
 draw_set_mapped_element_buffer( struct draw_context *draw,
                                 unsigned eltSize, void *elements )
 {
+//   draw_statechange( draw );
+
    /* choose the get_vertex() function to use */
    switch (eltSize) {
    case 0:
-      draw->get_vertex = get_vertex;
+      draw->vcache.get_vertex = get_vertex;
       break;
    case 1:
-      draw->get_vertex = get_ubyte_elt_vertex;
+      draw->vcache.get_vertex = get_ubyte_elt_vertex;
       break;
    case 2:
-      draw->get_vertex = get_ushort_elt_vertex;
+      draw->vcache.get_vertex = get_ushort_elt_vertex;
       break;
    case 4:
-      draw->get_vertex = get_uint_elt_vertex;
+      draw->vcache.get_vertex = get_uint_elt_vertex;
       break;
    default:
       assert(0);
index 62e8d61be4cd27a0e4fd34b596a6b8b2984b040b..2b839d641ebad787dc2be094be41e72ed4e12dde 100644 (file)
@@ -99,6 +99,8 @@ void draw_vertex_fetch( struct draw_context *draw,
 
          /*printf("  %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);*/
 
+         /* Transform to AoS xxxx/yyyy/zzzz/wwww representation:
+          */
          machine->Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/
          machine->Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/
          machine->Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/
index fe4f124dd2f0f3e59b914bb015a8faad05f1475d..b9e4cc13ccacb02aecae252c3e1ec12adb66acfd 100644 (file)
@@ -169,13 +169,12 @@ run_vertex_program(struct draw_context *draw,
          vOut[j]->data[slot][1] = machine.Outputs[slot].xyzw[1].f[j];
          vOut[j]->data[slot][2] = machine.Outputs[slot].xyzw[2].f[j];
          vOut[j]->data[slot][3] = machine.Outputs[slot].xyzw[3].f[j];
-         /*
+         
          printf("output %d: %f %f %f %f\n", slot,
                 vOut[j]->data[slot][0],
                 vOut[j]->data[slot][1],
                 vOut[j]->data[slot][2],
                 vOut[j]->data[slot][3]);
-         */
       }
    } /* loop over vertices */
 }
@@ -189,7 +188,7 @@ void draw_vertex_shader_queue_flush( struct draw_context *draw )
 {
    unsigned i, j;
 
-//   fprintf(stderr, " q(%d) ", draw->vs.queue_nr );
+   fprintf(stderr, " q(%d) ", draw->vs.queue_nr );
 
    /* run vertex shader on vertex cache entries, four per invokation */
    for (i = 0; i < draw->vs.queue_nr; i += 4) {
index 7ea29a0a2696989369d04baebfde98828176ba4d..21c30b53f3ab673b1e8ca76cc719e059031ce729 100644 (file)
@@ -95,14 +95,16 @@ softpipe_draw_elements(struct pipe_context *pipe,
 {
    struct softpipe_context *sp = softpipe_context(pipe);
    struct draw_context *draw = sp->draw;
-   unsigned length, first, incr, i;
+   unsigned i;
 
-   /* first, check that the primitive is not malformed */
-   draw_prim_info( mode, &first, &incr );
-   length = draw_trim( count, first, incr );
-   if (!length)
-      return TRUE;
+   /* first, check that the primitive is not malformed.  It is the
+    * state tracker's responsibility to do send only correctly formed
+    * primitives down.
+    */
+//   count = draw_trim_prim( mode, count );
 
+   if (!draw_validate_prim( mode, count ))
+      assert(0);
 
    if (sp->dirty)
       softpipe_update_derived( sp );
@@ -151,6 +153,9 @@ 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
     */
index 2e27d00acfb02c4fec960caa3fbe63a67e38fd09..621a44512c4811e890461d01254693b07516d0b2 100644 (file)
@@ -41,7 +41,7 @@
 #include "pipe/draw/draw_vertex.h"
 #include "pipe/p_util.h"
 
-#define DEBUG_VERTS 0
+#define DEBUG_VERTS 1
 
 /**
  * Triangle edge info
index 985bd2dce6f2f68c5d92e6a7b963728045b91932..069be2e01db9c3fa1dbe344547bdd4e4366e1115 100644 (file)
@@ -157,15 +157,16 @@ VF_SOURCES = \
 
 
 DRAW_SOURCES = \
-       pipe/draw/draw_arrays.c \
        pipe/draw/draw_clip.c \
        pipe/draw/draw_context.c\
        pipe/draw/draw_cull.c \
+       pipe/draw/draw_debug.c \
        pipe/draw/draw_feedback.c \
        pipe/draw/draw_flatshade.c \
        pipe/draw/draw_offset.c \
        pipe/draw/draw_prim.c \
        pipe/draw/draw_twoside.c \
+       pipe/draw/draw_validate.c \
        pipe/draw/draw_vertex.c \
        pipe/draw/draw_vertex_cache.c \
        pipe/draw/draw_vertex_fetch.c \