summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/draw')
-rw-r--r--src/mesa/pipe/draw/draw_private.h4
-rw-r--r--src/mesa/pipe/draw/draw_vb.c454
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 );