summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2007-09-26 11:56:17 +0100
committerKeith Whitwell <keith@tungstengraphics.com>2007-09-27 07:56:23 +0100
commit08589f71051e588b0bb7d0c8b529976c85398dd1 (patch)
tree294a567114f73cd51fc92e6553230a76867905ad /src/mesa
parent7770acf8d4360ecfcaeece6e366f5adc6c0c9dee (diff)
Make flushing more lazy in the draw module.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/pipe/draw/draw_arrays.c76
-rw-r--r--src/mesa/pipe/draw/draw_clip.c4
-rw-r--r--src/mesa/pipe/draw/draw_context.c118
-rw-r--r--src/mesa/pipe/draw/draw_context.h24
-rw-r--r--src/mesa/pipe/draw/draw_debug.c115
-rw-r--r--src/mesa/pipe/draw/draw_feedback.c2
-rw-r--r--src/mesa/pipe/draw/draw_prim.c172
-rw-r--r--src/mesa/pipe/draw/draw_prim.h5
-rw-r--r--src/mesa/pipe/draw/draw_private.h23
-rw-r--r--src/mesa/pipe/draw/draw_validate.c124
-rw-r--r--src/mesa/pipe/draw/draw_vertex_cache.c17
-rw-r--r--src/mesa/pipe/draw/draw_vertex_fetch.c2
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader.c5
-rw-r--r--src/mesa/pipe/softpipe/sp_draw_arrays.c17
-rw-r--r--src/mesa/pipe/softpipe/sp_prim_setup.c2
-rw-r--r--src/mesa/sources3
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 \