diff options
author | Brian <[email protected]> | 2007-08-16 12:36:17 -0600 |
---|---|---|
committer | Brian <[email protected]> | 2007-08-16 12:37:26 -0600 |
commit | 59bd1e260bf40e4d2b1662cc4e68eff8235739e4 (patch) | |
tree | b8b094e8a20bac270c867a2f29e90321149f6c8c /src/mesa/pipe/softpipe | |
parent | 926323df8692f48134a65322d5790d3f950b67dd (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.c | 465 |
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 */ } |