1/**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#ifndef U_PRIM_H
30#define U_PRIM_H
31
32
33#include "pipe/p_defines.h"
34#include "util/compiler.h"
35#include "util/u_debug.h"
36#include "compiler/shader_enums.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42struct u_prim_vertex_count {
43   unsigned min;
44   unsigned incr;
45};
46
47/**
48 * Decompose a primitive that is a loop, a strip, or a fan.  Return the
49 * original primitive if it is already decomposed.
50 */
51static inline enum pipe_prim_type
52u_decomposed_prim(enum pipe_prim_type prim)
53{
54   switch (prim) {
55   case PIPE_PRIM_LINE_LOOP:
56   case PIPE_PRIM_LINE_STRIP:
57      return PIPE_PRIM_LINES;
58   case PIPE_PRIM_TRIANGLE_STRIP:
59   case PIPE_PRIM_TRIANGLE_FAN:
60      return PIPE_PRIM_TRIANGLES;
61   case PIPE_PRIM_QUAD_STRIP:
62      return PIPE_PRIM_QUADS;
63   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
64      return PIPE_PRIM_LINES_ADJACENCY;
65   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
66      return PIPE_PRIM_TRIANGLES_ADJACENCY;
67   default:
68      return prim;
69   }
70}
71
72/**
73 * Reduce a primitive to one of PIPE_PRIM_POINTS, PIPE_PRIM_LINES, and
74 * PIPE_PRIM_TRIANGLES.
75 */
76static inline enum pipe_prim_type
77u_reduced_prim(enum pipe_prim_type prim)
78{
79   switch (prim) {
80   case PIPE_PRIM_POINTS:
81      return PIPE_PRIM_POINTS;
82   case PIPE_PRIM_LINES:
83   case PIPE_PRIM_LINE_LOOP:
84   case PIPE_PRIM_LINE_STRIP:
85   case PIPE_PRIM_LINES_ADJACENCY:
86   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
87      return PIPE_PRIM_LINES;
88   default:
89      return PIPE_PRIM_TRIANGLES;
90   }
91}
92
93/**
94 * Re-assemble a primitive to remove its adjacency.
95 */
96static inline enum pipe_prim_type
97u_assembled_prim(enum pipe_prim_type prim)
98{
99   switch (prim) {
100   case PIPE_PRIM_LINES_ADJACENCY:
101   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
102      return PIPE_PRIM_LINES;
103   case PIPE_PRIM_TRIANGLES_ADJACENCY:
104   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
105      return PIPE_PRIM_TRIANGLES;
106   default:
107      return prim;
108   }
109}
110
111/**
112 * Return the vertex count information for a primitive.
113 *
114 * Note that if this function is called directly or indirectly anywhere in a
115 * source file, it will increase the size of the binary slightly more than
116 * expected because of the use of a table.
117 */
118static inline const struct u_prim_vertex_count *
119u_prim_vertex_count(enum pipe_prim_type prim)
120{
121   static const struct u_prim_vertex_count prim_table[PIPE_PRIM_MAX] = {
122      { 1, 1 }, /* PIPE_PRIM_POINTS */
123      { 2, 2 }, /* PIPE_PRIM_LINES */
124      { 2, 1 }, /* PIPE_PRIM_LINE_LOOP */
125      { 2, 1 }, /* PIPE_PRIM_LINE_STRIP */
126      { 3, 3 }, /* PIPE_PRIM_TRIANGLES */
127      { 3, 1 }, /* PIPE_PRIM_TRIANGLE_STRIP */
128      { 3, 1 }, /* PIPE_PRIM_TRIANGLE_FAN */
129      { 4, 4 }, /* PIPE_PRIM_QUADS */
130      { 4, 2 }, /* PIPE_PRIM_QUAD_STRIP */
131      { 3, 1 }, /* PIPE_PRIM_POLYGON */
132      { 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */
133      { 4, 1 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
134      { 6, 6 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
135      { 6, 2 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
136   };
137
138   return (likely(prim < PIPE_PRIM_MAX)) ? &prim_table[prim] : NULL;
139}
140
141/**
142 * Given a vertex count, return the number of primitives.
143 * For polygons, return the number of triangles.
144 */
145static inline unsigned
146u_prims_for_vertices(enum pipe_prim_type prim, unsigned num)
147{
148   const struct u_prim_vertex_count *info = u_prim_vertex_count(prim);
149
150   assert(info);
151   assert(info->incr != 0);
152
153   if (num < info->min)
154      return 0;
155
156   return 1 + ((num - info->min) / info->incr);
157}
158
159static inline boolean
160u_validate_pipe_prim(enum pipe_prim_type pipe_prim, unsigned nr)
161{
162   const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
163
164   return (count && nr >= count->min);
165}
166
167
168static inline boolean
169u_trim_pipe_prim(enum pipe_prim_type pipe_prim, unsigned *nr)
170{
171   const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
172
173   if (count && *nr >= count->min) {
174      if (count->incr > 1)
175         *nr -= (*nr % count->incr);
176      return TRUE;
177   }
178   else {
179      *nr = 0;
180      return FALSE;
181   }
182}
183
184static inline unsigned
185u_vertices_per_prim(enum pipe_prim_type primitive)
186{
187   switch(primitive) {
188   case PIPE_PRIM_POINTS:
189      return 1;
190   case PIPE_PRIM_LINES:
191   case PIPE_PRIM_LINE_LOOP:
192   case PIPE_PRIM_LINE_STRIP:
193      return 2;
194   case PIPE_PRIM_TRIANGLES:
195   case PIPE_PRIM_TRIANGLE_STRIP:
196   case PIPE_PRIM_TRIANGLE_FAN:
197      return 3;
198   case PIPE_PRIM_LINES_ADJACENCY:
199   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
200      return 4;
201   case PIPE_PRIM_TRIANGLES_ADJACENCY:
202   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
203      return 6;
204
205   case PIPE_PRIM_QUADS:
206   case PIPE_PRIM_QUAD_STRIP:
207      /* these won't be seen from geometry shaders
208         but prim assembly might for prim id. */
209      return 4;
210
211   /* following primitives should never be used
212    * with geometry shaders abd their size is
213    * undefined */
214   case PIPE_PRIM_POLYGON:
215   default:
216      debug_printf("Unrecognized geometry shader primitive");
217      return 3;
218   }
219}
220
221/**
222 * Returns the number of decomposed primitives for the given
223 * vertex count.
224 * Parts of the pipline are invoked once for each triangle in
225 * triangle strip, triangle fans and triangles and once
226 * for each line in line strip, line loop, lines. Also
227 * statistics depend on knowing the exact number of decomposed
228 * primitives for a set of vertices.
229 */
230static inline unsigned
231u_decomposed_prims_for_vertices(enum pipe_prim_type primitive, int vertices)
232{
233   switch (primitive) {
234   case PIPE_PRIM_POINTS:
235      return vertices;
236   case PIPE_PRIM_LINES:
237      return vertices / 2;
238   case PIPE_PRIM_LINE_LOOP:
239      return (vertices >= 2) ? vertices : 0;
240   case PIPE_PRIM_LINE_STRIP:
241      return (vertices >= 2) ? vertices - 1 : 0;
242   case PIPE_PRIM_TRIANGLES:
243      return vertices / 3;
244   case PIPE_PRIM_TRIANGLE_STRIP:
245      return (vertices >= 3) ? vertices - 2 : 0;
246   case PIPE_PRIM_TRIANGLE_FAN:
247      return (vertices >= 3) ? vertices - 2 : 0;
248   case PIPE_PRIM_LINES_ADJACENCY:
249      return vertices / 4;
250   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
251      return (vertices >= 4) ? vertices - 3 : 0;
252   case PIPE_PRIM_TRIANGLES_ADJACENCY:
253      return vertices / 6;
254   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
255      return (vertices >= 6) ? 1 + (vertices - 6) / 2 : 0;
256   case PIPE_PRIM_QUADS:
257      return vertices / 4;
258   case PIPE_PRIM_QUAD_STRIP:
259      return (vertices >= 4) ? (vertices - 2) / 2 : 0;
260   /* Polygons can't be decomposed
261    * because the number of their vertices isn't known so
262    * for them and whatever else we don't recognize just
263    * return 1 if the number of vertices is greater than
264    * or equal to 3 and zero otherwise */
265   case PIPE_PRIM_POLYGON:
266   default:
267      debug_printf("Invalid decomposition primitive!\n");
268      return (vertices >= 3) ? 1 : 0;
269   }
270}
271
272/**
273 * Returns the number of reduced/tessellated primitives for the given vertex
274 * count.  Each quad is treated as two triangles.  Polygons are treated as
275 * triangle fans.
276 */
277static inline unsigned
278u_reduced_prims_for_vertices(enum pipe_prim_type primitive, int vertices)
279{
280   switch (primitive) {
281   case PIPE_PRIM_QUADS:
282   case PIPE_PRIM_QUAD_STRIP:
283      return u_decomposed_prims_for_vertices(primitive, vertices) * 2;
284   case PIPE_PRIM_POLYGON:
285      primitive = PIPE_PRIM_TRIANGLE_FAN;
286      FALLTHROUGH;
287   default:
288      return u_decomposed_prims_for_vertices(primitive, vertices);
289   }
290}
291
292static inline enum pipe_prim_type
293u_base_prim_type(enum pipe_prim_type prim_type)
294{
295   switch(prim_type) {
296      case PIPE_PRIM_POINTS:
297         return PIPE_PRIM_POINTS;
298      case PIPE_PRIM_LINES:
299      case PIPE_PRIM_LINE_LOOP:
300      case PIPE_PRIM_LINE_STRIP:
301      case PIPE_PRIM_LINES_ADJACENCY:
302      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
303         return PIPE_PRIM_LINES;
304      case PIPE_PRIM_TRIANGLES:
305      case PIPE_PRIM_TRIANGLE_STRIP:
306      case PIPE_PRIM_TRIANGLE_FAN:
307      case PIPE_PRIM_TRIANGLES_ADJACENCY:
308      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
309         return PIPE_PRIM_TRIANGLES;
310      case PIPE_PRIM_QUADS:
311      case PIPE_PRIM_QUAD_STRIP:
312         return PIPE_PRIM_QUADS;
313      default:
314         return prim_type;
315   }
316}
317
318static inline enum pipe_prim_type
319u_tess_prim_from_shader(enum tess_primitive_mode shader_mode)
320{
321   switch (shader_mode) {
322   case TESS_PRIMITIVE_TRIANGLES:
323      return PIPE_PRIM_TRIANGLES;
324   case TESS_PRIMITIVE_QUADS:
325      return PIPE_PRIM_QUADS;
326   case TESS_PRIMITIVE_ISOLINES:
327      return PIPE_PRIM_LINES;
328   default:
329      return PIPE_PRIM_POINTS;
330   }
331}
332
333static inline unsigned
334u_vertices_for_prims(enum pipe_prim_type prim_type, int count)
335{
336   if (count <= 0)
337      return 0;
338
339   /* We can only figure out the number of vertices from a number of primitives
340    * if we are using basic primitives (so no loops, strips, fans, etc).
341    */
342   assert(prim_type == u_base_prim_type(prim_type) &&
343          prim_type != PIPE_PRIM_PATCHES && prim_type != PIPE_PRIM_POLYGON);
344
345   const struct u_prim_vertex_count *info = u_prim_vertex_count(prim_type);
346   assert(info);
347
348   return info->min + (count - 1) * info->incr;
349}
350
351/**
352 * Returns the number of stream out outputs for a given number of vertices and
353 * primitive type.
354 */
355
356static inline unsigned
357u_stream_outputs_for_vertices(enum pipe_prim_type primitive, unsigned nr)
358{
359   /* Extraneous vertices don't contribute to stream outputs */
360   u_trim_pipe_prim(primitive, &nr);
361
362   /* Polygons are special, since they are a single primitive with many
363    * vertices. In this case, we just have an output for each vertex (after
364    * trimming) */
365
366   if (primitive == PIPE_PRIM_POLYGON)
367      return nr;
368
369   /* Normally, consider how many primitives are actually generated */
370   unsigned prims = u_decomposed_prims_for_vertices(primitive, nr);
371
372   /* One output per vertex after decomposition */
373   enum pipe_prim_type base = u_base_prim_type(primitive);
374   return u_vertices_for_prims(base, prims);
375}
376
377const char *u_prim_name(enum pipe_prim_type pipe_prim);
378
379
380#ifdef __cplusplus
381}
382#endif
383
384
385#endif
386