+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return PIPE_PRIM_LINES;
+ default:
+ return PIPE_PRIM_TRIANGLES;
+ }
+}
+
+/**
+ * Re-assemble a primitive to remove its adjacency.
+ */
+static inline enum pipe_prim_type
+u_assembled_prim(enum pipe_prim_type prim)
+{
+ switch (prim) {
+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return PIPE_PRIM_LINES;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return PIPE_PRIM_TRIANGLES;
+ default:
+ return prim;
+ }
+}
+
+/**
+ * Return the vertex count information for a primitive.
+ *
+ * Note that if this function is called directly or indirectly anywhere in a
+ * source file, it will increase the size of the binary slightly more than
+ * expected because of the use of a table.
+ */
+static inline const struct u_prim_vertex_count *
+u_prim_vertex_count(enum pipe_prim_type prim)
+{
+ static const struct u_prim_vertex_count prim_table[PIPE_PRIM_MAX] = {
+ { 1, 1 }, /* PIPE_PRIM_POINTS */
+ { 2, 2 }, /* PIPE_PRIM_LINES */
+ { 2, 1 }, /* PIPE_PRIM_LINE_LOOP */
+ { 2, 1 }, /* PIPE_PRIM_LINE_STRIP */
+ { 3, 3 }, /* PIPE_PRIM_TRIANGLES */
+ { 3, 1 }, /* PIPE_PRIM_TRIANGLE_STRIP */
+ { 3, 1 }, /* PIPE_PRIM_TRIANGLE_FAN */
+ { 4, 4 }, /* PIPE_PRIM_QUADS */
+ { 4, 2 }, /* PIPE_PRIM_QUAD_STRIP */
+ { 3, 1 }, /* PIPE_PRIM_POLYGON */
+ { 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */
+ { 4, 1 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
+ { 6, 6 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
+ { 6, 2 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
+ };
+
+ return (likely(prim < PIPE_PRIM_MAX)) ? &prim_table[prim] : NULL;
+}
+
+/**
+ * Given a vertex count, return the number of primitives.
+ * For polygons, return the number of triangles.
+ */
+static inline unsigned
+u_prims_for_vertices(enum pipe_prim_type prim, unsigned num)
+{
+ const struct u_prim_vertex_count *info = u_prim_vertex_count(prim);
+
+ assert(info);
+ assert(info->incr != 0);
+
+ if (num < info->min)
+ return 0;
+
+ return 1 + ((num - info->min) / info->incr);
+}
+
+static inline boolean
+u_validate_pipe_prim(enum pipe_prim_type pipe_prim, unsigned nr)
+{
+ const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
+
+ return (count && nr >= count->min);
+}
+
+
+static inline boolean
+u_trim_pipe_prim(enum pipe_prim_type pipe_prim, unsigned *nr)
+{
+ const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
+
+ if (count && *nr >= count->min) {
+ if (count->incr > 1)
+ *nr -= (*nr % count->incr);
+ return TRUE;
+ }
+ else {
+ *nr = 0;
+ return FALSE;
+ }
+}
+
+static inline unsigned
+u_vertices_per_prim(enum pipe_prim_type primitive)
+{
+ switch(primitive) {
+ case PIPE_PRIM_POINTS:
+ return 1;
+ case PIPE_PRIM_LINES: