diff options
Diffstat (limited to 'src/mesa/pipe/draw')
-rw-r--r-- | src/mesa/pipe/draw/draw_private.h | 4 | ||||
-rw-r--r-- | src/mesa/pipe/draw/draw_vb.c | 454 |
2 files changed, 14 insertions, 444 deletions
diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 76ca80dab07..c1ebd341216 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -157,6 +157,8 @@ struct draw_context GLuint nr_vertices; GLboolean in_vb; + /** Pointer to vertex element/index buffer */ + unsigned eltSize; /**< bytes per index (0, 1, 2 or 4) */ void *elts; struct vertex_header *(*get_vertex)( struct draw_context *draw, @@ -197,6 +199,8 @@ struct draw_context GLenum prim; /**< GL_POINTS, GL_LINE_STRIP, GL_QUADS, etc */ unsigned reduced_prim; + void (*vs_flush)( struct draw_context *draw ); + /* Helper for tnl: */ GLvector4f header; diff --git a/src/mesa/pipe/draw/draw_vb.c b/src/mesa/pipe/draw/draw_vb.c index 23a5e3fc3b2..a88babc44e7 100644 --- a/src/mesa/pipe/draw/draw_vb.c +++ b/src/mesa/pipe/draw/draw_vb.c @@ -38,25 +38,7 @@ #include "draw_private.h" #include "draw_context.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 -}; +#include "draw_prim.h" @@ -105,364 +87,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, - GLuint 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, - GLuint 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 struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, - GLuint i ) -{ - const GLuint *elts = (const GLuint *)draw->elts; - return get_vertex( draw, elts[i] ); -} - -#if 0 -static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, - const void *elts, - GLuint i ) -{ - const GLushort *elts = (const GLushort *)draw->elts; - return get_vertex( draw, elts[i] ); -} - -static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, - const void *elts, - GLuint i ) -{ - const GLubyte *elts = (const GLubyte *)draw->elts; - return get_vertex( draw, elts[i] ); -} -#endif - - -static void draw_set_prim( struct draw_context *draw, - GLenum 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, - GLuint 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, - GLuint i0, - GLuint 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, - GLuint i0, - GLuint i1, - GLuint 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, - GLuint ef_mask, - GLuint i0, - GLuint i1, - GLuint 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, - GLuint start, - GLuint count ) -{ - GLuint i; - -// _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); - - switch (draw->prim) { - case GL_POINTS: - for (i = 0; i < count; i ++) { - do_point( draw, - start + i ); - } - break; - - case GL_LINES: - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); - } - break; - - case GL_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 GL_LINE_STRIP: - if (count >= 2) { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); - } - } - break; - - case GL_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 GL_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 GL_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 GL_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 GL_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 GL_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; - } -} - /** * Allocate storage for post-transformation vertices. @@ -554,66 +178,6 @@ build_vertex_headers( struct draw_context *draw, - - -static GLuint draw_prim_info(GLenum mode, GLuint *first, GLuint *incr) -{ - switch (mode) { - case GL_POINTS: - *first = 1; - *incr = 1; - return 0; - case GL_LINES: - *first = 2; - *incr = 2; - return 0; - case GL_LINE_STRIP: - *first = 2; - *incr = 1; - return 0; - case GL_LINE_LOOP: - *first = 2; - *incr = 1; - return 1; - case GL_TRIANGLES: - *first = 3; - *incr = 3; - return 0; - case GL_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return 0; - case GL_TRIANGLE_FAN: - case GL_POLYGON: - *first = 3; - *incr = 1; - return 1; - case GL_QUADS: - *first = 4; - *incr = 4; - return 0; - case GL_QUAD_STRIP: - *first = 4; - *incr = 2; - return 0; - default: - assert(0); - *first = 1; - *incr = 1; - return 0; - } -} - - -static GLuint trim( GLuint count, GLuint first, GLuint incr ) -{ - if (count < first) - return 0; - else - return count - (count - first) % incr; -} - - /** * This is a hack & will all go away. */ @@ -631,6 +195,8 @@ void draw_vb(struct draw_context *draw, */ build_vertex_headers( draw, VB ); + draw->vs_flush = vs_flush; + draw->in_vb = 1; /* tell drawing pipeline we're beginning drawing */ @@ -645,12 +211,10 @@ void draw_vb(struct draw_context *draw, vf_set_sources( draw->vf, VB->AttribPtr, 0 ); vf_emit_vertices( draw->vf, VB->Count, draw->verts ); - draw->elts = VB->Elts; - if (VB->Elts) - draw->get_vertex = get_uint_elt_vertex; + draw_set_element_buffer(draw, sizeof(GLuint), VB->Elts); else - draw->get_vertex = get_vertex; + draw_set_element_buffer(draw, 0, NULL); for (i = 0; i < VB->PrimitiveCount; i++) { const GLenum mode = VB->Primitive[i].mode; @@ -660,7 +224,7 @@ void draw_vb(struct draw_context *draw, /* Trim the primitive down to a legal size. */ draw_prim_info( mode, &first, &incr ); - length = trim( VB->Primitive[i].count, first, incr ); + length = draw_trim( VB->Primitive[i].count, first, incr ); if (!length) continue; @@ -700,12 +264,14 @@ draw_vertices(struct draw_context *draw, assert(mode <= GL_POLYGON); - draw->get_vertex = get_vertex; + draw->vs_flush = vs_flush; + draw->vertex_size = sizeof(struct vertex_header) + numAttrs * 4 * sizeof(GLfloat); - + /* no element/index buffer */ + draw_set_element_buffer(draw, 0, NULL); /*draw_prim_info(mode, &first, &incr);*/ draw_allocate_vertices( draw, numVerts ); |