{
struct prim_header prim;
- prim.reset_line_stipple = 0;
- prim.edgeflags = 1;
+ prim.flags = 0;
prim.pad = 0;
prim.v[0] = (struct vertex_header *)v0;
static void do_line( struct draw_context *draw,
+ ushort flags,
const char *v0,
const char *v1 )
{
struct prim_header prim;
- prim.reset_line_stipple = 1; /* fixme */
- prim.edgeflags = 1;
+ prim.flags = flags;
prim.pad = 0;
prim.v[0] = (struct vertex_header *)v0;
prim.v[1] = (struct vertex_header *)v1;
static void do_triangle( struct draw_context *draw,
+ ushort flags,
char *v0,
char *v1,
char *v2 )
prim.v[0] = (struct vertex_header *)v0;
prim.v[1] = (struct vertex_header *)v1;
prim.v[2] = (struct vertex_header *)v2;
- prim.reset_line_stipple = 1;
- prim.edgeflags = ((prim.v[0]->edgeflag) |
- (prim.v[1]->edgeflag << 1) |
- (prim.v[2]->edgeflag << 2));
+ prim.flags = flags;
prim.pad = 0;
draw->pipeline.first->tri( draw->pipeline.first, &prim );
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2)
do_line( draw,
- verts + stride * elts[i+0],
+ elts[i+0],
+ verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
verts + stride * elts[i+1]);
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3)
do_triangle( draw,
- verts + stride * elts[i+0],
+ elts[i+0],
+ verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
verts + stride * elts[i+1],
verts + stride * elts[i+2]);
break;
#include "draw_private.h" /* for sizeof(vertex_header) */
+/**
+ * Basic info for a point/line/triangle primitive.
+ */
+struct prim_header {
+ float det; /**< front/back face determinant */
+ ushort flags;
+ ushort pad;
+ struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */
+};
+
+
/**
* Base class for all primitive drawing stages.
*/
{
dst->clipmask = 0;
- dst->edgeflag = 0;
+ dst->edgeflag = 0; /* will get overwritten later */
dst->pad = 0;
dst->vertex_id = UNDEFINED_VERTEX_ID;
}
struct prim_header header;
unsigned i;
+ const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
+ const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+ const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
+
/* later stages may need the determinant, but only the sign matters */
header.det = origPrim->det;
+ header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
+ header.pad = 0;
- for (i = 2; i < n; i++) {
+ for (i = 2; i < n; i++, header.flags = 0) {
header.v[0] = inlist[i-1];
header.v[1] = inlist[i];
header.v[2] = inlist[0]; /* keep in v[2] for flatshading */
-
- {
- unsigned tmp1 = header.v[1]->edgeflag;
- unsigned tmp2 = header.v[2]->edgeflag;
-
- if (i != n-1) header.v[1]->edgeflag = 0;
- if (i != 2) header.v[2]->edgeflag = 0;
-
- header.edgeflags = ((header.v[0]->edgeflag << 0) |
- (header.v[1]->edgeflag << 1) |
- (header.v[2]->edgeflag << 2));
-
- if (0) {
- const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
- uint j, k;
- debug_printf("Clipped tri:\n");
- for (j = 0; j < 3; j++) {
- for (k = 0; k < vs->info.num_outputs; k++) {
- debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k,
- header.v[j]->data[k][0],
- header.v[j]->data[k][1],
- header.v[j]->data[k][2],
- header.v[j]->data[k][3]);
- }
+
+ if (i == n-1)
+ header.flags |= edge_last;
+
+ if (0) {
+ const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+ uint j, k;
+ debug_printf("Clipped tri:\n");
+ for (j = 0; j < 3; j++) {
+ for (k = 0; k < vs->info.num_outputs; k++) {
+ debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k,
+ header.v[j]->data[k][0],
+ header.v[j]->data[k][1],
+ header.v[j]->data[k][2],
+ header.v[j]->data[k][3]);
}
}
-
- stage->next->tri( stage->next, &header );
-
- header.v[1]->edgeflag = tmp1;
- header.v[2]->edgeflag = tmp2;
}
+
+ stage->next->tri( stage->next, &header );
}
}
struct prim_header tmp;
tmp.det = header->det;
- tmp.edgeflags = header->edgeflags;
+ tmp.flags = header->flags;
+ tmp.pad = header->pad;
tmp.v[0] = header->v[0];
tmp.v[1] = dup_vert(stage, header->v[1], 0);
tmp.v[2] = dup_vert(stage, header->v[2], 1);
struct prim_header tmp;
tmp.det = header->det;
- tmp.edgeflags = header->edgeflags;
+ tmp.flags = header->flags;
+ tmp.pad = header->pad;
tmp.v[0] = dup_vert(stage, header->v[0], 0);
tmp.v[1] = dup_vert(stage, header->v[1], 1);
tmp.v[2] = header->v[2];
struct prim_header tmp;
tmp.det = header->det;
- tmp.edgeflags = header->edgeflags;
+ tmp.flags = header->flags;
+ tmp.pad = header->pad;
tmp.v[0] = dup_vert(stage, header->v[0], 0);
tmp.v[1] = dup_vert(stage, header->v[1], 1);
tmp.v[2] = dup_vert(stage, header->v[2], 2);
float length = MAX2(dx, dy);
int i;
+ if (header->flags & DRAW_PIPE_RESET_STIPPLE)
+ stipple->counter = 0;
+
+
/* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table.
*/
for (i = 0; i < length; i++) {
struct prim_header tmp;
tmp.det = header->det;
- tmp.edgeflags = header->edgeflags;
+ tmp.flags = header->flags;
+ tmp.pad = header->pad;
/* copy back attribs to front attribs */
tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
struct vertex_header *v1 = header->v[1];
struct vertex_header *v2 = header->v[2];
- if (header->edgeflags & 0x1) point( stage, v0 );
- if (header->edgeflags & 0x2) point( stage, v1 );
- if (header->edgeflags & 0x4) point( stage, v2 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) point( stage, v0 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) point( stage, v1 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) point( stage, v2 );
}
struct vertex_header *v1 = header->v[1];
struct vertex_header *v2 = header->v[2];
-#if 0
- assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag);
- assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag);
- assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag);
-#endif
+ if (header->flags & DRAW_PIPE_RESET_STIPPLE)
+ stage->next->reset_stipple_counter( stage->next );
- if (header->edgeflags & 0x4) line( stage, v2, v0 );
- if (header->edgeflags & 0x1) line( stage, v0, v1 );
- if (header->edgeflags & 0x2) line( stage, v1, v2 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) line( stage, v2, v0 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) line( stage, v0, v1 );
+ if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) line( stage, v1, v2 );
}
/* Unfilled tri:
*
* Note edgeflags in the vertex struct is not sufficient as we will
- * need to manipulate them when decomposing primitives???
+ * need to manipulate them when decomposing primitives.
+ *
+ * We currently keep the vertex edgeflag and primitive edgeflag mask
+ * separate until the last possible moment.
*/
static void unfilled_tri( struct draw_stage *stage,
struct prim_header *header )
#define UNDEFINED_VERTEX_ID 0xffff
-/**
- * Basic info for a point/line/triangle primitive.
- */
-struct prim_header {
- float det; /**< front/back face determinant */
- unsigned reset_line_stipple:1;
- unsigned edgeflags:3;
- unsigned pad:28;
- struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */
-};
-
-
-
-
-#define PT_SHADE 0x1
-#define PT_CLIPTEST 0x2
-#define PT_PIPELINE 0x4
-#define PT_MAX_MIDDLE 0x8
-
/**
* Private context for the drawing module.
*/
boolean draw_pipeline_init( struct draw_context *draw );
void draw_pipeline_destroy( struct draw_context *draw );
+
+
+
+
+/* We use the top few bits in the elts[] parameter to convey a little
+ * API information. This limits the number of vertices we can address
+ * to only 4096 -- if that becomes a problem, we can switch to 32-bit
+ * draw indices.
+ *
+ * These flags expected at first vertex of lines & triangles when
+ * unfilled and/or line stipple modes are operational.
+ */
+#define DRAW_PIPE_EDGE_FLAG_0 (0x1<<12)
+#define DRAW_PIPE_EDGE_FLAG_1 (0x2<<12)
+#define DRAW_PIPE_EDGE_FLAG_2 (0x4<<12)
+#define DRAW_PIPE_EDGE_FLAG_ALL (0x7<<12)
+#define DRAW_PIPE_RESET_STIPPLE (0x8<<12)
+#define DRAW_PIPE_FLAG_MASK (0xf<<12)
+
void draw_pipeline_run( struct draw_context *draw,
unsigned prim,
struct vertex_header *vertices,
const ushort *elts,
unsigned count );
+
+
void draw_pipeline_flush( struct draw_context *draw,
unsigned flags );
struct draw_pt_middle_end;
struct draw_context;
-/* We use the top couple of bits in the vertex fetch index to convey a
- * little API information. This limits the number of vertices we can
- * address to only 1 billion -- if that becomes a problem, these could
- * be moved out & passed separately.
- */
-#define DRAW_PT_EDGEFLAG (1<<30)
-#define DRAW_PT_RESET_STIPPLE (1<<31)
-#define DRAW_PT_FLAG_MASK (3<<30)
-
#define PT_SHADE 0x1
#define PT_CLIPTEST 0x2
struct translate *translate;
unsigned vertex_size;
+ boolean need_edgeflags;
struct translate_cache *cache;
};
0);
}
}
+
+ fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+ draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
+ draw->pt.user.edgeflag);
}
elts,
count,
verts );
+
+ /* Edgeflags are hard to fit into a translate program, populate
+ * them separately if required. In the setup above they are
+ * defaulted to one, so only need this if there is reason to change
+ * that default:
+ */
+ if (fetch->need_edgeflags) {
+ for (i = 0; i < count; i++) {
+ struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
+ vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
+ }
+ }
}
#include "pipe/p_util.h"
#include "draw/draw_context.h"
#include "draw/draw_private.h"
-//#include "draw/draw_vbuf.h"
-//#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
}
-static void vcache_elt( struct vcache_frontend *vcache,
- unsigned felt )
+static INLINE void vcache_elt( struct vcache_frontend *vcache,
+ unsigned felt,
+ ushort flags )
{
unsigned idx = felt % CACHE_MAX;
vcache->fetch_elts[vcache->fetch_count++] = felt;
}
- vcache->draw_elts[vcache->draw_count++] = vcache->out[idx];
+ vcache->draw_elts[vcache->draw_count++] = vcache->out[idx] | flags;
}
-static unsigned add_edgeflag( struct vcache_frontend *vcache,
- unsigned idx,
- unsigned mask )
-{
- if (0 && mask && draw_pt_get_edgeflag(vcache->draw, idx))
- return idx | DRAW_PT_EDGEFLAG;
- else
- return idx;
-}
-
-
-static unsigned add_reset_stipple( unsigned idx,
- unsigned reset )
-{
- if (0 && reset)
- return idx | DRAW_PT_RESET_STIPPLE;
- else
- return idx;
-}
static void vcache_triangle( struct vcache_frontend *vcache,
unsigned i1,
unsigned i2 )
{
- vcache_elt(vcache, i0 /* | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE */ );
- vcache_elt(vcache, i1 /* | DRAW_PT_EDGEFLAG */);
- vcache_elt(vcache, i2 /* | DRAW_PT_EDGEFLAG */);
+ vcache_elt(vcache, i0, 0);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, i2, 0);
vcache_check_flush(vcache);
}
-static void vcache_ef_triangle( struct vcache_frontend *vcache,
- boolean reset_stipple,
- unsigned ef_mask,
- unsigned i0,
- unsigned i1,
- unsigned i2 )
+static void vcache_triangle_flags( struct vcache_frontend *vcache,
+ ushort flags,
+ unsigned i0,
+ unsigned i1,
+ unsigned i2 )
{
-/*
- i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 );
- i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 );
- i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 );
- i0 = add_reset_stipple( i0, reset_stipple );
-*/
-
- vcache_elt(vcache, i0);
- vcache_elt(vcache, i1);
- vcache_elt(vcache, i2);
+ vcache_elt(vcache, i0, flags);
+ vcache_elt(vcache, i1, 0);
+ vcache_elt(vcache, i2, 0);
vcache_check_flush(vcache);
-
- if (0) debug_printf("emit tri ef: %d %d %d\n",
- !!(i0 & DRAW_PT_EDGEFLAG),
- !!(i1 & DRAW_PT_EDGEFLAG),
- !!(i2 & DRAW_PT_EDGEFLAG));
-
}
-
static void vcache_line( struct vcache_frontend *vcache,
- boolean reset_stipple,
unsigned i0,
unsigned i1 )
{
- i0 = add_reset_stipple( i0, reset_stipple );
+ vcache_elt(vcache, i0, 0);
+ vcache_elt(vcache, i1, 0);
+ vcache_check_flush(vcache);
+}
+
- vcache_elt(vcache, i0);
- vcache_elt(vcache, i1);
+static void vcache_line_flags( struct vcache_frontend *vcache,
+ ushort flags,
+ unsigned i0,
+ unsigned i1 )
+{
+ vcache_elt(vcache, i0, flags);
+ vcache_elt(vcache, i1, 0);
vcache_check_flush(vcache);
}
static void vcache_point( struct vcache_frontend *vcache,
unsigned i0 )
{
- vcache_elt(vcache, i0);
+ vcache_elt(vcache, i0, 0);
vcache_check_flush(vcache);
}
unsigned i2,
unsigned i3 )
{
- const unsigned omitEdge2 = ~(1 << 1);
- const unsigned omitEdge3 = ~(1 << 2);
- vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 );
- vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 );
-}
+ const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2;
+ const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1;
+ vcache_triangle_flags( vcache,
+ DRAW_PIPE_RESET_STIPPLE | omitEdge1,
+ i0, i1, i3 );
+ vcache_triangle_flags( vcache,
+ omitEdge2,
+ i1, i2, i3 );
+}
+/* At least for now, we're back to using a template include file for
+ * this. The two paths aren't too different though - it may be
+ * possible to reunify them.
+ */
+#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2)
+#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3)
+#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1)
+#define POINT(vc,i0) vcache_point(vc,i0)
+#define FUNC vcache_run_extras
+#include "draw_pt_vcache_tmp.h"
+
+#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2)
+#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3)
+#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1)
+#define POINT(vc,i0) vcache_point(vc,i0)
+#define FUNC vcache_run
+#include "draw_pt_vcache_tmp.h"
-static void vcache_run( struct draw_pt_front_end *frontend,
- pt_elt_func get_elt,
- const void *elts,
- unsigned count )
-{
- struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
- struct draw_context *draw = vcache->draw;
-
- boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
- draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL);
-
- boolean flatfirst = (draw->rasterizer->flatshade &&
- draw->rasterizer->flatshade_first);
- unsigned i;
-
-// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
-
- switch (vcache->input_prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i ++) {
- vcache_point( vcache,
- get_elt(elts, i + 0) );
- }
- break;
-
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- vcache_line( vcache,
- TRUE,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1));
- }
- break;
-
- case PIPE_PRIM_LINE_LOOP:
- if (count >= 2) {
- for (i = 1; i < count; i++) {
- vcache_line( vcache,
- i == 1, /* XXX: only if vb not split */
- get_elt(elts, i - 1),
- get_elt(elts, i ));
- }
-
- vcache_line( vcache,
- 0,
- get_elt(elts, count - 1),
- get_elt(elts, 0 ));
- }
- break;
-
- case PIPE_PRIM_LINE_STRIP:
- for (i = 1; i < count; i++) {
- vcache_line( vcache,
- i == 1,
- get_elt(elts, i - 1),
- get_elt(elts, i ));
- }
- break;
-
- case PIPE_PRIM_TRIANGLES:
- if (unfilled) {
- for (i = 0; i+2 < count; i += 3) {
- vcache_ef_triangle( vcache,
- 1,
- ~0,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2 ));
- }
- }
- else {
- for (i = 0; i+2 < count; i += 3) {
- vcache_triangle( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2 ));
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_STRIP:
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- vcache_triangle( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 2),
- get_elt(elts, i + 1 ));
- }
- else {
- vcache_triangle( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2 ));
- }
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- vcache_triangle( vcache,
- get_elt(elts, i + 1),
- get_elt(elts, i + 0),
- get_elt(elts, i + 2 ));
- }
- else {
- vcache_triangle( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2 ));
- }
- }
- }
- break;
-
- case PIPE_PRIM_TRIANGLE_FAN:
- if (count >= 3) {
- if (flatfirst) {
- for (i = 0; i+2 < count; i++) {
- vcache_triangle( vcache,
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, 0 ));
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- vcache_triangle( vcache,
- get_elt(elts, 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2 ));
- }
- }
- }
- break;
-
-
- case PIPE_PRIM_QUADS:
- if (unfilled) {
- for (i = 0; i+3 < count; i += 4) {
- vcache_ef_quad( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3));
- }
- }
- else {
- for (i = 0; i+3 < count; i += 4) {
- vcache_quad( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3));
- }
- }
- break;
-
- case PIPE_PRIM_QUAD_STRIP:
- if (unfilled) {
- for (i = 0; i+3 < count; i += 2) {
- vcache_ef_quad( vcache,
- get_elt(elts, i + 2),
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3));
- }
- }
- else {
- for (i = 0; i+3 < count; i += 2) {
- vcache_quad( vcache,
- get_elt(elts, i + 2),
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3));
- }
- }
- break;
-
- case PIPE_PRIM_POLYGON:
- if (unfilled) {
- /* These bitflags look a little odd because we submit the
- * vertices as (1,2,0) to satisfy flatshade requirements.
- */
- const unsigned edge_first = (1<<2);
- const unsigned edge_middle = (1<<0);
- const unsigned edge_last = (1<<1);
-
- for (i = 0; i+2 < count; i++) {
- unsigned ef_mask = edge_middle;
-
- if (i == 0)
- ef_mask |= edge_first;
-
- if (i + 3 == count)
- ef_mask |= edge_last;
-
- vcache_ef_triangle( vcache,
- i == 0,
- ef_mask,
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, 0));
- }
- }
- else {
- for (i = 0; i+2 < count; i++) {
- vcache_triangle( vcache,
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, 0));
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-
- vcache_flush( vcache );
-}
unsigned opt )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+ const struct pipe_rasterizer_state *rasterizer = vcache->draw->rasterizer;
+
-/*
- if (vcache->draw->rasterizer->flatshade_first)
- vcache->base.run = vcache_run_pv0;
- else
- vcache->base.run = vcache_run_pv2;
-*/
+ if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+ rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL ||
+ rasterizer->line_stipple_enable)
+ {
+ assert(opt & PT_PIPELINE);
+ vcache->base.run = vcache_run_extras;
+ }
+ else
+ {
+ vcache->base.run = vcache_run;
+ }
- vcache->base.run = vcache_run;
vcache->input_prim = prim;
vcache->output_prim = reduced_prim[prim];
--- /dev/null
+
+
+static void FUNC( struct draw_pt_front_end *frontend,
+ pt_elt_func get_elt,
+ const void *elts,
+ unsigned count )
+{
+ struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+ struct draw_context *draw = vcache->draw;
+
+ boolean flatfirst = (draw->rasterizer->flatshade &&
+ draw->rasterizer->flatshade_first);
+ unsigned i, flags;
+
+
+ switch (vcache->input_prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < count; i ++) {
+ POINT( vcache,
+ get_elt(elts, i + 0) );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 0; i+1 < count; i += 2) {
+ LINE( vcache,
+ DRAW_PIPE_RESET_STIPPLE,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1));
+ }
+ break;
+
+ case PIPE_PRIM_LINE_LOOP:
+ if (count >= 2) {
+ flags = DRAW_PIPE_RESET_STIPPLE;
+
+ for (i = 1; i < count; i++, flags = 0) {
+ LINE( vcache,
+ flags,
+ get_elt(elts, i - 1),
+ get_elt(elts, i ));
+ }
+
+ LINE( vcache,
+ flags,
+ get_elt(elts, i - 1),
+ get_elt(elts, 0 ));
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP:
+ flags = DRAW_PIPE_RESET_STIPPLE;
+ for (i = 1; i < count; i++, flags = 0) {
+ LINE( vcache,
+ flags,
+ get_elt(elts, i - 1),
+ get_elt(elts, i ));
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3) {
+ TRIANGLE( vcache,
+ DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2 ));
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ if (flatfirst) {
+ for (i = 0; i+2 < count; i++) {
+ TRIANGLE( vcache,
+ DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1 + (i&1)),
+ get_elt(elts, i + 2 - (i&1)));
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ TRIANGLE( vcache,
+ DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ get_elt(elts, i + 0 + (i&1)),
+ get_elt(elts, i + 1 - (i&1)),
+ get_elt(elts, i + 2 ));
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ if (count >= 3) {
+ if (flatfirst) {
+ for (i = 0; i+2 < count; i++) {
+ TRIANGLE( vcache,
+ DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, 0 ));
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ TRIANGLE( vcache,
+ DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+ get_elt(elts, 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2 ));
+ }
+ }
+ }
+ break;
+
+
+ case PIPE_PRIM_QUADS:
+ for (i = 0; i+3 < count; i += 4) {
+ QUAD( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 3));
+ }
+ break;
+
+ case PIPE_PRIM_QUAD_STRIP:
+ for (i = 0; i+3 < count; i += 2) {
+ QUAD( vcache,
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 3));
+ }
+ break;
+
+ case PIPE_PRIM_POLYGON:
+ {
+ /* These bitflags look a little odd because we submit the
+ * vertices as (1,2,0) to satisfy flatshade requirements.
+ */
+ const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2;
+ const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+ const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1;
+
+ flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
+
+ for (i = 0; i+2 < count; i++, flags = edge_middle) {
+
+ if (i + 3 == count)
+ flags |= edge_last;
+
+ TRIANGLE( vcache,
+ flags,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, 0));
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ vcache_flush( vcache );
+}
+
+
+#undef TRIANGLE
+#undef QUAD
+#undef POINT
+#undef LINE
+#undef FUNC