redo the linear paths

This commit is contained in:
Zack Rusin
2008-05-06 18:59:45 -04:00
parent e897fd6cd3
commit fe586f8612
8 changed files with 279 additions and 56 deletions
+39
View File
@@ -212,6 +212,45 @@ void draw_pipeline_run( struct draw_context *draw,
draw->pipeline.vertex_count = 0;
}
void draw_pipeline_run_linear( struct draw_context *draw,
unsigned prim,
struct vertex_header *vertices,
unsigned count,
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;
}
draw->pipeline.verts = NULL;
draw->pipeline.vertex_count = 0;
}
void draw_pipeline_flush( struct draw_context *draw,
@@ -247,6 +247,12 @@ void draw_pipeline_run( struct draw_context *draw,
const ushort *elts,
unsigned count );
void draw_pipeline_run_linear( struct draw_context *draw,
unsigned prim,
struct vertex_header *vertices,
unsigned count,
unsigned stride );
void draw_pipeline_flush( struct draw_context *draw,
+2 -4
View File
@@ -93,10 +93,8 @@ struct draw_pt_middle_end {
unsigned draw_count );
void (*run_linear)(struct draw_pt_middle_end *,
unsigned fetch_start,
unsigned fetch_count,
const ushort *draw_elts,
unsigned draw_count);
unsigned start,
unsigned count);
void (*finish)( struct draw_pt_middle_end * );
void (*destroy)( struct draw_pt_middle_end * );
@@ -258,10 +258,8 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
unsigned fetch_start,
unsigned fetch_count,
const ushort *draw_elts,
unsigned draw_count )
unsigned start,
unsigned count )
{
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
struct draw_context *draw = feme->draw;
@@ -273,7 +271,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
hw_verts = draw->render->allocate_vertices( draw->render,
(ushort)feme->translate->key.output_stride,
(ushort)fetch_count );
(ushort)count );
if (!hw_verts) {
assert(0);
return;
@@ -282,13 +280,13 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
/* Single routine to fetch vertices and emit HW verts.
*/
feme->translate->run( feme->translate,
fetch_start,
fetch_count,
start,
count,
hw_verts );
if (0) {
unsigned i;
for (i = 0; i < fetch_count; i++) {
for (i = 0; i < count; i++) {
debug_printf("\n\nvertex %d:\n", i);
draw_dump_emitted_vertex( feme->vinfo,
(const uint8_t *)hw_verts + feme->vinfo->size * 4 * i );
@@ -300,14 +298,14 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
*/
draw->render->draw_arrays( draw->render,
0, /*start*/
draw_count );
count );
/* Done -- that was easy, wasn't it:
*/
draw->render->release_vertices( draw->render,
hw_verts,
feme->translate->key.output_stride,
fetch_count );
count );
}
@@ -178,18 +178,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
unsigned fetch_start,
unsigned fetch_count,
const ushort *draw_elts,
unsigned draw_count )
unsigned start,
unsigned count)
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vertex_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align_int( fetch_count, 4 );
unsigned alloc_count = align_int( count, 4 );
struct vertex_header *pipeline_verts =
struct vertex_header *pipeline_verts =
(struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
if (!pipeline_verts) {
@@ -202,8 +200,8 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
/* Fetch into our vertex buffer
*/
draw_pt_fetch_run_linear( fpme->fetch,
fetch_start,
fetch_count,
start,
count,
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
@@ -213,18 +211,18 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
*/
if (opt & PT_SHADE)
{
shader->run_linear(shader,
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.constants,
fetch_count,
count,
fpme->vertex_size,
fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
pipeline_verts,
fetch_count,
count,
fpme->vertex_size ))
{
opt |= PT_PIPELINE;
@@ -233,21 +231,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
/* Do we need to run the pipeline?
*/
if (opt & PT_PIPELINE) {
draw_pipeline_run( fpme->draw,
fpme->prim,
pipeline_verts,
fetch_count,
fpme->vertex_size,
draw_elts,
draw_count );
draw_pipeline_run_linear( fpme->draw,
fpme->prim,
pipeline_verts,
count,
fpme->vertex_size);
}
else {
draw_pt_emit_linear( fpme->emit,
(const float (*)[4])pipeline_verts->data,
fetch_count,
count,
fpme->vertex_size,
0, /*start*/
draw_count );
count );
}
FREE(pipeline_verts);
+8 -19
View File
@@ -75,29 +75,18 @@ static void varray_flush(struct varray_frontend *varray)
varray->draw_count = 0;
}
static void varray_flush_linear(struct varray_frontend *varray)
static void varray_flush_linear(struct varray_frontend *varray,
unsigned start, unsigned count)
{
if (varray->draw_count) {
if (count) {
#if 0
debug_printf("FLUSH LINEAR fc = %d, dc = %d\n",
varray->fetch_count,
varray->draw_count);
debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n",
varray->fetch_elts[0],
varray->fetch_elts[varray->fetch_count-1],
varray->draw_elts[0],
varray->draw_elts[varray->draw_count-1]);
debug_printf("FLUSH LINEAR start = %d, count = %d\n",
start,
count);
#endif
assert(varray->middle->run_linear);
varray->middle->run_linear(varray->middle,
varray->fetch_start,
varray->fetch_count,
varray->draw_elts,
varray->draw_count);
varray->middle->run_linear(varray->middle, start, count);
}
varray->fetch_count = 0;
varray->draw_count = 0;
}
static INLINE void fetch_init(struct varray_frontend *varray,
@@ -261,7 +250,7 @@ static INLINE void varray_ef_quad( struct varray_frontend *varray,
#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1)
#define POINT(vc,i0) varray_point(vc,i0)
#define FUNC varray_run
#include "draw_pt_varray_tmp.h"
#include "draw_pt_varray_tmp_linear.h"
@@ -92,9 +92,8 @@ static void FUNC(struct draw_pt_front_end *frontend,
i + 0, i + 1, i + 2);
}
i = end;
varray->fetch_count = end;
varray_flush_linear(varray);
varray->fetch_start += end;
fetch_init(varray, end);
varray_flush(varray);
}
break;
@@ -0,0 +1,198 @@
static void FUNC(struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
const void *elts,
unsigned count)
{
struct varray_frontend *varray = (struct varray_frontend *)frontend;
struct draw_context *draw = varray->draw;
unsigned start = (unsigned)elts;
boolean flatfirst = (draw->rasterizer->flatshade &&
draw->rasterizer->flatshade_first);
unsigned i, j, flags;
unsigned first, incr;
varray->fetch_start = start;
split_prim_inplace(varray->input_prim, &first, &incr);
#if 0
debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
varray->input_prim,
start, count);
#endif
switch (varray->input_prim) {
case PIPE_PRIM_POINTS:
case PIPE_PRIM_LINES:
case PIPE_PRIM_TRIANGLES:
j = 0;
while (j + first <= count) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
varray_flush_linear(varray, start + j, end);
j += end;
}
break;
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
flags = DRAW_PIPE_RESET_STIPPLE;
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 1; i < end; i++, flags = 0) {
LINE(varray, flags, i - 1, i);
}
LINE(varray, flags, i - 1, 0);
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
}
break;
case PIPE_PRIM_LINE_STRIP:
flags = DRAW_PIPE_RESET_STIPPLE;
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 1; i < end; i++, flags = 0) {
LINE(varray, flags, i - 1, i);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
if (flatfirst) {
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+2 < end; i++) {
TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
i + 0, i + 1 + (i&1), i + 2 - (i&1));
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
}
else {
for (j = 0; j + first <= count;) {
unsigned end = MIN2(FETCH_MAX, count - j);
//end -= (end % incr);
for (i = 0; i+2 < end; i++) {
TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
i + 0 + (i&1), i + 1 - (i&1), i + 2);
}
fetch_init(varray, end);
varray_flush(varray);
j += end;
if (j <= count)
j -= incr;
}
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
if (flatfirst) {
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+2 < end; i++) {
TRIANGLE(varray, flags, i + 1, i + 2, 0);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
}
else {
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+2 < end; i++) {
TRIANGLE(varray, flags, 0, i + 1, i + 2);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
}
}
break;
case PIPE_PRIM_QUADS:
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+3 < end; i += 4) {
QUAD(varray, i + 0, i + 1, i + 2, i + 3);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+3 < end; i += 2) {
QUAD(varray, i + 2, i + 0, i + 1, i + 3);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
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 (j = 0; j + first <= count; j += i) {
unsigned end = MIN2(FETCH_MAX, count - j);
end -= (end % incr);
for (i = 0; i+2 < end; i++, flags = edge_middle) {
if (i + 3 == count)
flags |= edge_last;
TRIANGLE(varray, flags, i + 1, i + 2, 0);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
}
}
break;
default:
assert(0);
break;
}
varray_flush(varray);
}
#undef TRIANGLE
#undef QUAD
#undef POINT
#undef LINE
#undef FUNC