m_clip_tmp.h revision 7117f1b4
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 */ 43static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, 44 GLvector4f *proj_vec, 45 GLubyte clipMask[], 46 GLubyte *orMask, 47 GLubyte *andMask ) 48{ 49 const GLuint stride = clip_vec->stride; 50 const GLfloat *from = (GLfloat *)clip_vec->start; 51 const GLuint count = clip_vec->count; 52 GLuint c = 0; 53 GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; 54 GLubyte tmpAndMask = *andMask; 55 GLubyte tmpOrMask = *orMask; 56 GLuint i; 57 STRIDE_LOOP { 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. */ 64 GLuint mask; 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)) */ 72 GLubyte mask = 0; 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) */ 80 81 clipMask[i] = mask; 82 if (mask) { 83 c++; 84 tmpAndMask &= mask; 85 tmpOrMask |= mask; 86 vProj[i][0] = 0; 87 vProj[i][1] = 0; 88 vProj[i][2] = 0; 89 vProj[i][3] = 1; 90 } else { 91 GLfloat oow = 1.0F / cw; 92 vProj[i][0] = cx * oow; 93 vProj[i][1] = cy * oow; 94 vProj[i][2] = cz * oow; 95 vProj[i][3] = oow; 96 } 97 } 98 99 *orMask = tmpOrMask; 100 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); 101 102 proj_vec->flags |= VEC_SIZE_4; 103 proj_vec->size = 4; 104 proj_vec->count = clip_vec->count; 105 return proj_vec; 106} 107 108 109 110/* 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 117 */ 118static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec, 119 GLvector4f *proj_vec, 120 GLubyte clipMask[], 121 GLubyte *orMask, 122 GLubyte *andMask ) 123{ 124 const GLuint stride = clip_vec->stride; 125 const GLuint count = clip_vec->count; 126 const GLfloat *from = (GLfloat *)clip_vec->start; 127 GLuint c = 0; 128 GLubyte tmpAndMask = *andMask; 129 GLubyte tmpOrMask = *orMask; 130 GLuint i; 131 (void) proj_vec; 132 STRIDE_LOOP { 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. */ 139 GLuint mask; 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)) */ 147 GLubyte mask = 0; 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) */ 155 156 clipMask[i] = mask; 157 if (mask) { 158 c++; 159 tmpAndMask &= mask; 160 tmpOrMask |= mask; 161 } 162 } 163 164 *orMask = tmpOrMask; 165 *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); 166 return clip_vec; 167} 168 169 170static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, 171 GLvector4f *proj_vec, 172 GLubyte clipMask[], 173 GLubyte *orMask, 174 GLubyte *andMask ) 175{ 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; 181 GLuint i; 182 (void) proj_vec; 183 STRIDE_LOOP { 184 const GLfloat cx = from[0], cy = from[1], cz = from[2]; 185 GLubyte mask = 0; 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; 192 clipMask[i] = mask; 193 tmpOrMask |= mask; 194 tmpAndMask &= mask; 195 } 196 197 *orMask = tmpOrMask; 198 *andMask = tmpAndMask; 199 return clip_vec; 200} 201 202 203static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, 204 GLvector4f *proj_vec, 205 GLubyte clipMask[], 206 GLubyte *orMask, 207 GLubyte *andMask ) 208{ 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; 214 GLuint i; 215 (void) proj_vec; 216 STRIDE_LOOP { 217 const GLfloat cx = from[0], cy = from[1]; 218 GLubyte mask = 0; 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; 223 clipMask[i] = mask; 224 tmpOrMask |= mask; 225 tmpAndMask &= mask; 226 } 227 228 *orMask = tmpOrMask; 229 *andMask = tmpAndMask; 230 return clip_vec; 231} 232 233 234static void TAG(init_c_cliptest)( void ) 235{ 236 _mesa_clip_tab[4] = TAG(cliptest_points4); 237 _mesa_clip_tab[3] = TAG(cliptest_points3); 238 _mesa_clip_tab[2] = TAG(cliptest_points2); 239 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); 243} 244