draw: more flatshade_first changes

- Reduce the number of changes to the normal vertex ordering
- Assume that the hardware knows how to do this in the standard case.
- Add support to the passthrough vcache path.
This commit is contained in:
Keith Whitwell
2008-04-01 14:49:56 +01:00
parent caa44763f7
commit edfa8201a5
5 changed files with 144 additions and 97 deletions

View File

@@ -343,21 +343,11 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINES:
if (flatfirst) {
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 1,
start + i + 0);
}
}
else {
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 0,
start + i + 1);
}
for (i = 0; i+1 < count; i += 2) {
do_line( draw,
TRUE,
start + i + 0,
start + i + 1);
}
break;
@@ -378,63 +368,31 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINE_STRIP:
if (flatfirst) {
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i,
start + i - 1 );
}
}
else {
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i - 1,
start + i );
}
for (i = 1; i < count; i++) {
do_line( draw,
i == 1,
start + i - 1,
start + i );
}
break;
case PIPE_PRIM_TRIANGLES:
if (flatfirst) {
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 1,
start + i + 2,
start + i + 0 );
}
}
else {
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 1,
start + i + 2,
start + i + 0 );
}
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
}
else {
if (unfilled) {
for (i = 0; i+2 < count; i += 3) {
do_ef_triangle( draw,
1,
~0,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
else {
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2 );
}
for (i = 0; i+2 < count; i += 3) {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2 );
}
}
break;
@@ -444,15 +402,15 @@ draw_prim( struct draw_context *draw,
for (i = 0; i+2 < count; i++) {
if (i & 1) {
do_triangle( draw,
start + i + 0,
start + i + 2,
start + i + 1,
start + i + 0 );
start + i + 1 );
}
else {
do_triangle( draw,
start + i + 0,
start + i + 1,
start + i + 2,
start + i + 0 );
start + i + 2 );
}
}
}
@@ -479,9 +437,9 @@ draw_prim( struct draw_context *draw,
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
do_triangle( draw,
start + i + 1,
start + i + 2,
start + 0,
start + i + 1 );
start + 0 );
}
}
else {

View File

@@ -191,7 +191,7 @@ boolean draw_pt_init( struct draw_context *draw )
if (!draw->pt.middle.fetch_emit)
return FALSE;
draw->pt.front.vcache = draw_pt_vcache();
draw->pt.front.vcache = draw_pt_vcache( draw );
if (!draw->pt.front.vcache)
return FALSE;

View File

@@ -110,7 +110,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw,
/* Implementations:
*/
struct draw_pt_front_end *draw_pt_vcache( void );
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );

View File

@@ -44,6 +44,7 @@
struct vcache_frontend {
struct draw_pt_front_end base;
struct draw_context *draw;
unsigned in[CACHE_MAX];
ushort out[CACHE_MAX];
@@ -157,14 +158,6 @@ static void vcache_quad( struct vcache_frontend *vcache,
}
static void vcache_prepare( struct draw_pt_front_end *frontend,
struct draw_pt_middle_end *middle )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
vcache->middle = middle;
middle->prepare( middle );
}
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,
PIPE_PRIM_LINES,
@@ -179,11 +172,11 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
};
static void vcache_run( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
static void vcache_run_pv2( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
unsigned i;
@@ -309,6 +302,109 @@ static void vcache_run( struct draw_pt_front_end *frontend,
vcache_flush( vcache );
}
static void vcache_run_pv0( struct draw_pt_front_end *frontend,
unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
unsigned i;
/* These are for validation only:
*/
vcache->elt_func = get_elt;
vcache->elt_ptr = elts;
vcache->output_prim = reduced_prim[prim];
switch (prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
vcache_point( vcache,
get_elt(elts, i) );
}
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_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:
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:
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) );
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
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 );
}
static void vcache_prepare( struct draw_pt_front_end *frontend,
struct draw_pt_middle_end *middle )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
if (vcache->draw->rasterizer->flatshade_first)
vcache->base.run = vcache_run_pv0;
else
vcache->base.run = vcache_run_pv2;
vcache->middle = middle;
middle->prepare( middle );
}
static void vcache_finish( struct draw_pt_front_end *frontend )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
@@ -322,14 +418,15 @@ static void vcache_destroy( struct draw_pt_front_end *frontend )
}
struct draw_pt_front_end *draw_pt_vcache( void )
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw )
{
struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend );
vcache->base.prepare = vcache_prepare;
vcache->base.run = vcache_run;
vcache->base.run = NULL;
vcache->base.finish = vcache_finish;
vcache->base.destroy = vcache_destroy;
vcache->draw = draw;
memset(vcache->in, ~0, sizeof(vcache->in));

View File

@@ -76,10 +76,6 @@ draw_need_pipeline(const struct draw_context *draw,
/* AA lines */
if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
return TRUE;
/* first-vertex driven flatshading */
if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first)
return TRUE;
}
if (points(prim))
@@ -116,10 +112,6 @@ draw_need_pipeline(const struct draw_context *draw,
/* two-side lighting */
if (draw->rasterizer->light_twoside)
return TRUE;
/* first-vertex driven flatshading */
if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first)
return TRUE;
}
/* polygon cull - this is difficult - hardware can cull just fine