Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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/u_debug.h"
35
 
36
#ifdef __cplusplus
37
extern "C" {
38
#endif
39
 
40
struct u_prim_vertex_count {
41
   unsigned min;
42
   unsigned incr;
43
};
44
 
45
/**
46
 * Decompose a primitive that is a loop, a strip, or a fan.  Return the
47
 * original primitive if it is already decomposed.
48
 */
49
static INLINE unsigned
50
u_decomposed_prim(unsigned prim)
51
{
52
   switch (prim) {
53
   case PIPE_PRIM_LINE_LOOP:
54
   case PIPE_PRIM_LINE_STRIP:
55
      return PIPE_PRIM_LINES;
56
   case PIPE_PRIM_TRIANGLE_STRIP:
57
   case PIPE_PRIM_TRIANGLE_FAN:
58
      return PIPE_PRIM_TRIANGLES;
59
   case PIPE_PRIM_QUAD_STRIP:
60
      return PIPE_PRIM_QUADS;
61
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
62
      return PIPE_PRIM_LINES_ADJACENCY;
63
   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
64
      return PIPE_PRIM_TRIANGLES_ADJACENCY;
65
   default:
66
      return prim;
67
   }
68
}
69
 
70
/**
71
 * Reduce a primitive to one of PIPE_PRIM_POINTS, PIPE_PRIM_LINES, and
72
 * PIPE_PRIM_TRIANGLES.
73
 */
74
static INLINE unsigned
75
u_reduced_prim(unsigned prim)
76
{
77
   switch (prim) {
78
   case PIPE_PRIM_POINTS:
79
      return PIPE_PRIM_POINTS;
80
   case PIPE_PRIM_LINES:
81
   case PIPE_PRIM_LINE_LOOP:
82
   case PIPE_PRIM_LINE_STRIP:
83
   case PIPE_PRIM_LINES_ADJACENCY:
84
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
85
      return PIPE_PRIM_LINES;
86
   default:
87
      return PIPE_PRIM_TRIANGLES;
88
   }
89
}
90
 
91
/**
92
 * Re-assemble a primitive to remove its adjacency.
93
 */
94
static INLINE unsigned
95
u_assembled_prim(unsigned prim)
96
{
97
   switch (prim) {
98
   case PIPE_PRIM_LINES_ADJACENCY:
99
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
100
      return PIPE_PRIM_LINES;
101
   case PIPE_PRIM_TRIANGLES_ADJACENCY:
102
   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
103
      return PIPE_PRIM_TRIANGLES;
104
   default:
105
      return prim;
106
   }
107
}
108
 
109
/**
110
 * Return the vertex count information for a primitive.
111
 *
112
 * Note that if this function is called directly or indirectly anywhere in a
113
 * source file, it will increase the size of the binary slightly more than
114
 * expected because of the use of a table.
115
 */
116
static INLINE const struct u_prim_vertex_count *
117
u_prim_vertex_count(unsigned prim)
118
{
119
   static const struct u_prim_vertex_count prim_table[PIPE_PRIM_MAX] = {
120
      { 1, 1 }, /* PIPE_PRIM_POINTS */
121
      { 2, 2 }, /* PIPE_PRIM_LINES */
122
      { 2, 1 }, /* PIPE_PRIM_LINE_LOOP */
123
      { 2, 1 }, /* PIPE_PRIM_LINE_STRIP */
124
      { 3, 3 }, /* PIPE_PRIM_TRIANGLES */
125
      { 3, 1 }, /* PIPE_PRIM_TRIANGLE_STRIP */
126
      { 3, 1 }, /* PIPE_PRIM_TRIANGLE_FAN */
127
      { 4, 4 }, /* PIPE_PRIM_QUADS */
128
      { 4, 2 }, /* PIPE_PRIM_QUAD_STRIP */
129
      { 3, 1 }, /* PIPE_PRIM_POLYGON */
130
      { 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */
131
      { 4, 1 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
132
      { 6, 6 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
133
      { 6, 2 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
134
   };
135
 
136
   return (likely(prim < PIPE_PRIM_MAX)) ? &prim_table[prim] : NULL;
137
}
138
 
139
/**
140
 * Given a vertex count, return the number of primitives.
141
 * For polygons, return the number of triangles.
142
 */
143
static INLINE unsigned
144
u_prims_for_vertices(unsigned prim, unsigned num)
145
{
146
   const struct u_prim_vertex_count *info = u_prim_vertex_count(prim);
147
 
148
   if (num < info->min)
149
      return 0;
150
 
151
   return 1 + ((num - info->min) / info->incr);
152
}
153
 
154
static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr )
155
{
156
   const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
157
 
158
   return (count && nr >= count->min);
159
}
160
 
161
 
162
static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr )
163
{
164
   const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
165
 
166
   if (count && *nr >= count->min) {
167
      if (count->incr > 1)
168
         *nr -= (*nr % count->incr);
169
      return TRUE;
170
   }
171
   else {
172
      *nr = 0;
173
      return FALSE;
174
   }
175
}
176
 
177
static INLINE unsigned
178
u_vertices_per_prim(int primitive)
179
{
180
   switch(primitive) {
181
   case PIPE_PRIM_POINTS:
182
      return 1;
183
   case PIPE_PRIM_LINES:
184
   case PIPE_PRIM_LINE_LOOP:
185
   case PIPE_PRIM_LINE_STRIP:
186
      return 2;
187
   case PIPE_PRIM_TRIANGLES:
188
   case PIPE_PRIM_TRIANGLE_STRIP:
189
   case PIPE_PRIM_TRIANGLE_FAN:
190
      return 3;
191
   case PIPE_PRIM_LINES_ADJACENCY:
192
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
193
      return 4;
194
   case PIPE_PRIM_TRIANGLES_ADJACENCY:
195
   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
196
      return 6;
197
 
198
   /* following primitives should never be used
199
    * with geometry shaders abd their size is
200
    * undefined */
201
   case PIPE_PRIM_POLYGON:
202
   case PIPE_PRIM_QUADS:
203
   case PIPE_PRIM_QUAD_STRIP:
204
   default:
205
      debug_printf("Unrecognized geometry shader primitive");
206
      return 3;
207
   }
208
}
209
 
210
/**
211
 * Returns the number of decomposed primitives for the given
212
 * vertex count.
213
 * Parts of the pipline are invoked once for each triangle in
214
 * triangle strip, triangle fans and triangles and once
215
 * for each line in line strip, line loop, lines. Also
216
 * statistics depend on knowing the exact number of decomposed
217
 * primitives for a set of vertices.
218
 */
219
static INLINE unsigned
220
u_decomposed_prims_for_vertices(int primitive, int vertices)
221
{
222
   switch (primitive) {
223
   case PIPE_PRIM_POINTS:
224
      return vertices;
225
   case PIPE_PRIM_LINES:
226
      return vertices / 2;
227
   case PIPE_PRIM_LINE_LOOP:
228
      return (vertices >= 2) ? vertices : 0;
229
   case PIPE_PRIM_LINE_STRIP:
230
      return (vertices >= 2) ? vertices - 1 : 0;
231
   case PIPE_PRIM_TRIANGLES:
232
      return vertices / 3;
233
   case PIPE_PRIM_TRIANGLE_STRIP:
234
      return (vertices >= 3) ? vertices - 2 : 0;
235
   case PIPE_PRIM_TRIANGLE_FAN:
236
      return (vertices >= 3) ? vertices - 2 : 0;
237
   case PIPE_PRIM_LINES_ADJACENCY:
238
      return vertices / 4;
239
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
240
      return (vertices >= 4) ? vertices - 3 : 0;
241
   case PIPE_PRIM_TRIANGLES_ADJACENCY:
242
      return vertices / 6;
243
   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
244
      return (vertices >= 6) ? 1 + (vertices - 6) / 2 : 0;
245
   case PIPE_PRIM_QUADS:
246
      return vertices / 4;
247
   case PIPE_PRIM_QUAD_STRIP:
248
      return (vertices >= 4) ? (vertices - 2) / 2 : 0;
249
   /* Polygons can't be decomposed
250
    * because the number of their vertices isn't known so
251
    * for them and whatever else we don't recognize just
252
    * return 1 if the number of vertices is greater than
253
    * or equal to 3 and zero otherwise */
254
   case PIPE_PRIM_POLYGON:
255
   default:
256
      debug_printf("Invalid decomposition primitive!\n");
257
      return (vertices >= 3) ? 1 : 0;
258
   }
259
}
260
 
261
/**
262
 * Returns the number of reduced/tessellated primitives for the given vertex
263
 * count.  Each quad is treated as two triangles.  Polygons are treated as
264
 * triangle fans.
265
 */
266
static INLINE unsigned
267
u_reduced_prims_for_vertices(int primitive, int vertices)
268
{
269
   switch (primitive) {
270
   case PIPE_PRIM_QUADS:
271
   case PIPE_PRIM_QUAD_STRIP:
272
      return u_decomposed_prims_for_vertices(primitive, vertices) * 2;
273
   case PIPE_PRIM_POLYGON:
274
      primitive = PIPE_PRIM_TRIANGLE_FAN;
275
      /* fall through */
276
   default:
277
      return u_decomposed_prims_for_vertices(primitive, vertices);
278
   }
279
}
280
 
281
const char *u_prim_name( unsigned pipe_prim );
282
 
283
 
284
#ifdef __cplusplus
285
}
286
#endif
287
 
288
 
289
#endif