Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.