static INLINE void add_draw_el(struct varray_frontend *varray,
- int idx, ushort flags)
+ int idx)
{
- varray->draw_elts[varray->draw_count++] = idx | flags;
+ varray->draw_elts[varray->draw_count++] = idx;
}
unsigned i1,
unsigned i2 )
{
- add_draw_el(varray, i0, 0);
- add_draw_el(varray, i1, 0);
- add_draw_el(varray, i2, 0);
-}
-
-static INLINE void varray_triangle_flags( struct varray_frontend *varray,
- ushort flags,
- unsigned i0,
- unsigned i1,
- unsigned i2 )
-{
- add_draw_el(varray, i0, flags);
- add_draw_el(varray, i1, 0);
- add_draw_el(varray, i2, 0);
+ 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 )
{
- add_draw_el(varray, i0, 0);
- add_draw_el(varray, i1, 0);
-}
-
-
-static INLINE void varray_line_flags( struct varray_frontend *varray,
- ushort flags,
- unsigned i0,
- unsigned i1 )
-{
- add_draw_el(varray, i0, flags);
- add_draw_el(varray, i1, 0);
+ add_draw_el(varray, i0);
+ add_draw_el(varray, i1);
}
static INLINE void varray_point( struct varray_frontend *varray,
unsigned i0 )
{
- add_draw_el(varray, i0, 0);
-}
-
-static INLINE void varray_quad( struct varray_frontend *varray,
- unsigned i0,
- unsigned i1,
- unsigned i2,
- unsigned i3 )
-{
- varray_triangle( varray, i0, i1, i3 );
- varray_triangle( varray, i1, i2, i3 );
+ add_draw_el(varray, i0);
}
-static INLINE void varray_ef_quad( struct varray_frontend *varray,
- 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;
-
- varray_triangle_flags( varray,
- DRAW_PIPE_RESET_STIPPLE | omitEdge1,
- i0, i1, i3 );
-
- varray_triangle_flags( varray,
- omitEdge2,
- 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) varray_triangle_flags(vc,flags,i0,i1,i2)
-#define QUAD(vc,i0,i1,i2,i3) varray_ef_quad(vc,i0,i1,i2,i3)
-#define LINE(vc,flags,i0,i1) varray_line_flags(vc,flags,i0,i1)
-#define POINT(vc,i0) varray_point(vc,i0)
-#define FUNC varray_run_extras
-#include "draw_pt_varray_tmp.h"
-#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle(vc,i0,i1,i2)
-#define QUAD(vc,i0,i1,i2,i3) varray_quad(vc,i0,i1,i2,i3)
-#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1)
+#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"
-static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
+static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,
PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
+ PIPE_PRIM_LINE_STRIP,
+ PIPE_PRIM_LINES, /* decomposed */
PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES
+ PIPE_PRIM_TRIANGLE_STRIP,
+ PIPE_PRIM_TRIANGLES, /* decomposed */
+ PIPE_PRIM_QUADS,
+ PIPE_PRIM_QUAD_STRIP,
+ PIPE_PRIM_TRIANGLES /* decomposed */
};
{
struct varray_frontend *varray = (struct varray_frontend *)frontend;
- if (opt & PT_PIPELINE)
- {
- varray->base.run = varray_run_extras;
- }
- else
- {
- varray->base.run = varray_run;
- }
+ varray->base.run = varray_run;
varray->input_prim = prim;
- varray->output_prim = reduced_prim[prim];
+ varray->output_prim = decompose_prim[prim];
varray->middle = middle;
middle->prepare(middle, varray->output_prim, opt);
+static unsigned trim( unsigned count, unsigned first, unsigned incr )
+{
+ return count - (count - first) % incr;
+}
static void FUNC(struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
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 i, j;
unsigned first, incr;
varray->fetch_start = start;
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;
+ case PIPE_PRIM_LINE_STRIP:
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ case PIPE_PRIM_QUADS:
+ case PIPE_PRIM_QUAD_STRIP:
+
+ for (j = 0; j < count;) {
+ unsigned remaining = count - j;
+ unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr );
+ varray_flush_linear(varray, start + j, nr);
+ j += nr;
+ if (nr != remaining)
+ j -= (first - incr);
}
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);
+ for (i = 1; i < end; i++) {
+ LINE(varray, i - 1, i);
}
- LINE(varray, flags, i - 1, 0);
+ LINE(varray, 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);
- if (j + first + i <= count) {
- varray->fetch_start -= 2;
- i -= 2;
- }
- }
- }
- else {
- 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&1), i + 2);
- }
- i = end;
- fetch_init(varray, end);
- varray_flush(varray);
- if (j + first + i <= count) {
- varray->fetch_start -= 2;
- i -= 2;
- }
- }
- }
- break;
+ case PIPE_PRIM_POLYGON:
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);
+ for (i = 2; i < end; i++) {
+ TRIANGLE(varray, 0, i - 1, i);
}
i = end;
fetch_init(varray, end);
varray_flush(varray);
- if (j + first + i <= count) {
- varray->fetch_start -= 2;
- i -= 2;
- }
}
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;