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 
u_validate_pipe_prim(unsigned pipe_prim,unsigned nr)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 
u_trim_pipe_prim(unsigned pipe_prim,unsigned * nr)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 
u_reduced_prim(unsigned pipe_prim)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
u_vertices_per_prim(int primitive)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
u_gs_prims_for_vertices(int primitive,int vertices)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