Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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. static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr )
  140. {
  141.    const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
  142.  
  143.    return (count && nr >= count->min);
  144. }
  145.  
  146.  
  147. static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr )
  148. {
  149.    const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim);
  150.  
  151.    if (count && *nr >= count->min) {
  152.       if (count->incr > 1)
  153.          *nr -= (*nr % count->incr);
  154.       return TRUE;
  155.    }
  156.    else {
  157.       *nr = 0;
  158.       return FALSE;
  159.    }
  160. }
  161.  
  162. static INLINE unsigned
  163. u_vertices_per_prim(int primitive)
  164. {
  165.    switch(primitive) {
  166.    case PIPE_PRIM_POINTS:
  167.       return 1;
  168.    case PIPE_PRIM_LINES:
  169.    case PIPE_PRIM_LINE_LOOP:
  170.    case PIPE_PRIM_LINE_STRIP:
  171.       return 2;
  172.    case PIPE_PRIM_TRIANGLES:
  173.    case PIPE_PRIM_TRIANGLE_STRIP:
  174.    case PIPE_PRIM_TRIANGLE_FAN:
  175.       return 3;
  176.    case PIPE_PRIM_LINES_ADJACENCY:
  177.    case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  178.       return 4;
  179.    case PIPE_PRIM_TRIANGLES_ADJACENCY:
  180.    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  181.       return 6;
  182.  
  183.    /* following primitives should never be used
  184.     * with geometry shaders abd their size is
  185.     * undefined */
  186.    case PIPE_PRIM_POLYGON:
  187.    case PIPE_PRIM_QUADS:
  188.    case PIPE_PRIM_QUAD_STRIP:
  189.    default:
  190.       debug_printf("Unrecognized geometry shader primitive");
  191.       return 3;
  192.    }
  193. }
  194.  
  195. /**
  196.  * Returns the number of decomposed primitives for the given
  197.  * vertex count.
  198.  * Parts of the pipline are invoked once for each triangle in
  199.  * triangle strip, triangle fans and triangles and once
  200.  * for each line in line strip, line loop, lines. Also
  201.  * statistics depend on knowing the exact number of decomposed
  202.  * primitives for a set of vertices.
  203.  */
  204. static INLINE unsigned
  205. u_decomposed_prims_for_vertices(int primitive, int vertices)
  206. {
  207.    switch (primitive) {
  208.    case PIPE_PRIM_POINTS:
  209.       return vertices;
  210.    case PIPE_PRIM_LINES:
  211.       return vertices / 2;
  212.    case PIPE_PRIM_LINE_LOOP:
  213.       return (vertices >= 2) ? vertices : 0;
  214.    case PIPE_PRIM_LINE_STRIP:
  215.       return (vertices >= 2) ? vertices - 1 : 0;
  216.    case PIPE_PRIM_TRIANGLES:
  217.       return vertices / 3;
  218.    case PIPE_PRIM_TRIANGLE_STRIP:
  219.       return (vertices >= 3) ? vertices - 2 : 0;
  220.    case PIPE_PRIM_TRIANGLE_FAN:
  221.       return (vertices >= 3) ? vertices - 2 : 0;
  222.    case PIPE_PRIM_LINES_ADJACENCY:
  223.       return vertices / 4;
  224.    case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  225.       return (vertices >= 4) ? vertices - 3 : 0;
  226.    case PIPE_PRIM_TRIANGLES_ADJACENCY:
  227.       return vertices / 6;
  228.    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  229.       return (vertices >= 6) ? 1 + (vertices - 6) / 2 : 0;
  230.    case PIPE_PRIM_QUADS:
  231.       return vertices / 4;
  232.    case PIPE_PRIM_QUAD_STRIP:
  233.       return (vertices >= 4) ? (vertices - 2) / 2 : 0;
  234.    /* Polygons can't be decomposed
  235.     * because the number of their vertices isn't known so
  236.     * for them and whatever else we don't recognize just
  237.     * return 1 if the number of vertices is greater than
  238.     * or equal to 3 and zero otherwise */
  239.    case PIPE_PRIM_POLYGON:
  240.    default:
  241.       debug_printf("Invalid decomposition primitive!\n");
  242.       return (vertices >= 3) ? 1 : 0;
  243.    }
  244. }
  245.  
  246. /**
  247.  * Returns the number of reduced/tessellated primitives for the given vertex
  248.  * count.  Each quad is treated as two triangles.  Polygons are treated as
  249.  * triangle fans.
  250.  */
  251. static INLINE unsigned
  252. u_reduced_prims_for_vertices(int primitive, int vertices)
  253. {
  254.    switch (primitive) {
  255.    case PIPE_PRIM_QUADS:
  256.    case PIPE_PRIM_QUAD_STRIP:
  257.       return u_decomposed_prims_for_vertices(primitive, vertices) * 2;
  258.    case PIPE_PRIM_POLYGON:
  259.       primitive = PIPE_PRIM_TRIANGLE_FAN;
  260.       /* fall through */
  261.    default:
  262.       return u_decomposed_prims_for_vertices(primitive, vertices);
  263.    }
  264. }
  265.  
  266. const char *u_prim_name( unsigned pipe_prim );
  267.  
  268. #endif
  269.