1 /* 2 * Mesa 3-D graphics library 3 * Version: 6.2 4 * 5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 6 * 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: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 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. 23 */ 24 25 /* 26 * New (3.1) transformation code written by Keith Whitwell. 27 */ 28 29 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. 35 * 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 42 */ 43 static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, 44 GLvector4f *proj_vec, 45 GLubyte clipMask[], 46 GLubyte *orMask, 47 GLubyte *andMask, 48 GLboolean viewport_z_clip ) 49 { 50 const GLuint stride = clip_vec->stride; 51 const GLfloat *from = (GLfloat *)clip_vec->start; 52 const GLuint count = clip_vec->count; 53 GLuint c = 0; 54 GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; 55 GLubyte tmpAndMask = *andMask; 56 GLubyte tmpOrMask = *orMask; 57 GLuint i; 58 STRIDE_LOOP { 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(macintosh) || defined(__powerpc__) 64 /* on powerpc cliptest is 17% faster in this way. */ 65 GLuint mask; 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)); 73 } 74 #else /* !defined(macintosh)) */ 75 GLubyte mask = 0; 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; 83 } 84 #endif /* defined(macintosh) */ 85 86 clipMask[i] = mask; 87 if (mask) { 88 c++; 89 tmpAndMask &= mask; 90 tmpOrMask |= mask; 91 vProj[i][0] = 0; 92 vProj[i][1] = 0; 93 vProj[i][2] = 0; 94 vProj[i][3] = 1; 95 } else { 96 GLfloat oow = 1.0F / cw; 97 vProj[i][0] = cx * oow; 98 vProj[i][1] = cy * oow; 99 vProj[i][2] = cz * oow; 100 vProj[i][3] = oow; 101 } 102 } 103 104 *orMask = tmpOrMask; 105 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); 106 107 proj_vec->flags |= VEC_SIZE_4; 108 proj_vec->size = 4; 109 proj_vec->count = clip_vec->count; 110 return proj_vec; 111 } 112 113 114 115 /* 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 122 */ 123 static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec, 124 GLvector4f *proj_vec, 125 GLubyte clipMask[], 126 GLubyte *orMask, 127 GLubyte *andMask, 128 GLboolean viewport_z_clip ) 129 { 130 const GLuint stride = clip_vec->stride; 131 const GLuint count = clip_vec->count; 132 const GLfloat *from = (GLfloat *)clip_vec->start; 133 GLuint c = 0; 134 GLubyte tmpAndMask = *andMask; 135 GLubyte tmpOrMask = *orMask; 136 GLuint i; 137 (void) proj_vec; 138 STRIDE_LOOP { 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(macintosh) || defined(__powerpc__) 144 /* on powerpc cliptest is 17% faster in this way. */ 145 GLuint mask; 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)); 153 } 154 #else /* !defined(macintosh)) */ 155 GLubyte mask = 0; 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; 163 } 164 #endif /* defined(macintosh) */ 165 166 clipMask[i] = mask; 167 if (mask) { 168 c++; 169 tmpAndMask &= mask; 170 tmpOrMask |= mask; 171 } 172 } 173 174 *orMask = tmpOrMask; 175 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); 176 return clip_vec; 177 } 178 179 180 static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, 181 GLvector4f *proj_vec, 182 GLubyte clipMask[], 183 GLubyte *orMask, 184 GLubyte *andMask, 185 GLboolean viewport_z_clip ) 186 { 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; 192 GLuint i; 193 (void) proj_vec; 194 STRIDE_LOOP { 195 const GLfloat cx = from[0], cy = from[1], cz = from[2]; 196 GLubyte mask = 0; 197 if (cx > 1.0) mask |= CLIP_RIGHT_BIT; 198 else if (cx < -1.0) mask |= CLIP_LEFT_BIT; 199 if (cy > 1.0) mask |= CLIP_TOP_BIT; 200 else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; 201 if (viewport_z_clip) { 202 if (cz > 1.0) mask |= CLIP_FAR_BIT; 203 else if (cz < -1.0) mask |= CLIP_NEAR_BIT; 204 } 205 clipMask[i] = mask; 206 tmpOrMask |= mask; 207 tmpAndMask &= mask; 208 } 209 210 *orMask = tmpOrMask; 211 *andMask = tmpAndMask; 212 return clip_vec; 213 } 214 215 216 static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, 217 GLvector4f *proj_vec, 218 GLubyte clipMask[], 219 GLubyte *orMask, 220 GLubyte *andMask, 221 GLboolean viewport_z_clip ) 222 { 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; 228 GLuint i; 229 (void) proj_vec; 230 STRIDE_LOOP { 231 const GLfloat cx = from[0], cy = from[1]; 232 GLubyte mask = 0; 233 if (cx > 1.0) mask |= CLIP_RIGHT_BIT; 234 else if (cx < -1.0) mask |= CLIP_LEFT_BIT; 235 if (cy > 1.0) mask |= CLIP_TOP_BIT; 236 else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; 237 clipMask[i] = mask; 238 tmpOrMask |= mask; 239 tmpAndMask &= mask; 240 } 241 242 *orMask = tmpOrMask; 243 *andMask = tmpAndMask; 244 return clip_vec; 245 } 246 247 248 void TAG(init_c_cliptest)( void ) 249 { 250 _mesa_clip_tab[4] = TAG(cliptest_points4); 251 _mesa_clip_tab[3] = TAG(cliptest_points3); 252 _mesa_clip_tab[2] = TAG(cliptest_points2); 253 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); 257 } 258