Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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
  290.