2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * New (3.1) transformation code written by Keith Whitwell.
30 /* KW: a clever asm implementation would nestle integer versions
31 * of the outcode calculation underneath the division. Gcc won't
32 * do this, strangely enough, so I only do the divide in
33 * the case where the cliptest passes. This isn't essential,
34 * and an asm implementation needn't replicate that behaviour.
36 * \param clip_vec vector of incoming clip-space coords
37 * \param proj_vec vector of resultant NDC-space projected coords
38 * \param clipMask resulting array of clip flags
39 * \param orMask bitwise-OR of clipMask values
40 * \param andMask bitwise-AND of clipMask values
41 * \return proj_vec pointer
43 static GLvector4f
* _XFORMAPI
TAG(cliptest_points4
)( GLvector4f
*clip_vec
,
49 const GLuint stride
= clip_vec
->stride
;
50 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
51 const GLuint count
= clip_vec
->count
;
53 GLfloat (*vProj
)[4] = (GLfloat (*)[4])proj_vec
->start
;
54 GLubyte tmpAndMask
= *andMask
;
55 GLubyte tmpOrMask
= *orMask
;
58 const GLfloat cx
= from
[0];
59 const GLfloat cy
= from
[1];
60 const GLfloat cz
= from
[2];
61 const GLfloat cw
= from
[3];
62 #if defined(macintosh) || defined(__powerpc__)
63 /* on powerpc cliptest is 17% faster in this way. */
65 mask
= (((cw
< cx
) << CLIP_RIGHT_SHIFT
));
66 mask
|= (((cw
< -cx
) << CLIP_LEFT_SHIFT
));
67 mask
|= (((cw
< cy
) << CLIP_TOP_SHIFT
));
68 mask
|= (((cw
< -cy
) << CLIP_BOTTOM_SHIFT
));
69 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
70 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
71 #else /* !defined(macintosh)) */
73 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
74 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
75 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
76 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
77 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
78 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
79 #endif /* defined(macintosh) */
91 GLfloat oow
= 1.0F
/ cw
;
92 vProj
[i
][0] = cx
* oow
;
93 vProj
[i
][1] = cy
* oow
;
94 vProj
[i
][2] = cz
* oow
;
100 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
102 proj_vec
->flags
|= VEC_SIZE_4
;
104 proj_vec
->count
= clip_vec
->count
;
111 * \param clip_vec vector of incoming clip-space coords
112 * \param proj_vec vector of resultant NDC-space projected coords
113 * \param clipMask resulting array of clip flags
114 * \param orMask bitwise-OR of clipMask values
115 * \param andMask bitwise-AND of clipMask values
116 * \return clip_vec pointer
118 static GLvector4f
* _XFORMAPI
TAG(cliptest_np_points4
)( GLvector4f
*clip_vec
,
119 GLvector4f
*proj_vec
,
124 const GLuint stride
= clip_vec
->stride
;
125 const GLuint count
= clip_vec
->count
;
126 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
128 GLubyte tmpAndMask
= *andMask
;
129 GLubyte tmpOrMask
= *orMask
;
133 const GLfloat cx
= from
[0];
134 const GLfloat cy
= from
[1];
135 const GLfloat cz
= from
[2];
136 const GLfloat cw
= from
[3];
137 #if defined(macintosh) || defined(__powerpc__)
138 /* on powerpc cliptest is 17% faster in this way. */
140 mask
= (((cw
< cx
) << CLIP_RIGHT_SHIFT
));
141 mask
|= (((cw
< -cx
) << CLIP_LEFT_SHIFT
));
142 mask
|= (((cw
< cy
) << CLIP_TOP_SHIFT
));
143 mask
|= (((cw
< -cy
) << CLIP_BOTTOM_SHIFT
));
144 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
145 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
146 #else /* !defined(macintosh)) */
148 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
149 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
150 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
151 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
152 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
153 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
154 #endif /* defined(macintosh) */
165 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
170 static GLvector4f
* _XFORMAPI
TAG(cliptest_points3
)( GLvector4f
*clip_vec
,
171 GLvector4f
*proj_vec
,
176 const GLuint stride
= clip_vec
->stride
;
177 const GLuint count
= clip_vec
->count
;
178 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
179 GLubyte tmpOrMask
= *orMask
;
180 GLubyte tmpAndMask
= *andMask
;
184 const GLfloat cx
= from
[0], cy
= from
[1], cz
= from
[2];
186 if (cx
> 1.0) mask
|= CLIP_RIGHT_BIT
;
187 else if (cx
< -1.0) mask
|= CLIP_LEFT_BIT
;
188 if (cy
> 1.0) mask
|= CLIP_TOP_BIT
;
189 else if (cy
< -1.0) mask
|= CLIP_BOTTOM_BIT
;
190 if (cz
> 1.0) mask
|= CLIP_FAR_BIT
;
191 else if (cz
< -1.0) mask
|= CLIP_NEAR_BIT
;
198 *andMask
= tmpAndMask
;
203 static GLvector4f
* _XFORMAPI
TAG(cliptest_points2
)( GLvector4f
*clip_vec
,
204 GLvector4f
*proj_vec
,
209 const GLuint stride
= clip_vec
->stride
;
210 const GLuint count
= clip_vec
->count
;
211 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
212 GLubyte tmpOrMask
= *orMask
;
213 GLubyte tmpAndMask
= *andMask
;
217 const GLfloat cx
= from
[0], cy
= from
[1];
219 if (cx
> 1.0) mask
|= CLIP_RIGHT_BIT
;
220 else if (cx
< -1.0) mask
|= CLIP_LEFT_BIT
;
221 if (cy
> 1.0) mask
|= CLIP_TOP_BIT
;
222 else if (cy
< -1.0) mask
|= CLIP_BOTTOM_BIT
;
229 *andMask
= tmpAndMask
;
234 static void TAG(init_c_cliptest
)( void )
236 _mesa_clip_tab
[4] = TAG(cliptest_points4
);
237 _mesa_clip_tab
[3] = TAG(cliptest_points3
);
238 _mesa_clip_tab
[2] = TAG(cliptest_points2
);
240 _mesa_clip_np_tab
[4] = TAG(cliptest_np_points4
);
241 _mesa_clip_np_tab
[3] = TAG(cliptest_points3
);
242 _mesa_clip_np_tab
[2] = TAG(cliptest_points2
);