diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/pipe/draw/draw_arrays.c | 76 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_clip.c | 4 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_context.c | 118 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_context.h | 24 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_debug.c | 115 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_feedback.c | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_prim.c | 172 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_prim.h | 5 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_private.h | 23 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_validate.c | 124 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_vertex_cache.c | 17 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_vertex_fetch.c | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_vertex_shader.c | 5 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_draw_arrays.c | 17 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_setup.c | 2 | ||||
| -rw-r--r-- | src/mesa/sources | 3 | 
16 files changed, 430 insertions, 279 deletions
| diff --git a/src/mesa/pipe/draw/draw_arrays.c b/src/mesa/pipe/draw/draw_arrays.c deleted file mode 100644 index bbb243c469..0000000000 --- a/src/mesa/pipe/draw/draw_arrays.c +++ /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 ); -} - - diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c index 3ccc408bc0..a505146047 100644 --- a/src/mesa/pipe/draw/draw_clip.c +++ b/src/mesa/pipe/draw/draw_clip.c @@ -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]; diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index 9acbc53742..66c66ff698 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -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); +   } +} + + diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 4eb59aab01..0ccf5f6046 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -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 index 0000000000..246e20fb30 --- /dev/null +++ b/src/mesa/pipe/draw/draw_debug.c @@ -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 )); +} + diff --git a/src/mesa/pipe/draw/draw_feedback.c b/src/mesa/pipe/draw/draw_feedback.c index ee54db0ad5..15fad4da80 100644 --- a/src/mesa/pipe/draw/draw_feedback.c +++ b/src/mesa/pipe/draw/draw_feedback.c @@ -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; diff --git a/src/mesa/pipe/draw/draw_prim.c b/src/mesa/pipe/draw/draw_prim.c index be2f987b9a..a497a350f7 100644 --- a/src/mesa/pipe/draw/draw_prim.c +++ b/src/mesa/pipe/draw/draw_prim.c @@ -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);  } + + diff --git a/src/mesa/pipe/draw/draw_prim.h b/src/mesa/pipe/draw/draw_prim.h index 4c55b02978..07cd3e2c9f 100644 --- a/src/mesa/pipe/draw/draw_prim.h +++ b/src/mesa/pipe/draw/draw_prim.h @@ -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 */ diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 04d38c4e0c..ebef5347ab 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -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 index 0000000000..7c5a9dceca --- /dev/null +++ b/src/mesa/pipe/draw/draw_validate.c @@ -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; +} diff --git a/src/mesa/pipe/draw/draw_vertex_cache.c b/src/mesa/pipe/draw/draw_vertex_cache.c index a226798123..1f4adedede 100644 --- a/src/mesa/pipe/draw/draw_vertex_cache.c +++ b/src/mesa/pipe/draw/draw_vertex_cache.c @@ -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); diff --git a/src/mesa/pipe/draw/draw_vertex_fetch.c b/src/mesa/pipe/draw/draw_vertex_fetch.c index 62e8d61be4..2b839d641e 100644 --- a/src/mesa/pipe/draw/draw_vertex_fetch.c +++ b/src/mesa/pipe/draw/draw_vertex_fetch.c @@ -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*/ diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c index fe4f124dd2..b9e4cc13cc 100644 --- a/src/mesa/pipe/draw/draw_vertex_shader.c +++ b/src/mesa/pipe/draw/draw_vertex_shader.c @@ -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) { diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index 7ea29a0a26..21c30b53f3 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -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      */ diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 2e27d00acf..621a44512c 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -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 diff --git a/src/mesa/sources b/src/mesa/sources index 985bd2dce6..069be2e01d 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -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 \ | 
