redo the linear paths
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user