1 #ifndef __NOUVEAU_UTIL_H__
2 #define __NOUVEAU_UTIL_H__
4 /* Determine how many vertices can be pushed into the command stream.
5 * Where the remaining space isn't large enough to represent all verices,
6 * split the buffer at primitive boundaries.
8 * Returns a count of vertices that can be rendered, and an index to
9 * restart drawing at after a flush.
11 static INLINE unsigned
12 nouveau_vbuf_split(unsigned remaining, unsigned overhead, unsigned vpp,
13 unsigned mode, unsigned start, unsigned count,
18 max = remaining - overhead;
27 case PIPE_PRIM_POINTS:
32 case PIPE_PRIM_TRIANGLES:
33 max = max - (max % 3);
38 case PIPE_PRIM_LINE_LOOP:
39 case PIPE_PRIM_LINE_STRIP:
44 case PIPE_PRIM_POLYGON:
45 case PIPE_PRIM_TRIANGLE_STRIP:
46 case PIPE_PRIM_TRIANGLE_FAN:
51 case PIPE_PRIM_QUAD_STRIP:
60 *restart = start + max - adj;
64 /* Integer base-2 logarithm, rounded towards zero. */
65 static INLINE unsigned log2i(unsigned i)
93 void (*emit)(void *priv, unsigned start, unsigned count);
94 void (*edge)(void *priv, boolean enabled);
107 u_split_prim_init(struct u_split_prim *s,
108 unsigned mode, unsigned start, unsigned count)
110 if (mode == PIPE_PRIM_LINE_LOOP) {
111 s->mode = PIPE_PRIM_LINE_STRIP;
119 s->p_end = start + count;
124 static INLINE boolean
125 u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
129 if (s->repeat_first) {
130 s->emit(s->priv, s->start, 1);
132 if (s->edgeflag_off) {
133 s->edge(s->priv, TRUE);
134 s->edgeflag_off = FALSE;
138 if (s->p_start + s->close_first + max_verts >= s->p_end) {
139 s->emit(s->priv, s->p_start, s->p_end - s->p_start);
141 s->emit(s->priv, s->start, 1);
146 case PIPE_PRIM_LINES:
149 case PIPE_PRIM_LINE_STRIP:
152 case PIPE_PRIM_POLYGON:
154 s->emit(s->priv, s->p_start, max_verts);
155 s->edge(s->priv, FALSE);
156 s->emit(s->priv, s->p_start + max_verts, 1);
157 s->p_start += max_verts;
158 s->repeat_first = TRUE;
159 s->edgeflag_off = TRUE;
161 case PIPE_PRIM_TRIANGLES:
162 max_verts = max_verts - (max_verts % 3);
164 case PIPE_PRIM_TRIANGLE_STRIP:
165 /* to ensure winding stays correct, always split
166 * on an even number of generated triangles
168 max_verts = max_verts & ~1;
171 case PIPE_PRIM_TRIANGLE_FAN:
172 s->repeat_first = TRUE;
175 case PIPE_PRIM_QUADS:
178 case PIPE_PRIM_QUAD_STRIP:
186 s->emit (s->priv, s->p_start, max_verts);
187 s->p_start += (max_verts - repeat);