u_prim.h revision af69d88d
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 37extern "C" { 38#endif 39 40struct 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 */ 49static INLINE unsigned 50u_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 */ 74static INLINE unsigned 75u_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 */ 94static INLINE unsigned 95u_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 */ 116static INLINE const struct u_prim_vertex_count * 117u_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 */ 143static INLINE unsigned 144u_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 154static 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 162static 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 177static INLINE unsigned 178u_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 */ 219static INLINE unsigned 220u_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 */ 266static INLINE unsigned 267u_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 281const char *u_prim_name( unsigned pipe_prim ); 282 283#endif 284