2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * 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
* TAG(cliptest_points4
)( GLvector4f
*clip_vec
,
48 GLboolean viewport_z_clip
)
50 const GLuint stride
= clip_vec
->stride
;
51 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
52 const GLuint count
= clip_vec
->count
;
54 GLfloat (*vProj
)[4] = (GLfloat (*)[4])proj_vec
->start
;
55 GLubyte tmpAndMask
= *andMask
;
56 GLubyte tmpOrMask
= *orMask
;
59 const GLfloat cx
= from
[0];
60 const GLfloat cy
= from
[1];
61 const GLfloat cz
= from
[2];
62 const GLfloat cw
= from
[3];
63 #if defined(__powerpc__)
64 /* on powerpc cliptest is 17% faster in this way. */
66 mask
= (((cw
< cx
) << CLIP_RIGHT_SHIFT
));
67 mask
|= (((cw
< -cx
) << CLIP_LEFT_SHIFT
));
68 mask
|= (((cw
< cy
) << CLIP_TOP_SHIFT
));
69 mask
|= (((cw
< -cy
) << CLIP_BOTTOM_SHIFT
));
70 if (viewport_z_clip
) {
71 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
72 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
76 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
77 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
78 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
79 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
80 if (viewport_z_clip
) {
81 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
82 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
96 GLfloat oow
= 1.0F
/ cw
;
97 vProj
[i
][0] = cx
* oow
;
98 vProj
[i
][1] = cy
* oow
;
99 vProj
[i
][2] = cz
* oow
;
105 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
107 proj_vec
->flags
|= VEC_SIZE_4
;
109 proj_vec
->count
= clip_vec
->count
;
116 * \param clip_vec vector of incoming clip-space coords
117 * \param proj_vec vector of resultant NDC-space projected coords
118 * \param clipMask resulting array of clip flags
119 * \param orMask bitwise-OR of clipMask values
120 * \param andMask bitwise-AND of clipMask values
121 * \return clip_vec pointer
123 static GLvector4f
* TAG(cliptest_np_points4
)( GLvector4f
*clip_vec
,
124 GLvector4f
*proj_vec
,
128 GLboolean viewport_z_clip
)
130 const GLuint stride
= clip_vec
->stride
;
131 const GLuint count
= clip_vec
->count
;
132 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
134 GLubyte tmpAndMask
= *andMask
;
135 GLubyte tmpOrMask
= *orMask
;
139 const GLfloat cx
= from
[0];
140 const GLfloat cy
= from
[1];
141 const GLfloat cz
= from
[2];
142 const GLfloat cw
= from
[3];
143 #if defined(__powerpc__)
144 /* on powerpc cliptest is 17% faster in this way. */
146 mask
= (((cw
< cx
) << CLIP_RIGHT_SHIFT
));
147 mask
|= (((cw
< -cx
) << CLIP_LEFT_SHIFT
));
148 mask
|= (((cw
< cy
) << CLIP_TOP_SHIFT
));
149 mask
|= (((cw
< -cy
) << CLIP_BOTTOM_SHIFT
));
150 if (viewport_z_clip
) {
151 mask
|= (((cw
< cz
) << CLIP_FAR_SHIFT
));
152 mask
|= (((cw
< -cz
) << CLIP_NEAR_SHIFT
));
156 if (-cx
+ cw
< 0) mask
|= CLIP_RIGHT_BIT
;
157 if ( cx
+ cw
< 0) mask
|= CLIP_LEFT_BIT
;
158 if (-cy
+ cw
< 0) mask
|= CLIP_TOP_BIT
;
159 if ( cy
+ cw
< 0) mask
|= CLIP_BOTTOM_BIT
;
160 if (viewport_z_clip
) {
161 if (-cz
+ cw
< 0) mask
|= CLIP_FAR_BIT
;
162 if ( cz
+ cw
< 0) mask
|= CLIP_NEAR_BIT
;
175 *andMask
= (GLubyte
) (c
< count
? 0 : tmpAndMask
);
180 static GLvector4f
* TAG(cliptest_points3
)( GLvector4f
*clip_vec
,
181 GLvector4f
*proj_vec
,
185 GLboolean viewport_z_clip
)
187 const GLuint stride
= clip_vec
->stride
;
188 const GLuint count
= clip_vec
->count
;
189 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
190 GLubyte tmpOrMask
= *orMask
;
191 GLubyte tmpAndMask
= *andMask
;
195 const GLfloat cx
= from
[0], cy
= from
[1], cz
= from
[2];
197 if (cx
> 1.0F
) mask
|= CLIP_RIGHT_BIT
;
198 else if (cx
< -1.0F
) mask
|= CLIP_LEFT_BIT
;
199 if (cy
> 1.0F
) mask
|= CLIP_TOP_BIT
;
200 else if (cy
< -1.0F
) mask
|= CLIP_BOTTOM_BIT
;
201 if (viewport_z_clip
) {
202 if (cz
> 1.0F
) mask
|= CLIP_FAR_BIT
;
203 else if (cz
< -1.0F
) mask
|= CLIP_NEAR_BIT
;
211 *andMask
= tmpAndMask
;
216 static GLvector4f
* TAG(cliptest_points2
)( GLvector4f
*clip_vec
,
217 GLvector4f
*proj_vec
,
221 GLboolean viewport_z_clip
)
223 const GLuint stride
= clip_vec
->stride
;
224 const GLuint count
= clip_vec
->count
;
225 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
226 GLubyte tmpOrMask
= *orMask
;
227 GLubyte tmpAndMask
= *andMask
;
231 const GLfloat cx
= from
[0], cy
= from
[1];
233 if (cx
> 1.0F
) mask
|= CLIP_RIGHT_BIT
;
234 else if (cx
< -1.0F
) mask
|= CLIP_LEFT_BIT
;
235 if (cy
> 1.0F
) mask
|= CLIP_TOP_BIT
;
236 else if (cy
< -1.0F
) mask
|= CLIP_BOTTOM_BIT
;
243 *andMask
= tmpAndMask
;
248 void TAG(init_c_cliptest
)( void )
250 _mesa_clip_tab
[4] = TAG(cliptest_points4
);
251 _mesa_clip_tab
[3] = TAG(cliptest_points3
);
252 _mesa_clip_tab
[2] = TAG(cliptest_points2
);
254 _mesa_clip_np_tab
[4] = TAG(cliptest_np_points4
);
255 _mesa_clip_np_tab
[3] = TAG(cliptest_points3
);
256 _mesa_clip_np_tab
[2] = TAG(cliptest_points2
);