Home | History | Annotate | Download | only in util
      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_BLIT_H
     30 #define U_BLIT_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 static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr )
     41 {
     42    boolean ok = TRUE;
     43 
     44    switch (pipe_prim) {
     45    case PIPE_PRIM_POINTS:
     46       ok = (nr >= 1);
     47       break;
     48    case PIPE_PRIM_LINES:
     49       ok = (nr >= 2);
     50       break;
     51    case PIPE_PRIM_LINE_STRIP:
     52    case PIPE_PRIM_LINE_LOOP:
     53       ok = (nr >= 2);
     54       break;
     55    case PIPE_PRIM_TRIANGLES:
     56       ok = (nr >= 3);
     57       break;
     58    case PIPE_PRIM_TRIANGLE_STRIP:
     59    case PIPE_PRIM_TRIANGLE_FAN:
     60    case PIPE_PRIM_POLYGON:
     61       ok = (nr >= 3);
     62       break;
     63    case PIPE_PRIM_QUADS:
     64       ok = (nr >= 4);
     65       break;
     66    case PIPE_PRIM_QUAD_STRIP:
     67       ok = (nr >= 4);
     68       break;
     69    default:
     70       ok = 0;
     71       break;
     72    }
     73 
     74    return ok;
     75 }
     76 
     77 
     78 static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr )
     79 {
     80    boolean ok = TRUE;
     81    const static unsigned values[][2] = {
     82       { 1, 0 }, /* PIPE_PRIM_POINTS */
     83       { 2, 2 }, /* PIPE_PRIM_LINES */
     84       { 2, 0 }, /* PIPE_PRIM_LINE_LOOP */
     85       { 2, 0 }, /* PIPE_PRIM_LINE_STRIP */
     86       { 3, 3 }, /* PIPE_PRIM_TRIANGLES */
     87       { 3, 0 }, /* PIPE_PRIM_TRIANGLE_STRIP */
     88       { 3, 0 }, /* PIPE_PRIM_TRIANGLE_FAN */
     89       { 4, 4 }, /* PIPE_PRIM_TRIANGLE_QUADS */
     90       { 4, 2 }, /* PIPE_PRIM_TRIANGLE_QUAD_STRIP */
     91       { 3, 0 }, /* PIPE_PRIM_TRIANGLE_POLYGON */
     92       { 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */
     93       { 4, 0 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
     94       { 6, 5 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
     95       { 4, 0 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
     96    };
     97 
     98    if (unlikely(pipe_prim >= PIPE_PRIM_MAX)) {
     99        *nr = 0;
    100        return FALSE;
    101    }
    102 
    103    ok = (*nr >= values[pipe_prim][0]);
    104    if (values[pipe_prim][1])
    105        *nr -= (*nr % values[pipe_prim][1]);
    106 
    107    if (!ok)
    108       *nr = 0;
    109 
    110    return ok;
    111 }
    112 
    113 
    114 static INLINE unsigned u_reduced_prim( unsigned pipe_prim )
    115 {
    116    switch (pipe_prim) {
    117    case PIPE_PRIM_POINTS:
    118       return PIPE_PRIM_POINTS;
    119 
    120    case PIPE_PRIM_LINES:
    121    case PIPE_PRIM_LINE_STRIP:
    122    case PIPE_PRIM_LINE_LOOP:
    123       return PIPE_PRIM_LINES;
    124 
    125    default:
    126       return PIPE_PRIM_TRIANGLES;
    127    }
    128 }
    129 
    130 static INLINE unsigned
    131 u_vertices_per_prim(int primitive)
    132 {
    133    switch(primitive) {
    134    case PIPE_PRIM_POINTS:
    135       return 1;
    136    case PIPE_PRIM_LINES:
    137    case PIPE_PRIM_LINE_LOOP:
    138    case PIPE_PRIM_LINE_STRIP:
    139       return 2;
    140    case PIPE_PRIM_TRIANGLES:
    141    case PIPE_PRIM_TRIANGLE_STRIP:
    142    case PIPE_PRIM_TRIANGLE_FAN:
    143       return 3;
    144    case PIPE_PRIM_LINES_ADJACENCY:
    145    case PIPE_PRIM_LINE_STRIP_ADJACENCY:
    146       return 4;
    147    case PIPE_PRIM_TRIANGLES_ADJACENCY:
    148    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
    149       return 6;
    150 
    151    /* following primitives should never be used
    152     * with geometry shaders abd their size is
    153     * undefined */
    154    case PIPE_PRIM_POLYGON:
    155    case PIPE_PRIM_QUADS:
    156    case PIPE_PRIM_QUAD_STRIP:
    157    default:
    158       debug_printf("Unrecognized geometry shader primitive");
    159       return 3;
    160    }
    161 }
    162 
    163 /**
    164  * Returns the number of decomposed primitives for the given
    165  * vertex count.
    166  * Geometry shader is invoked once for each triangle in
    167  * triangle strip, triangle fans and triangles and once
    168  * for each line in line strip, line loop, lines.
    169  */
    170 static INLINE unsigned
    171 u_gs_prims_for_vertices(int primitive, int vertices)
    172 {
    173    switch(primitive) {
    174    case PIPE_PRIM_POINTS:
    175       return vertices;
    176    case PIPE_PRIM_LINES:
    177       return vertices / 2;
    178    case PIPE_PRIM_LINE_LOOP:
    179       return vertices;
    180    case PIPE_PRIM_LINE_STRIP:
    181       return vertices - 1;
    182    case PIPE_PRIM_TRIANGLES:
    183       return vertices /  3;
    184    case PIPE_PRIM_TRIANGLE_STRIP:
    185       return vertices - 2;
    186    case PIPE_PRIM_TRIANGLE_FAN:
    187       return vertices - 2;
    188    case PIPE_PRIM_LINES_ADJACENCY:
    189       return vertices / 2;
    190    case PIPE_PRIM_LINE_STRIP_ADJACENCY:
    191       return vertices - 1;
    192    case PIPE_PRIM_TRIANGLES_ADJACENCY:
    193       return vertices / 3;
    194    case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
    195       return vertices - 2;
    196 
    197    /* following primitives should never be used
    198     * with geometry shaders abd their size is
    199     * undefined */
    200    case PIPE_PRIM_POLYGON:
    201    case PIPE_PRIM_QUADS:
    202    case PIPE_PRIM_QUAD_STRIP:
    203    default:
    204       debug_printf("Unrecognized geometry shader primitive");
    205       return 3;
    206    }
    207 }
    208 
    209 const char *u_prim_name( unsigned pipe_prim );
    210 
    211 #endif
    212