5a8bd0d0b848a1eeedca4d40fda5747742454095
[mesa.git] / src / mesa / math / m_clip_tmp.h
1 /* $Id: m_clip_tmp.h,v 1.9 2003/03/19 05:33:09 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 5.1
6 *
7 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /*
28 * New (3.1) transformation code written by Keith Whitwell.
29 */
30
31
32 /* KW: a clever asm implementation would nestle integer versions
33 * of the outcode calculation underneath the division. Gcc won't
34 * do this, strangely enough, so I only do the divide in
35 * the case where the cliptest passes. This isn't essential,
36 * and an asm implementation needn't replicate that behaviour.
37 *
38 * \param clip_vec vector of incoming clip-space coords
39 * \param proj_vec vector of resultant NDC-space projected coords
40 * \param clipMask resulting array of clip flags
41 * \param orMask bitwise-OR of clipMask values
42 * \param andMask bitwise-AND of clipMask values
43 * \return proj_vec pointer
44 */
45 static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec,
46 GLvector4f *proj_vec,
47 GLubyte clipMask[],
48 GLubyte *orMask,
49 GLubyte *andMask )
50 {
51 const GLuint stride = clip_vec->stride;
52 const GLfloat *from = (GLfloat *)clip_vec->start;
53 const GLuint count = clip_vec->count;
54 GLuint c = 0;
55 GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
56 GLubyte tmpAndMask = *andMask;
57 GLubyte tmpOrMask = *orMask;
58 GLuint i;
59 STRIDE_LOOP {
60 const GLfloat cx = from[0];
61 const GLfloat cy = from[1];
62 const GLfloat cz = from[2];
63 const GLfloat cw = from[3];
64 #if defined(macintosh) || defined(__powerpc__)
65 /* on powerpc cliptest is 17% faster in this way. */
66 GLuint mask;
67 mask = (((cw < cx) << CLIP_RIGHT_SHIFT));
68 mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
69 mask |= (((cw < cy) << CLIP_TOP_SHIFT));
70 mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
71 mask |= (((cw < cz) << CLIP_FAR_SHIFT));
72 mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
73 #else /* !defined(macintosh)) */
74 GLubyte mask = 0;
75 if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
76 if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
77 if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
78 if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
79 if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
80 if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
81 #endif /* defined(macintosh) */
82
83 clipMask[i] = mask;
84 if (mask) {
85 c++;
86 tmpAndMask &= mask;
87 tmpOrMask |= mask;
88 vProj[i][0] = 0;
89 vProj[i][1] = 0;
90 vProj[i][2] = 0;
91 vProj[i][3] = 1;
92 } else {
93 GLfloat oow = 1.0F / cw;
94 vProj[i][0] = cx * oow;
95 vProj[i][1] = cy * oow;
96 vProj[i][2] = cz * oow;
97 vProj[i][3] = oow;
98 }
99 }
100
101 *orMask = tmpOrMask;
102 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask);
103
104 proj_vec->flags |= VEC_SIZE_4;
105 proj_vec->size = 4;
106 proj_vec->count = clip_vec->count;
107 return proj_vec;
108 }
109
110
111
112 /*
113 * \param clip_vec vector of incoming clip-space coords
114 * \param proj_vec vector of resultant NDC-space projected coords
115 * \param clipMask resulting array of clip flags
116 * \param orMask bitwise-OR of clipMask values
117 * \param andMask bitwise-AND of clipMask values
118 * \return clip_vec pointer
119 */
120 static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec,
121 GLvector4f *proj_vec,
122 GLubyte clipMask[],
123 GLubyte *orMask,
124 GLubyte *andMask )
125 {
126 const GLuint stride = clip_vec->stride;
127 const GLuint count = clip_vec->count;
128 const GLfloat *from = (GLfloat *)clip_vec->start;
129 GLuint c = 0;
130 GLubyte tmpAndMask = *andMask;
131 GLubyte tmpOrMask = *orMask;
132 GLuint i;
133 STRIDE_LOOP {
134 const GLfloat cx = from[0];
135 const GLfloat cy = from[1];
136 const GLfloat cz = from[2];
137 const GLfloat cw = from[3];
138 #if defined(macintosh) || defined(__powerpc__)
139 /* on powerpc cliptest is 17% faster in this way. */
140 GLuint mask;
141 mask = (((cw < cx) << CLIP_RIGHT_SHIFT));
142 mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
143 mask |= (((cw < cy) << CLIP_TOP_SHIFT));
144 mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
145 mask |= (((cw < cz) << CLIP_FAR_SHIFT));
146 mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
147 #else /* !defined(macintosh)) */
148 GLubyte mask = 0;
149 if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
150 if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
151 if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
152 if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
153 if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
154 if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
155 #endif /* defined(macintosh) */
156
157 clipMask[i] = mask;
158 if (mask) {
159 c++;
160 tmpAndMask &= mask;
161 tmpOrMask |= mask;
162 }
163 }
164
165 *orMask = tmpOrMask;
166 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask);
167 return clip_vec;
168 }
169
170
171 static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec,
172 GLvector4f *proj_vec,
173 GLubyte clipMask[],
174 GLubyte *orMask,
175 GLubyte *andMask )
176 {
177 const GLuint stride = clip_vec->stride;
178 const GLuint count = clip_vec->count;
179 const GLfloat *from = (GLfloat *)clip_vec->start;
180
181 GLubyte tmpOrMask = *orMask;
182 GLubyte tmpAndMask = *andMask;
183 GLuint i;
184 STRIDE_LOOP {
185 const GLfloat cx = from[0], cy = from[1], cz = from[2];
186 GLubyte mask = 0;
187 if (cx > 1.0) mask |= CLIP_RIGHT_BIT;
188 else if (cx < -1.0) mask |= CLIP_LEFT_BIT;
189 if (cy > 1.0) mask |= CLIP_TOP_BIT;
190 else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT;
191 if (cz > 1.0) mask |= CLIP_FAR_BIT;
192 else if (cz < -1.0) mask |= CLIP_NEAR_BIT;
193 clipMask[i] = mask;
194 tmpOrMask |= mask;
195 tmpAndMask &= mask;
196 }
197
198 *orMask = tmpOrMask;
199 *andMask = tmpAndMask;
200 return clip_vec;
201 }
202
203
204 static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec,
205 GLvector4f *proj_vec,
206 GLubyte clipMask[],
207 GLubyte *orMask,
208 GLubyte *andMask )
209 {
210 const GLuint stride = clip_vec->stride;
211 const GLuint count = clip_vec->count;
212 const GLfloat *from = (GLfloat *)clip_vec->start;
213
214 GLubyte tmpOrMask = *orMask;
215 GLubyte tmpAndMask = *andMask;
216 GLuint i;
217 STRIDE_LOOP {
218 const GLfloat cx = from[0], cy = from[1];
219 GLubyte mask = 0;
220 if (cx > 1.0) mask |= CLIP_RIGHT_BIT;
221 else if (cx < -1.0) mask |= CLIP_LEFT_BIT;
222 if (cy > 1.0) mask |= CLIP_TOP_BIT;
223 else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT;
224 clipMask[i] = mask;
225 tmpOrMask |= mask;
226 tmpAndMask &= mask;
227 }
228
229 *orMask = tmpOrMask;
230 *andMask = tmpAndMask;
231 return clip_vec;
232 }
233
234
235 static void TAG(init_c_cliptest)( void )
236 {
237 _mesa_clip_tab[4] = TAG(cliptest_points4);
238 _mesa_clip_tab[3] = TAG(cliptest_points3);
239 _mesa_clip_tab[2] = TAG(cliptest_points2);
240
241 _mesa_clip_np_tab[4] = TAG(cliptest_np_points4);
242 _mesa_clip_np_tab[3] = TAG(cliptest_points3);
243 _mesa_clip_np_tab[2] = TAG(cliptest_points2);
244 }