Fixed MAXFIFO_S4. Removed WAIT_IDLE_EMPTY from savage_BCI_swap which resulted
[mesa.git] / src / mesa / tnl / t_vb_cliptmp.h
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.5
5 *
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions 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 MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29
30 #define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D
31
32 #define POLY_CLIP( PLANE, A, B, C, D ) \
33 do { \
34 if (mask & PLANE) { \
35 GLuint idxPrev = inlist[0]; \
36 GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \
37 GLuint outcount = 0; \
38 GLuint i; \
39 \
40 inlist[n] = inlist[0]; /* prevent rotation of vertices */ \
41 for (i = 1; i <= n; i++) { \
42 GLuint idx = inlist[i]; \
43 GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \
44 \
45 clipmask[idxPrev] |= PLANE; \
46 if (!IS_NEGATIVE(dpPrev)) { \
47 outlist[outcount++] = idxPrev; \
48 clipmask[idxPrev] &= ~PLANE; \
49 } \
50 \
51 if (DIFFERENT_SIGNS(dp, dpPrev)) { \
52 GLuint newvert = VB->LastClipped++; \
53 VB->ClipMask[newvert] = 0; \
54 outlist[outcount++] = newvert; \
55 if (IS_NEGATIVE(dp)) { \
56 /* Going out of bounds. Avoid division by zero as we \
57 * know dp != dpPrev from DIFFERENT_SIGNS, above. \
58 */ \
59 GLfloat t = dp / (dp - dpPrev); \
60 INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \
61 interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \
62 } else { \
63 /* Coming back in. \
64 */ \
65 GLfloat t = dpPrev / (dpPrev - dp); \
66 INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \
67 interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \
68 } \
69 } \
70 \
71 idxPrev = idx; \
72 dpPrev = dp; \
73 } \
74 \
75 if (outcount < 3) \
76 return; \
77 \
78 { \
79 GLuint *tmp = inlist; \
80 inlist = outlist; \
81 outlist = tmp; \
82 n = outcount; \
83 } \
84 } \
85 } while (0)
86
87
88 #define LINE_CLIP(PLANE, A, B, C, D ) \
89 do { \
90 if (mask & PLANE) { \
91 GLfloat dpI = CLIP_DOTPROD( ii, A, B, C, D ); \
92 GLfloat dpJ = CLIP_DOTPROD( jj, A, B, C, D ); \
93 \
94 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
95 GLuint newvert = VB->LastClipped++; \
96 VB->ClipMask[newvert] = 0; \
97 if (IS_NEGATIVE(dpJ)) { \
98 GLfloat t = dpI / (dpI - dpJ); \
99 VB->ClipMask[jj] |= PLANE; \
100 INTERP_4F( t, coord[newvert], coord[ii], coord[jj] ); \
101 interp( ctx, t, newvert, ii, jj, GL_FALSE ); \
102 jj = newvert; \
103 } else { \
104 GLfloat t = dpJ / (dpJ - dpI); \
105 VB->ClipMask[ii] |= PLANE; \
106 INTERP_4F( t, coord[newvert], coord[jj], coord[ii] ); \
107 interp( ctx, t, newvert, jj, ii, GL_FALSE ); \
108 ii = newvert; \
109 } \
110 } \
111 else if (IS_NEGATIVE(dpI)) \
112 return; \
113 } \
114 } while (0)
115
116
117
118 /* Clip a line against the viewport and user clip planes.
119 */
120 static INLINE void
121 TAG(clip_line)( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask )
122 {
123 TNLcontext *tnl = TNL_CONTEXT(ctx);
124 struct vertex_buffer *VB = &tnl->vb;
125 interp_func interp = tnl->Driver.Render.Interp;
126 GLfloat (*coord)[4] = VB->ClipPtr->data;
127 GLuint ii = i, jj = j, p;
128
129 VB->LastClipped = VB->Count;
130
131 if (mask & 0x3f) {
132 LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
133 LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
134 LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
135 LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
136 LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
137 LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
138 }
139
140 if (mask & CLIP_USER_BIT) {
141 for (p=0;p<MAX_CLIP_PLANES;p++) {
142 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
143 const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
144 const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
145 const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
146 const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
147 LINE_CLIP( CLIP_USER_BIT, a, b, c, d );
148 }
149 }
150 }
151
152 if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
153 tnl->Driver.Render.CopyPV( ctx, jj, j );
154
155 tnl->Driver.Render.ClippedLine( ctx, ii, jj );
156 }
157
158
159 /* Clip a triangle against the viewport and user clip planes.
160 */
161 static INLINE void
162 TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask )
163 {
164 TNLcontext *tnl = TNL_CONTEXT(ctx);
165 struct vertex_buffer *VB = &tnl->vb;
166 interp_func interp = tnl->Driver.Render.Interp;
167 GLfloat (*coord)[4] = VB->ClipPtr->data;
168 GLuint pv = v2;
169 GLuint vlist[2][MAX_CLIPPED_VERTICES];
170 GLuint *inlist = vlist[0], *outlist = vlist[1];
171 GLuint p;
172 GLubyte *clipmask = VB->ClipMask;
173 GLuint n = 3;
174
175 ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */
176
177 VB->LastClipped = VB->Count;
178
179 if (mask & 0x3f) {
180 POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
181 POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
182 POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
183 POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
184 POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
185 POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
186 }
187
188 if (mask & CLIP_USER_BIT) {
189 for (p=0;p<MAX_CLIP_PLANES;p++) {
190 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
191 const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
192 const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
193 const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
194 const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
195 POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
196 }
197 }
198 }
199
200 if (ctx->_TriangleCaps & DD_FLATSHADE) {
201 if (pv != inlist[0]) {
202 ASSERT( inlist[0] >= VB->Count );
203 tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
204 }
205 }
206
207 tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
208 }
209
210
211 /* Clip a quad against the viewport and user clip planes.
212 */
213 static INLINE void
214 TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
215 GLubyte mask )
216 {
217 TNLcontext *tnl = TNL_CONTEXT(ctx);
218 struct vertex_buffer *VB = &tnl->vb;
219 interp_func interp = tnl->Driver.Render.Interp;
220 GLfloat (*coord)[4] = VB->ClipPtr->data;
221 GLuint pv = v3;
222 GLuint vlist[2][MAX_CLIPPED_VERTICES];
223 GLuint *inlist = vlist[0], *outlist = vlist[1];
224 GLuint p;
225 GLubyte *clipmask = VB->ClipMask;
226 GLuint n = 4;
227
228 ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */
229
230 VB->LastClipped = VB->Count;
231
232 if (mask & 0x3f) {
233 POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
234 POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 );
235 POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 );
236 POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 );
237 POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 );
238 POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 );
239 }
240
241 if (mask & CLIP_USER_BIT) {
242 for (p=0;p<MAX_CLIP_PLANES;p++) {
243 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
244 const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
245 const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
246 const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
247 const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
248 POLY_CLIP( CLIP_USER_BIT, a, b, c, d );
249 }
250 }
251 }
252
253 if (ctx->_TriangleCaps & DD_FLATSHADE) {
254 if (pv != inlist[0]) {
255 ASSERT( inlist[0] >= VB->Count );
256 tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
257 }
258 }
259
260 tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
261 }
262
263 #undef W
264 #undef Z
265 #undef Y
266 #undef X
267 #undef SIZE
268 #undef TAG
269 #undef POLY_CLIP
270 #undef LINE_CLIP