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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
27 * New (3.1) transformation code written by Keith Whitwell.
31 /* KW: a clever asm implementation would nestle integer versions
32 * of the outcode calculation underneath the division. Gcc won't
33 * do this, strangely enough, so I only do the divide in
34 * the case where the cliptest passes. This isn't essential,
35 * and an asm implementation needn't replicate that behaviour.
37 * \param clip_vec vector of incoming clip-space coords
38 * \param proj_vec vector of resultant NDC-space projected coords
39 * \param clipMask resulting array of clip flags
40 * \param orMask bitwise-OR of clipMask values
41 * \param andMask bitwise-AND of clipMask values
42 * \return proj_vec pointer
44 static GLvector4f
* _XFORMAPI
TAG(cliptest_points4
)( GLvector4f
*clip_vec
,
49 GLboolean viewport_z_clip
)
51 const GLuint stride
= clip_vec
->stride
;
52 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
53 const GLuint count
= clip_vec
->count
;
55 GLfloat (*vProj
)[4] = (GLfloat (*)[4])proj_vec
->start
;
56 GLubyte tmpAndMask
= *andMask
;
57 GLubyte tmpOrMask
= *orMask
;
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. */
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 if (viewport_z_clip
) {
72 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
73 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
75 #else /* !defined(macintosh)) */
77 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
78 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
79 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
80 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
81 if (viewport_z_clip
) {
82 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
83 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
85 #endif /* defined(macintosh) */
97 GLfloat oow
= 1.0F
/ cw
;
98 vProj
[i
][0] = cx
* oow
;
99 vProj
[i
][1] = cy
* oow
;
100 vProj
[i
][2] = cz
* oow
;
106 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
108 proj_vec
->flags
|= VEC_SIZE_4
;
110 proj_vec
->count
= clip_vec
->count
;
117 * \param clip_vec vector of incoming clip-space coords
118 * \param proj_vec vector of resultant NDC-space projected coords
119 * \param clipMask resulting array of clip flags
120 * \param orMask bitwise-OR of clipMask values
121 * \param andMask bitwise-AND of clipMask values
122 * \return clip_vec pointer
124 static GLvector4f
* _XFORMAPI
TAG(cliptest_np_points4
)( GLvector4f
*clip_vec
,
125 GLvector4f
*proj_vec
,
129 GLboolean viewport_z_clip
)
131 const GLuint stride
= clip_vec
->stride
;
132 const GLuint count
= clip_vec
->count
;
133 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
135 GLubyte tmpAndMask
= *andMask
;
136 GLubyte tmpOrMask
= *orMask
;
140 const GLfloat cx
= from
[0];
141 const GLfloat cy
= from
[1];
142 const GLfloat cz
= from
[2];
143 const GLfloat cw
= from
[3];
144 #if defined(macintosh) || defined(__powerpc__)
145 /* on powerpc cliptest is 17% faster in this way. */
147 mask
= (((cw
< cx
) << CLIP_RIGHT_SHIFT
));
148 mask
|= (((cw
< -cx
) << CLIP_LEFT_SHIFT
));
149 mask
|= (((cw
< cy
) << CLIP_TOP_SHIFT
));
150 mask
|= (((cw
< -cy
) << CLIP_BOTTOM_SHIFT
));
151 if (viewport_z_clip
) {
152 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
153 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
155 #else /* !defined(macintosh)) */
157 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
158 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
159 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
160 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
161 if (viewport_z_clip
) {
162 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
163 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
165 #endif /* defined(macintosh) */
176 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
181 static GLvector4f
* _XFORMAPI
TAG(cliptest_points3
)( GLvector4f
*clip_vec
,
182 GLvector4f
*proj_vec
,
186 GLboolean viewport_z_clip
)
188 const GLuint stride
= clip_vec
->stride
;
189 const GLuint count
= clip_vec
->count
;
190 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
191 GLubyte tmpOrMask
= *orMask
;
192 GLubyte tmpAndMask
= *andMask
;
196 const GLfloat cx
= from
[0], cy
= from
[1], cz
= from
[2];
198 if (cx
> 1.0) mask
|= CLIP_RIGHT_BIT
;
199 else if (cx
< -1.0) mask
|= CLIP_LEFT_BIT
;
200 if (cy
> 1.0) mask
|= CLIP_TOP_BIT
;
201 else if (cy
< -1.0) mask
|= CLIP_BOTTOM_BIT
;
202 if (viewport_z_clip
) {
203 if (cz
> 1.0) mask
|= CLIP_FAR_BIT
;
204 else if (cz
< -1.0) mask
|= CLIP_NEAR_BIT
;
212 *andMask
= tmpAndMask
;
217 static GLvector4f
* _XFORMAPI
TAG(cliptest_points2
)( GLvector4f
*clip_vec
,
218 GLvector4f
*proj_vec
,
222 GLboolean viewport_z_clip
)
224 const GLuint stride
= clip_vec
->stride
;
225 const GLuint count
= clip_vec
->count
;
226 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
227 GLubyte tmpOrMask
= *orMask
;
228 GLubyte tmpAndMask
= *andMask
;
232 const GLfloat cx
= from
[0], cy
= from
[1];
234 if (cx
> 1.0) mask
|= CLIP_RIGHT_BIT
;
235 else if (cx
< -1.0) mask
|= CLIP_LEFT_BIT
;
236 if (cy
> 1.0) mask
|= CLIP_TOP_BIT
;
237 else if (cy
< -1.0) mask
|= CLIP_BOTTOM_BIT
;
244 *andMask
= tmpAndMask
;
249 void TAG(init_c_cliptest
)( void )
251 _mesa_clip_tab
[4] = TAG(cliptest_points4
);
252 _mesa_clip_tab
[3] = TAG(cliptest_points3
);
253 _mesa_clip_tab
[2] = TAG(cliptest_points2
);
255 _mesa_clip_np_tab
[4] = TAG(cliptest_np_points4
);
256 _mesa_clip_np_tab
[3] = TAG(cliptest_points3
);
257 _mesa_clip_np_tab
[2] = TAG(cliptest_points2
);