1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
static unsigned trim( unsigned count, unsigned first, unsigned incr )
{
/*
* count either has been trimmed in draw_pt_arrays or is set to
* (driver)_fetch_max which is hopefully always larger than first.
*/
assert(count >= first);
return count - (count - first) % incr;
}
static void FUNC(struct draw_pt_front_end *frontend,
pt_elt_func get_elt,
const void *elts,
int elt_bias,
unsigned count)
{
struct varray_frontend *varray = (struct varray_frontend *)frontend;
unsigned start = (unsigned) ((char *) elts - (char *) NULL);
unsigned j;
unsigned first, incr;
assert(elt_bias == 0);
draw_pt_split_prim(varray->input_prim, &first, &incr);
/* Sanitize primitive length:
*/
count = trim(count, first, incr);
if (count < first)
return;
#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:
case PIPE_PRIM_LINE_STRIP:
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
case PIPE_PRIM_LINES_ADJACENCY:
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
case PIPE_PRIM_TRIANGLES_ADJACENCY:
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
for (j = 0; j < count;) {
unsigned remaining = count - j;
unsigned nr = trim( MIN2(varray->driver_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:
/* 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:
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);
}
}
break;
default:
assert(0);
break;
}
}
#undef TRIANGLE
#undef QUAD
#undef POINT
#undef LINE
#undef FUNC
|