*
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#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;
ushort draw_elts[DRAW_MAX];
unsigned fetch_elts[FETCH_MAX];
- unsigned draw_count;
- unsigned fetch_count;
+ unsigned driver_fetch_max;
+ unsigned fetch_max;
struct draw_pt_middle_end *middle;
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);
-#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;
-}
-#if 0
-static void varray_check_flush(struct varray_frontend *varray)
+static void varray_flush_linear(struct varray_frontend *varray,
+ unsigned start, unsigned count)
{
- if (varray->draw_count + 6 >= DRAW_MAX/* ||
- varray->fetch_count + 4 >= FETCH_MAX*/) {
- varray_flush(varray);
+ if (count) {
+ assert(varray->middle->run_linear);
+ varray->middle->run_linear(varray->middle, start, count);
}
}
-#endif
-static INLINE void add_draw_el(struct varray_frontend *varray,
- int idx, ushort flags)
+static void varray_line_loop_segment(struct varray_frontend *varray,
+ unsigned start,
+ unsigned segment_start,
+ unsigned segment_count,
+ boolean end )
{
- varray->draw_elts[varray->draw_count++] = idx | flags;
-}
+ assert(segment_count < 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;
-static INLINE void varray_triangle( struct varray_frontend *varray,
- unsigned i0,
- unsigned i1,
- unsigned i2 )
-{
- add_draw_el(varray, i0, 0);
- add_draw_el(varray, i1, 0);
- add_draw_el(varray, i2, 0);
-}
+ if (end)
+ varray->fetch_elts[nr++] = start;
-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);
-}
+ assert(nr <= FETCH_MAX);
-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);
+ varray->middle->run(varray->middle,
+ varray->fetch_elts,
+ nr,
+ varray->draw_elts, /* ie. linear */
+ nr);
+ }
}
-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);
-}
-
-static INLINE void varray_point( struct varray_frontend *varray,
- unsigned i0 )
+static void varray_fan_segment(struct varray_frontend *varray,
+ unsigned start,
+ unsigned segment_start,
+ unsigned segment_count )
{
- add_draw_el(varray, i0, 0);
-}
+ assert(segment_count < varray->fetch_max);
+ if (segment_count >= 2) {
+ unsigned nr = 0, i;
-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 );
-}
+ if (segment_start != 0)
+ varray->fetch_elts[nr++] = start;
-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;
+ for (i = 0 ; i < segment_count; i++)
+ varray->fetch_elts[nr++] = start + segment_start + i;
- varray_triangle_flags( varray,
- DRAW_PIPE_RESET_STIPPLE | omitEdge1,
- i0, i1, i3 );
+ assert(nr <= FETCH_MAX);
- varray_triangle_flags( varray,
- omitEdge2,
- i1, i2, i3 );
+ varray->middle->run(varray->middle,
+ varray->fetch_elts,
+ nr,
+ varray->draw_elts, /* ie. linear */
+ nr);
+ }
}
-/* 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 POINT(vc,i0) varray_point(vc,i0)
-#define FUNC varray_run
-#include "draw_pt_varray_tmp.h"
-static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
+#define FUNC varray_run
+#include "draw_pt_varray_tmp_linear.h"
+
+static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,
PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
+ PIPE_PRIM_LINE_STRIP, /* decomposed LINELOOP */
+ PIPE_PRIM_LINE_STRIP,
PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES
+ PIPE_PRIM_TRIANGLE_STRIP,
+ PIPE_PRIM_TRIANGLE_FAN,
+ PIPE_PRIM_QUADS,
+ PIPE_PRIM_QUAD_STRIP,
+ PIPE_PRIM_POLYGON
};
static void varray_prepare(struct draw_pt_front_end *frontend,
- unsigned prim,
+ unsigned in_prim,
+ unsigned out_prim,
struct draw_pt_middle_end *middle,
unsigned opt)
{
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->input_prim = in_prim;
+ varray->output_prim = decompose_prim[out_prim];
varray->middle = middle;
- middle->prepare(middle, varray->output_prim, opt);
+ middle->prepare(middle, varray->input_prim,
+ varray->output_prim, opt, &varray->driver_fetch_max );
+
+ /* check that the max is even */
+ assert((varray->driver_fetch_max & 1) == 0);
+
+ varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max);
}
struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw)
{
+ ushort i;
struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend);
if (varray == NULL)
return NULL;
varray->base.destroy = varray_destroy;
varray->draw = draw;
+ for (i = 0; i < DRAW_MAX; i++) {
+ varray->draw_elts[i] = i;
+ }
+
return &varray->base;
}