decomposition from keith, adds decomposition of more prim to the pipeline

This commit is contained in:
Zack Rusin 2008-05-13 16:06:09 -04:00
parent bbda45ec76
commit 1c624846a8
4 changed files with 261 additions and 90 deletions

View file

@ -212,6 +212,55 @@ void draw_pipeline_run( struct draw_context *draw,
draw->pipeline.vertex_count = 0;
}
#define QUAD(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_2 ), \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i1), \
verts + stride * (i3)); \
do_triangle( draw, \
( DRAW_PIPE_EDGE_FLAG_0 | \
DRAW_PIPE_EDGE_FLAG_1 ), \
verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i2), \
verts + stride * (i3))
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, \
flags, /* flags */ \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i1), \
verts + stride * (i2))
#define LINE(flags,i0,i1) \
do_line( draw, \
flags, \
verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
verts + stride * (i+1))
#define POINT(i0) \
do_point( draw, \
verts + stride * i0 )
#define FUNC pipe_run_linear
#define ARGS \
struct draw_context *draw, \
unsigned prim, \
struct vertex_header *vertices, \
unsigned stride
#define LOCAL_VARS \
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned i, flags
#define FLUSH
#include "draw_pt_decompose.h"
void draw_pipeline_run_linear( struct draw_context *draw,
unsigned prim,
struct vertex_header *vertices,
@ -219,34 +268,11 @@ void draw_pipeline_run_linear( struct draw_context *draw,
unsigned stride )
{
char *verts = (char *)vertices;
unsigned i;
draw->pipeline.verts = verts;
draw->pipeline.vertex_stride = stride;
draw->pipeline.vertex_count = count;
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i++)
do_point( draw,
verts + stride * i );
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2)
do_line( draw,
i+0, /* flags */
verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
verts + stride * (i+1));
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3)
do_triangle( draw,
(i+0), /* flags */
verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
verts + stride * (i+1),
verts + stride * (i+2));
break;
}
pipe_run_linear(draw, prim, vertices, stride, count);
draw->pipeline.verts = NULL;
draw->pipeline.vertex_count = 0;

View file

@ -0,0 +1,153 @@
static void FUNC( ARGS,
unsigned count )
{
LOCAL_VARS;
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
POINT( (i + 0) );
}
break;
case PIPE_PRIM_LINES:
for (i = 0; i+1 < count; i += 2) {
LINE( DRAW_PIPE_RESET_STIPPLE,
(i + 0),
(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( flags,
(i - 1),
(i ));
}
LINE( flags,
(i - 1),
(0 ));
}
break;
case PIPE_PRIM_LINE_STRIP:
flags = DRAW_PIPE_RESET_STIPPLE;
for (i = 1; i < count; i++, flags = 0) {
LINE( flags,
(i - 1),
(i ));
}
break;
case PIPE_PRIM_TRIANGLES:
for (i = 0; i+2 < count; i += 3) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0),
(i + 1),
(i + 2 ));
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0),
(i + 1 + (i&1)),
(i + 2 - (i&1)));
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 0 + (i&1)),
(i + 1 - (i&1)),
(i + 2 ));
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(i + 1),
(i + 2),
(0 ));
}
}
else {
for (i = 0; i+2 < count; i++) {
TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
(0),
(i + 1),
(i + 2 ));
}
}
}
break;
case PIPE_PRIM_QUADS:
for (i = 0; i+3 < count; i += 4) {
QUAD( (i + 0),
(i + 1),
(i + 2),
(i + 3));
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i+3 < count; i += 2) {
QUAD( (i + 2),
(i + 0),
(i + 1),
(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( flags,
(i + 1),
(i + 2),
(0));
}
}
break;
default:
assert(0);
break;
}
FLUSH;
}
#undef TRIANGLE
#undef QUAD
#undef POINT
#undef LINE
#undef FUNC

View file

@ -141,14 +141,19 @@ static INLINE void varray_point( struct varray_frontend *varray,
}
#if 0
#define TRIANGLE(flags,i0,i1,i2) varray_triangle(varray,i0,i1,i2)
#define LINE(flags,i0,i1) varray_line(varray,i0,i1)
#define POINT(i0) varray_point(varray,i0)
#define FUNC varray_decompose
#include "draw_pt_decompose.h"
#else
#define TRIANGLE(vc,i0,i1,i2) varray_triangle(vc,i0,i1,i2)
#define LINE(vc,i0,i1) varray_line(vc,i0,i1)
#define POINT(vc,i0) varray_point(vc,i0)
#define FUNC varray_run
#include "draw_pt_varray_tmp_linear.h"
#endif
static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,

View file

@ -104,22 +104,10 @@ static INLINE void vcache_elt( struct vcache_frontend *vcache,
static void vcache_triangle( struct vcache_frontend *vcache,
ushort flags,
unsigned i0,
unsigned i1,
unsigned i2 )
{
vcache_elt(vcache, i0, 0);
vcache_elt(vcache, i1, 0);
vcache_elt(vcache, i2, 0);
vcache_check_flush(vcache);
}
static void vcache_triangle_flags( struct vcache_frontend *vcache,
ushort flags,
unsigned i0,
unsigned i1,
unsigned i2 )
{
vcache_elt(vcache, i0, flags);
vcache_elt(vcache, i1, 0);
@ -128,19 +116,9 @@ static void vcache_triangle_flags( struct vcache_frontend *vcache,
}
static void vcache_line( struct vcache_frontend *vcache,
ushort flags,
unsigned i0,
unsigned i1 )
{
vcache_elt(vcache, i0, 0);
vcache_elt(vcache, i1, 0);
vcache_check_flush(vcache);
}
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);
@ -161,46 +139,63 @@ static void vcache_quad( struct vcache_frontend *vcache,
unsigned i2,
unsigned i3 )
{
vcache_triangle( vcache, i0, i1, i3 );
vcache_triangle( vcache, i1, i2, i3 );
}
vcache_triangle( vcache,
( DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_2 ),
i0, i1, i3 );
static void vcache_ef_quad( struct vcache_frontend *vcache,
unsigned i0,
unsigned i1,
unsigned i2,
unsigned 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 );
vcache_triangle( vcache,
( DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1 ),
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(flags,i0,i1,i2) \
vcache_triangle(vcache, \
flags, \
get_elt(elts,i0), \
get_elt(elts,i1), \
get_elt(elts,i2))
#define QUAD(i0,i1,i2,i3) \
vcache_quad(vcache, \
get_elt(elts,i0), \
get_elt(elts,i1), \
get_elt(elts,i2), \
get_elt(elts,i3))
#define LINE(flags,i0,i1) \
vcache_line(vcache, \
flags, \
get_elt(elts,i0), \
get_elt(elts,i1))
#define POINT(i0) \
vcache_point(vcache, \
get_elt(elts,i0))
#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"
#define ARGS \
struct draw_pt_front_end *frontend, \
pt_elt_func get_elt, \
const void *elts
#define LOCAL_VARS \
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; \
struct draw_context *draw = vcache->draw; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
unsigned prim = vcache->input_prim; \
unsigned i, flags;
#define FLUSH vcache_flush( vcache )
#include "draw_pt_decompose.h"
@ -213,15 +208,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
if (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 = draw_pt_reduced_prim(prim);