summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/softpipe
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-08-16 12:36:17 -0600
committerBrian <[email protected]>2007-08-16 12:37:26 -0600
commit59bd1e260bf40e4d2b1662cc4e68eff8235739e4 (patch)
treeb8b094e8a20bac270c867a2f29e90321149f6c8c /src/mesa/pipe/softpipe
parent926323df8692f48134a65322d5790d3f950b67dd (diff)
Drawing code refactoring.
Move code duplicated between draw_vb.c and sp_draw_arrays.c into draw_prim.c draw_vb.c will eventually go away, but this seems like a good step anyway.
Diffstat (limited to 'src/mesa/pipe/softpipe')
-rw-r--r--src/mesa/pipe/softpipe/sp_draw_arrays.c465
1 files changed, 24 insertions, 441 deletions
diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c
index 43a53f108ca..fbe2064bac8 100644
--- a/src/mesa/pipe/softpipe/sp_draw_arrays.c
+++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c
@@ -31,7 +31,6 @@
*/
-#include "main/mtypes.h"
#include "main/context.h"
#include "pipe/p_defines.h"
@@ -43,28 +42,10 @@
#include "pipe/draw/draw_private.h"
#include "pipe/draw/draw_context.h"
+#include "pipe/draw/draw_prim.h"
-#define RP_NONE 0
-#define RP_POINT 1
-#define RP_LINE 2
-#define RP_TRI 3
-
-static unsigned reduced_prim[GL_POLYGON + 1] = {
- RP_POINT,
- RP_LINE,
- RP_LINE,
- RP_LINE,
- RP_TRI,
- RP_TRI,
- RP_TRI,
- RP_TRI,
- RP_TRI,
- RP_TRI
-};
-
-
/**
* Stand-in for actual vertex program execution
* XXX this will probably live in a new file, like "sp_vs.c"
@@ -79,19 +60,20 @@ run_vertex_program(struct draw_context *draw,
struct vertex_header *vOut)
{
const float *vIn, *cIn;
- const GLfloat *scale = draw->viewport.scale;
- const GLfloat *trans = draw->viewport.translate;
+ const float *scale = draw->viewport.scale;
+ const float *trans = draw->viewport.translate;
const void *mapped = vbuffer;
+ /* XXX temporary hack: */
GET_CURRENT_CONTEXT(ctx);
- const GLfloat *m = ctx->_ModelProjectMatrix.m;
+ const float *m = ctx->_ModelProjectMatrix.m;
- vIn = (const float *) ((const GLubyte *) mapped
+ vIn = (const float *) ((const ubyte *) mapped
+ draw->vertex_buffer[0].buffer_offset
+ draw->vertex_element[0].src_offset
+ elem * draw->vertex_buffer[0].pitch);
- cIn = (const float *) ((const GLubyte *) mapped
+ cIn = (const float *) ((const ubyte *) mapped
+ draw->vertex_buffer[3].buffer_offset
+ draw->vertex_element[3].src_offset
+ elem * draw->vertex_buffer[3].pitch);
@@ -131,6 +113,10 @@ run_vertex_program(struct draw_context *draw,
}
+/**
+ * Called by the draw module when the vertx cache needs to be flushed.
+ * This involves running the vertex shader.
+ */
static void vs_flush( struct draw_context *draw )
{
unsigned i;
@@ -166,400 +152,6 @@ static void vs_flush( struct draw_context *draw )
}
-static void draw_flush( struct draw_context *draw )
-{
- struct draw_stage *first = draw->pipeline.first;
- unsigned i;
-
- /* Make sure all vertices are available:
- */
- vs_flush( draw );
-
-
- switch (draw->reduced_prim) {
- case RP_TRI:
- for (i = 0; i < draw->pq.queue_nr; i++) {
- if (draw->pq.queue[i].reset_line_stipple)
- first->reset_stipple_counter( first );
-
- first->tri( first, &draw->pq.queue[i] );
- }
- break;
- case RP_LINE:
- for (i = 0; i < draw->pq.queue_nr; i++) {
- if (draw->pq.queue[i].reset_line_stipple)
- first->reset_stipple_counter( first );
-
- first->line( first, &draw->pq.queue[i] );
- }
- break;
- case RP_POINT:
- first->reset_stipple_counter( first );
- for (i = 0; i < draw->pq.queue_nr; i++)
- first->point( first, &draw->pq.queue[i] );
- break;
- }
-
- draw->pq.queue_nr = 0;
- draw->vcache.referenced = 0;
- draw->vcache.overflow = 0;
-}
-
-
-static void draw_invalidate_vcache( struct draw_context *draw )
-{
- unsigned i;
-
- assert(draw->pq.queue_nr == 0);
- assert(draw->vs.queue_nr == 0);
- assert(draw->vcache.referenced == 0);
-
- for (i = 0; i < Elements( draw->vcache.idx ); i++)
- draw->vcache.idx[i] = ~0;
-}
-
-
-/* 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
- * vertices. Flush primitive and/or vertex queues if necessary to
- * make space.
- */
-static struct prim_header *
-get_queued_prim( struct draw_context *draw, unsigned nr_verts )
-{
- if (draw->pq.queue_nr + 1 >= PRIM_QUEUE_LENGTH ||
- draw->vcache.overflow + nr_verts >= VCACHE_OVERFLOW)
- draw_flush( draw );
-
- /* The vs queue is sized so that this can never happen:
- */
- assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH);
-
- return &draw->pq.queue[draw->pq.queue_nr++];
-}
-
-
-/* Check if vertex is in cache, otherwise add it. It won't go through
- * VS yet, not until there is a flush operation or the VS queue fills up.
- */
-static struct vertex_header *
-get_vertex( struct draw_context *draw, unsigned i )
-{
- unsigned slot = (i + (i>>5)) & 31;
-
- /* Cache miss?
- */
- if (draw->vcache.idx[slot] != i) {
-
- /* If slot is in use, use the overflow area:
- */
- if (draw->vcache.referenced & (1<<slot))
- slot = draw->vcache.overflow++;
-
- draw->vcache.idx[slot] = i;
-
- /* Add to vertex shader queue:
- */
- draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot];
- draw->vs.queue[draw->vs.queue_nr].elt = i;
- draw->vs.queue_nr++;
- }
-
- /* Mark slot as in-use:
- */
- draw->vcache.referenced |= (1<<slot);
- return draw->vcache.vertex[slot];
-}
-
-
-
-static void
-draw_set_prim( struct draw_context *draw, unsigned prim )
-{
- if (reduced_prim[prim] != draw->reduced_prim) {
- draw_flush( draw );
- draw->reduced_prim = reduced_prim[prim];
- }
-
- draw->prim = prim;
-}
-
-
-static void do_point( struct draw_context *draw,
- unsigned i0 )
-{
- struct prim_header *prim = get_queued_prim( draw, 1 );
-
- prim->reset_line_stipple = 0;
- prim->edgeflags = 1;
- prim->pad = 0;
- prim->v[0] = draw->get_vertex( draw, i0 );
-}
-
-
-static void do_line( struct draw_context *draw,
- GLboolean reset_stipple,
- unsigned i0,
- unsigned i1 )
-{
- struct prim_header *prim = get_queued_prim( draw, 2 );
-
- 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 );
-}
-
-static void do_triangle( struct draw_context *draw,
- unsigned i0,
- unsigned i1,
- unsigned i2 )
-{
- struct prim_header *prim = get_queued_prim( draw, 3 );
-
- 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 );
-}
-
-static void do_ef_triangle( struct draw_context *draw,
- GLboolean reset_stipple,
- unsigned ef_mask,
- unsigned i0,
- unsigned i1,
- 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 );
-
- prim->reset_line_stipple = reset_stipple;
-
- prim->edgeflags = ef_mask & ((v0->edgeflag << 0) |
- (v1->edgeflag << 1) |
- (v2->edgeflag << 2));
- prim->pad = 0;
- prim->v[0] = v0;
- prim->v[1] = v1;
- prim->v[2] = v2;
-}
-
-
-static void do_quad( struct draw_context *draw,
- unsigned v0,
- unsigned v1,
- unsigned v2,
- unsigned v3 )
-{
- do_ef_triangle( draw, 1, ~(1<<0), v0, v1, v3 );
- do_ef_triangle( draw, 0, ~(1<<1), v1, v2, v3 );
-}
-
-
-static void draw_prim( struct draw_context *draw,
- unsigned start,
- unsigned count )
-{
- unsigned i;
-
-// _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
-
- switch (draw->prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i ++) {
- do_point( draw,
- start + i );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- do_line( draw,
- TRUE,
- start + i + 0,
- start + i + 1);
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
- for (i = 1; i < count; i++) {
- do_line( draw,
- i == 1, /* XXX: only if vb not split */
- start + i - 1,
- start + i );
- }
-
- do_line( draw,
- 0,
- start + count - 1,
- start + 0 );
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- if (count >= 2) {
- for (i = 1; i < count; i++) {
- do_line( draw,
- i == 1,
- start + i - 1,
- start + i );
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- do_ef_triangle( draw,
- 1,
- ~0,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- do_triangle( draw,
- start + i + 1,
- start + i + 0,
- start + i + 2 );
- }
- else {
- do_triangle( draw,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- for (i = 0; i+2 < count; i++) {
- do_triangle( draw,
- start + 0,
- start + i + 1,
- start + i + 2 );
- }
- }
- break;
-
-
- case PIPE_PRIM_QUADS:
- for (i = 0; i+3 < count; i += 4) {
- do_quad( draw,
- start + i + 0,
- start + i + 1,
- start + i + 2,
- start + i + 3);
- }
- break;
-
- case PIPE_PRIM_QUAD_STRIP:
- for (i = 0; i+3 < count; i += 2) {
- do_quad( draw,
- start + i + 2,
- start + i + 0,
- start + i + 1,
- start + i + 3);
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- if (count >= 3) {
- unsigned ef_mask = (1<<2) | (1<<0);
-
- for (i = 0; i+2 < count; i++) {
-
- if (i + 3 >= count)
- ef_mask |= (1<<1);
-
- do_ef_triangle( draw,
- i == 0,
- ef_mask,
- start + i + 1,
- start + i + 2,
- start + i + 0);
-
- ef_mask &= ~(1<<2);
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-}
-
-
-
-static unsigned draw_prim_info(unsigned mode, unsigned *first, unsigned *incr)
-{
- switch (mode) {
- 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;
- }
-}
-
-
-static unsigned trim( unsigned count, unsigned first, unsigned incr )
-{
- if (count < first)
- return 0;
- else
- return count - (count - first) % incr;
-}
-
-
void
softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
@@ -582,15 +174,11 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
/* tell drawing pipeline we're beginning drawing */
draw->pipeline.first->begin( draw->pipeline.first );
- draw_invalidate_vcache( draw );
+ draw->vs_flush = vs_flush;
-#if 0
- if (VB->Elts)
- draw->get_vertex = get_uint_elt_vertex;
- else
-#endif
- draw->get_vertex = get_vertex;
+ draw_invalidate_vcache( draw );
+ draw_set_element_buffer(draw, 0, NULL); /* no index/element buffer */
draw_set_prim( draw, mode );
/* XXX draw_prim_info() and TRIM here */
@@ -602,12 +190,9 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
/* tell drawing pipeline we're done drawing */
draw->pipeline.first->end( draw->pipeline.first );
-#if 0
- draw->verts = NULL;
- draw->in_vb = 0;
- draw->elts = NULL;
-#endif
-
+ /*
+ * unmap vertex buffer
+ */
pipe->winsys->buffer_unmap(pipe->winsys, buf);
softpipe_unmap_surfaces(sp);
@@ -626,9 +211,13 @@ do { \
} while (0)
-void draw_set_vertex_attributes2( struct draw_context *draw,
- const unsigned *slot_to_vf_attr,
- unsigned nr_attrs )
+/**
+ * XXX very similar to same func in draw_vb.c (which will go away)
+ */
+void
+draw_set_vertex_attributes2( struct draw_context *draw,
+ const unsigned *slot_to_vf_attr,
+ unsigned nr_attrs )
{
unsigned i;
@@ -651,12 +240,6 @@ void draw_set_vertex_attributes2( struct draw_context *draw,
for (i = 1; i < nr_attrs; i++)
EMIT_ATTR(slot_to_vf_attr[i], EMIT_4F, 4);
-#if 0
- /* tell the vertex format module how to construct vertices for us */
- draw->vertex_size = vf_set_vertex_attributes( draw->vf, draw->attrs,
- draw->nr_attrs, 0 );
-#endif
-
draw->vertex_size *= 4; /* floats to bytes */
}