From 061e1c6c57703a92ac17b553f592c0c6114cb227 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 10 Jun 2008 09:16:34 +0100 Subject: [PATCH] draw: rework splitting of fan/loop prims in varray.c, fix flatshade issues --- src/gallium/auxiliary/draw/draw_pt_varray.c | 138 +++++++----------- .../draw/draw_pt_varray_tmp_linear.h | 54 +++---- 2 files changed, 76 insertions(+), 116 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index f5495a80c78..4479963db17 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -31,7 +31,7 @@ #include "draw/draw_pt.h" #define FETCH_MAX 256 -#define DRAW_MAX (16*FETCH_MAX) +#define DRAW_MAX (FETCH_MAX+8) struct varray_frontend { struct draw_pt_front_end base; @@ -40,11 +40,6 @@ struct varray_frontend { ushort draw_elts[DRAW_MAX]; unsigned fetch_elts[FETCH_MAX]; - unsigned draw_count; - unsigned fetch_count; - - unsigned fetch_start; - unsigned driver_fetch_max; unsigned fetch_max; @@ -54,121 +49,86 @@ struct varray_frontend { unsigned output_prim; }; -static void varray_flush(struct varray_frontend *varray) -{ - if (varray->draw_count) { -#if 0 - debug_printf("FLUSH 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]); -#endif - varray->middle->run(varray->middle, - varray->fetch_elts, - varray->fetch_count, - varray->draw_elts, - varray->draw_count); - } - - varray->fetch_count = 0; - varray->draw_count = 0; -} static void varray_flush_linear(struct varray_frontend *varray, unsigned start, unsigned count) { if (count) { -#if 0 - debug_printf("FLUSH LINEAR start = %d, count = %d\n", - start, - count); -#endif assert(varray->middle->run_linear); varray->middle->run_linear(varray->middle, start, count); } } -static INLINE void fetch_init(struct varray_frontend *varray, - unsigned count) +static void varray_line_loop_segment(struct varray_frontend *varray, + unsigned start, + unsigned segment_start, + unsigned segment_count, + boolean end ) { - unsigned idx; -#if 0 - debug_printf("FETCH INIT c = %d, fs = %d\n", - count, - varray->fetch_start); -#endif - for (idx = 0; idx < count; ++idx) { - varray->fetch_elts[idx] = varray->fetch_start + idx; - } - varray->fetch_start += idx; - varray->fetch_count = idx; -} + assert(segment_count+1 < varray->fetch_max); + if (segment_count >= 1) { + unsigned nr = 0, i; + for (i = 0; i < segment_count; i++) + varray->fetch_elts[nr++] = start + segment_start + i; + if (end) + varray->fetch_elts[nr++] = start; + assert(nr < FETCH_MAX); -static INLINE void add_draw_el(struct varray_frontend *varray, - unsigned idx) -{ - varray->draw_elts[varray->draw_count++] = (ushort)idx; + varray->middle->run(varray->middle, + varray->fetch_elts, + nr, + varray->draw_elts, /* ie. linear */ + nr); + } } -static INLINE void varray_triangle( struct varray_frontend *varray, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - add_draw_el(varray, i0); - add_draw_el(varray, i1); - add_draw_el(varray, i2); -} -static INLINE void varray_line( struct varray_frontend *varray, - unsigned i0, - unsigned i1 ) +static void varray_fan_segment(struct varray_frontend *varray, + unsigned start, + unsigned segment_start, + unsigned segment_count ) { - add_draw_el(varray, i0); - add_draw_el(varray, i1); -} + assert(segment_count+1 < varray->fetch_max); + if (segment_count >= 2) { + unsigned nr = 0, i; + if (segment_start != 0) + varray->fetch_elts[nr++] = start; -static INLINE void varray_point( struct varray_frontend *varray, - unsigned i0 ) -{ - add_draw_el(varray, i0); + for (i = 0 ; i < segment_count; i++) + varray->fetch_elts[nr++] = start + segment_start + i; + + assert(nr < FETCH_MAX); + + varray->middle->run(varray->middle, + varray->fetch_elts, + nr, + varray->draw_elts, /* ie. linear */ + nr); + } } -#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, PIPE_PRIM_LINES, - PIPE_PRIM_LINES, /* decomposed LINELOOP */ + PIPE_PRIM_LINE_STRIP, /* decomposed LINELOOP */ PIPE_PRIM_LINE_STRIP, PIPE_PRIM_TRIANGLES, PIPE_PRIM_TRIANGLE_STRIP, - PIPE_PRIM_TRIANGLES, /* decomposed TRI_FAN */ + PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP, - PIPE_PRIM_TRIANGLES /* decomposed POLYGON */ + PIPE_PRIM_POLYGON }; @@ -186,7 +146,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend, varray->output_prim = decompose_prim[prim]; varray->middle = middle; - middle->prepare(middle, varray->output_prim, opt, &varray->fetch_max ); + middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max ); + varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max); } @@ -207,6 +168,7 @@ static void varray_destroy(struct draw_pt_front_end *frontend) struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) { + unsigned i; struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend); if (varray == NULL) return NULL; @@ -217,5 +179,9 @@ struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) varray->base.destroy = varray_destroy; varray->draw = draw; + for (i = 0; i < DRAW_MAX; i++) { + varray->draw_elts[i] = i; + } + return &varray->base; } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index 6e5e30f38e5..55a8e6521dc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -11,11 +11,9 @@ static void FUNC(struct draw_pt_front_end *frontend, struct varray_frontend *varray = (struct varray_frontend *)frontend; unsigned start = (unsigned)elts; - unsigned i, j; + unsigned j; unsigned first, incr; - varray->fetch_start = start; - draw_pt_split_prim(varray->input_prim, &first, &incr); /* Sanitize primitive length: @@ -40,7 +38,7 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_QUAD_STRIP: for (j = 0; j < count;) { unsigned remaining = count - j; - unsigned nr = trim( MIN2(varray->fetch_max, remaining), first, incr ); + unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr ); varray_flush_linear(varray, start + j, nr); j += nr; if (nr != remaining) @@ -49,45 +47,41 @@ static void FUNC(struct draw_pt_front_end *frontend, break; case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(fetch_max, count - j); - end -= (end % incr); - for (i = 1; i < end; i++) { - LINE(varray, i - 1, i); - } - LINE(varray, i - 1, 0); - i = end; - fetch_init(varray, end); - varray_flush(varray); - } + /* Always have to decompose as we've stated that this will be + * emitted as a line-strip. + */ + for (j = 0; j < count;) { + unsigned remaining = count - j; + unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr ); + varray_line_loop_segment(varray, start, j, nr, nr == remaining); + j += nr; + if (nr != remaining) + j -= (first - incr); } break; case PIPE_PRIM_POLYGON: - case PIPE_PRIM_TRIANGLE_FAN: { - unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(fetch_max, count - j); - end -= (end % incr); - for (i = 2; i < end; i++) { - TRIANGLE(varray, 0, i - 1, i); + case PIPE_PRIM_TRIANGLE_FAN: + if (count < varray->driver_fetch_max) { + varray_flush_linear(varray, start, count); + } + else { + for ( j = 0; j < count;) { + unsigned remaining = count - j; + unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr ); + varray_fan_segment(varray, start, j, nr); + j += nr; + if (nr != remaining) + j -= (first - incr); } - i = end; - fetch_init(varray, end); - varray_flush(varray); } break; - } default: assert(0); break; } - - varray_flush(varray); } #undef TRIANGLE -- 2.30.2