1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2008 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg 29848b8605Smrg#ifndef U_PRIM_H 30848b8605Smrg#define U_PRIM_H 31848b8605Smrg 32848b8605Smrg 33848b8605Smrg#include "pipe/p_defines.h" 34848b8605Smrg#include "util/u_debug.h" 35848b8605Smrg 36848b8605Smrg#ifdef __cplusplus 37848b8605Smrgextern "C" { 38848b8605Smrg#endif 39848b8605Smrg 40848b8605Smrgstruct u_prim_vertex_count { 41848b8605Smrg unsigned min; 42848b8605Smrg unsigned incr; 43848b8605Smrg}; 44848b8605Smrg 45848b8605Smrg/** 46848b8605Smrg * Decompose a primitive that is a loop, a strip, or a fan. Return the 47848b8605Smrg * original primitive if it is already decomposed. 48848b8605Smrg */ 49b8e80941Smrgstatic inline enum pipe_prim_type 50b8e80941Smrgu_decomposed_prim(enum pipe_prim_type prim) 51848b8605Smrg{ 52848b8605Smrg switch (prim) { 53848b8605Smrg case PIPE_PRIM_LINE_LOOP: 54848b8605Smrg case PIPE_PRIM_LINE_STRIP: 55848b8605Smrg return PIPE_PRIM_LINES; 56848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP: 57848b8605Smrg case PIPE_PRIM_TRIANGLE_FAN: 58848b8605Smrg return PIPE_PRIM_TRIANGLES; 59848b8605Smrg case PIPE_PRIM_QUAD_STRIP: 60848b8605Smrg return PIPE_PRIM_QUADS; 61848b8605Smrg case PIPE_PRIM_LINE_STRIP_ADJACENCY: 62848b8605Smrg return PIPE_PRIM_LINES_ADJACENCY; 63848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 64848b8605Smrg return PIPE_PRIM_TRIANGLES_ADJACENCY; 65848b8605Smrg default: 66848b8605Smrg return prim; 67848b8605Smrg } 68848b8605Smrg} 69848b8605Smrg 70848b8605Smrg/** 71848b8605Smrg * Reduce a primitive to one of PIPE_PRIM_POINTS, PIPE_PRIM_LINES, and 72848b8605Smrg * PIPE_PRIM_TRIANGLES. 73848b8605Smrg */ 74b8e80941Smrgstatic inline enum pipe_prim_type 75b8e80941Smrgu_reduced_prim(enum pipe_prim_type prim) 76848b8605Smrg{ 77848b8605Smrg switch (prim) { 78848b8605Smrg case PIPE_PRIM_POINTS: 79848b8605Smrg return PIPE_PRIM_POINTS; 80848b8605Smrg case PIPE_PRIM_LINES: 81848b8605Smrg case PIPE_PRIM_LINE_LOOP: 82848b8605Smrg case PIPE_PRIM_LINE_STRIP: 83848b8605Smrg case PIPE_PRIM_LINES_ADJACENCY: 84848b8605Smrg case PIPE_PRIM_LINE_STRIP_ADJACENCY: 85848b8605Smrg return PIPE_PRIM_LINES; 86848b8605Smrg default: 87848b8605Smrg return PIPE_PRIM_TRIANGLES; 88848b8605Smrg } 89848b8605Smrg} 90848b8605Smrg 91848b8605Smrg/** 92848b8605Smrg * Re-assemble a primitive to remove its adjacency. 93848b8605Smrg */ 94b8e80941Smrgstatic inline enum pipe_prim_type 95b8e80941Smrgu_assembled_prim(enum pipe_prim_type prim) 96848b8605Smrg{ 97848b8605Smrg switch (prim) { 98848b8605Smrg case PIPE_PRIM_LINES_ADJACENCY: 99848b8605Smrg case PIPE_PRIM_LINE_STRIP_ADJACENCY: 100848b8605Smrg return PIPE_PRIM_LINES; 101848b8605Smrg case PIPE_PRIM_TRIANGLES_ADJACENCY: 102848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 103848b8605Smrg return PIPE_PRIM_TRIANGLES; 104848b8605Smrg default: 105848b8605Smrg return prim; 106848b8605Smrg } 107848b8605Smrg} 108848b8605Smrg 109848b8605Smrg/** 110848b8605Smrg * Return the vertex count information for a primitive. 111848b8605Smrg * 112848b8605Smrg * Note that if this function is called directly or indirectly anywhere in a 113848b8605Smrg * source file, it will increase the size of the binary slightly more than 114848b8605Smrg * expected because of the use of a table. 115848b8605Smrg */ 116b8e80941Smrgstatic inline const struct u_prim_vertex_count * 117b8e80941Smrgu_prim_vertex_count(enum pipe_prim_type prim) 118848b8605Smrg{ 119848b8605Smrg static const struct u_prim_vertex_count prim_table[PIPE_PRIM_MAX] = { 120848b8605Smrg { 1, 1 }, /* PIPE_PRIM_POINTS */ 121848b8605Smrg { 2, 2 }, /* PIPE_PRIM_LINES */ 122848b8605Smrg { 2, 1 }, /* PIPE_PRIM_LINE_LOOP */ 123848b8605Smrg { 2, 1 }, /* PIPE_PRIM_LINE_STRIP */ 124848b8605Smrg { 3, 3 }, /* PIPE_PRIM_TRIANGLES */ 125848b8605Smrg { 3, 1 }, /* PIPE_PRIM_TRIANGLE_STRIP */ 126848b8605Smrg { 3, 1 }, /* PIPE_PRIM_TRIANGLE_FAN */ 127848b8605Smrg { 4, 4 }, /* PIPE_PRIM_QUADS */ 128848b8605Smrg { 4, 2 }, /* PIPE_PRIM_QUAD_STRIP */ 129848b8605Smrg { 3, 1 }, /* PIPE_PRIM_POLYGON */ 130848b8605Smrg { 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */ 131848b8605Smrg { 4, 1 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */ 132848b8605Smrg { 6, 6 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */ 133848b8605Smrg { 6, 2 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */ 134848b8605Smrg }; 135848b8605Smrg 136848b8605Smrg return (likely(prim < PIPE_PRIM_MAX)) ? &prim_table[prim] : NULL; 137848b8605Smrg} 138848b8605Smrg 139848b8605Smrg/** 140848b8605Smrg * Given a vertex count, return the number of primitives. 141848b8605Smrg * For polygons, return the number of triangles. 142848b8605Smrg */ 143b8e80941Smrgstatic inline unsigned 144b8e80941Smrgu_prims_for_vertices(enum pipe_prim_type prim, unsigned num) 145848b8605Smrg{ 146848b8605Smrg const struct u_prim_vertex_count *info = u_prim_vertex_count(prim); 147848b8605Smrg 148b8e80941Smrg assert(info); 149b8e80941Smrg assert(info->incr != 0); 150b8e80941Smrg 151848b8605Smrg if (num < info->min) 152848b8605Smrg return 0; 153848b8605Smrg 154848b8605Smrg return 1 + ((num - info->min) / info->incr); 155848b8605Smrg} 156848b8605Smrg 157b8e80941Smrgstatic inline boolean 158b8e80941Smrgu_validate_pipe_prim(enum pipe_prim_type pipe_prim, unsigned nr) 159848b8605Smrg{ 160848b8605Smrg const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim); 161848b8605Smrg 162848b8605Smrg return (count && nr >= count->min); 163848b8605Smrg} 164848b8605Smrg 165848b8605Smrg 166b8e80941Smrgstatic inline boolean 167b8e80941Smrgu_trim_pipe_prim(enum pipe_prim_type pipe_prim, unsigned *nr) 168848b8605Smrg{ 169848b8605Smrg const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim); 170848b8605Smrg 171848b8605Smrg if (count && *nr >= count->min) { 172848b8605Smrg if (count->incr > 1) 173848b8605Smrg *nr -= (*nr % count->incr); 174848b8605Smrg return TRUE; 175848b8605Smrg } 176848b8605Smrg else { 177848b8605Smrg *nr = 0; 178848b8605Smrg return FALSE; 179848b8605Smrg } 180848b8605Smrg} 181848b8605Smrg 182b8e80941Smrgstatic inline unsigned 183b8e80941Smrgu_vertices_per_prim(enum pipe_prim_type primitive) 184848b8605Smrg{ 185848b8605Smrg switch(primitive) { 186848b8605Smrg case PIPE_PRIM_POINTS: 187848b8605Smrg return 1; 188848b8605Smrg case PIPE_PRIM_LINES: 189848b8605Smrg case PIPE_PRIM_LINE_LOOP: 190848b8605Smrg case PIPE_PRIM_LINE_STRIP: 191848b8605Smrg return 2; 192848b8605Smrg case PIPE_PRIM_TRIANGLES: 193848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP: 194848b8605Smrg case PIPE_PRIM_TRIANGLE_FAN: 195848b8605Smrg return 3; 196848b8605Smrg case PIPE_PRIM_LINES_ADJACENCY: 197848b8605Smrg case PIPE_PRIM_LINE_STRIP_ADJACENCY: 198848b8605Smrg return 4; 199848b8605Smrg case PIPE_PRIM_TRIANGLES_ADJACENCY: 200848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 201848b8605Smrg return 6; 202848b8605Smrg 203848b8605Smrg /* following primitives should never be used 204848b8605Smrg * with geometry shaders abd their size is 205848b8605Smrg * undefined */ 206848b8605Smrg case PIPE_PRIM_POLYGON: 207848b8605Smrg case PIPE_PRIM_QUADS: 208848b8605Smrg case PIPE_PRIM_QUAD_STRIP: 209848b8605Smrg default: 210848b8605Smrg debug_printf("Unrecognized geometry shader primitive"); 211848b8605Smrg return 3; 212848b8605Smrg } 213848b8605Smrg} 214848b8605Smrg 215848b8605Smrg/** 216848b8605Smrg * Returns the number of decomposed primitives for the given 217848b8605Smrg * vertex count. 218848b8605Smrg * Parts of the pipline are invoked once for each triangle in 219848b8605Smrg * triangle strip, triangle fans and triangles and once 220848b8605Smrg * for each line in line strip, line loop, lines. Also 221848b8605Smrg * statistics depend on knowing the exact number of decomposed 222848b8605Smrg * primitives for a set of vertices. 223848b8605Smrg */ 224b8e80941Smrgstatic inline unsigned 225b8e80941Smrgu_decomposed_prims_for_vertices(enum pipe_prim_type primitive, int vertices) 226848b8605Smrg{ 227848b8605Smrg switch (primitive) { 228848b8605Smrg case PIPE_PRIM_POINTS: 229848b8605Smrg return vertices; 230848b8605Smrg case PIPE_PRIM_LINES: 231848b8605Smrg return vertices / 2; 232848b8605Smrg case PIPE_PRIM_LINE_LOOP: 233848b8605Smrg return (vertices >= 2) ? vertices : 0; 234848b8605Smrg case PIPE_PRIM_LINE_STRIP: 235848b8605Smrg return (vertices >= 2) ? vertices - 1 : 0; 236848b8605Smrg case PIPE_PRIM_TRIANGLES: 237848b8605Smrg return vertices / 3; 238848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP: 239848b8605Smrg return (vertices >= 3) ? vertices - 2 : 0; 240848b8605Smrg case PIPE_PRIM_TRIANGLE_FAN: 241848b8605Smrg return (vertices >= 3) ? vertices - 2 : 0; 242848b8605Smrg case PIPE_PRIM_LINES_ADJACENCY: 243848b8605Smrg return vertices / 4; 244848b8605Smrg case PIPE_PRIM_LINE_STRIP_ADJACENCY: 245848b8605Smrg return (vertices >= 4) ? vertices - 3 : 0; 246848b8605Smrg case PIPE_PRIM_TRIANGLES_ADJACENCY: 247848b8605Smrg return vertices / 6; 248848b8605Smrg case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 249848b8605Smrg return (vertices >= 6) ? 1 + (vertices - 6) / 2 : 0; 250848b8605Smrg case PIPE_PRIM_QUADS: 251848b8605Smrg return vertices / 4; 252848b8605Smrg case PIPE_PRIM_QUAD_STRIP: 253848b8605Smrg return (vertices >= 4) ? (vertices - 2) / 2 : 0; 254848b8605Smrg /* Polygons can't be decomposed 255848b8605Smrg * because the number of their vertices isn't known so 256848b8605Smrg * for them and whatever else we don't recognize just 257848b8605Smrg * return 1 if the number of vertices is greater than 258848b8605Smrg * or equal to 3 and zero otherwise */ 259848b8605Smrg case PIPE_PRIM_POLYGON: 260848b8605Smrg default: 261848b8605Smrg debug_printf("Invalid decomposition primitive!\n"); 262848b8605Smrg return (vertices >= 3) ? 1 : 0; 263848b8605Smrg } 264848b8605Smrg} 265848b8605Smrg 266848b8605Smrg/** 267848b8605Smrg * Returns the number of reduced/tessellated primitives for the given vertex 268848b8605Smrg * count. Each quad is treated as two triangles. Polygons are treated as 269848b8605Smrg * triangle fans. 270848b8605Smrg */ 271b8e80941Smrgstatic inline unsigned 272b8e80941Smrgu_reduced_prims_for_vertices(enum pipe_prim_type primitive, int vertices) 273848b8605Smrg{ 274848b8605Smrg switch (primitive) { 275848b8605Smrg case PIPE_PRIM_QUADS: 276848b8605Smrg case PIPE_PRIM_QUAD_STRIP: 277848b8605Smrg return u_decomposed_prims_for_vertices(primitive, vertices) * 2; 278848b8605Smrg case PIPE_PRIM_POLYGON: 279848b8605Smrg primitive = PIPE_PRIM_TRIANGLE_FAN; 280848b8605Smrg /* fall through */ 281848b8605Smrg default: 282848b8605Smrg return u_decomposed_prims_for_vertices(primitive, vertices); 283848b8605Smrg } 284848b8605Smrg} 285848b8605Smrg 286b8e80941Smrgconst char *u_prim_name(enum pipe_prim_type pipe_prim); 287b8e80941Smrg 288b8e80941Smrg 289b8e80941Smrg#ifdef __cplusplus 290b8e80941Smrg} 291b8e80941Smrg#endif 292b8e80941Smrg 293848b8605Smrg 294848b8605Smrg#endif 295