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.5
  4.  *
  5.  * Copyright (C) 1999-2006  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.  * Authors:
  25.  *    Keith Whitwell <keith@tungstengraphics.com>
  26.  */
  27.  
  28.  
  29. #include "main/glheader.h"
  30. #include "main/colormac.h"
  31. #include "main/macros.h"
  32. #include "main/imports.h"
  33. #include "main/mtypes.h"
  34.  
  35. #include "math/m_xform.h"
  36.  
  37. #include "t_context.h"
  38. #include "t_pipeline.h"
  39.  
  40.  
  41.  
  42. struct vertex_stage_data {
  43.    GLvector4f eye;
  44.    GLvector4f clip;
  45.    GLvector4f proj;
  46.    GLubyte *clipmask;
  47.    GLubyte ormask;
  48.    GLubyte andmask;
  49. };
  50.  
  51. #define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
  52.  
  53.  
  54.  
  55.  
  56. /* This function implements cliptesting for user-defined clip planes.
  57.  * The clipping of primitives to these planes is implemented in
  58.  * t_render_clip.h.
  59.  */
  60. #define USER_CLIPTEST(NAME, SZ)                                 \
  61. static void NAME( struct gl_context *ctx,                               \
  62.                   GLvector4f *clip,                             \
  63.                   GLubyte *clipmask,                            \
  64.                   GLubyte *clipormask,                          \
  65.                   GLubyte *clipandmask )                        \
  66. {                                                               \
  67.    GLuint p;                                                    \
  68.                                                                 \
  69.    for (p = 0; p < ctx->Const.MaxClipPlanes; p++)               \
  70.       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {        \
  71.          GLuint nr, i;                                          \
  72.          const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \
  73.          const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \
  74.          const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \
  75.          const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \
  76.          GLfloat *coord = (GLfloat *)clip->data;                \
  77.          GLuint stride = clip->stride;                          \
  78.          GLuint count = clip->count;                            \
  79.                                                                 \
  80.          for (nr = 0, i = 0 ; i < count ; i++) {                \
  81.             GLfloat dp = coord[0] * a + coord[1] * b;           \
  82.             if (SZ > 2) dp += coord[2] * c;                     \
  83.             if (SZ > 3) dp += coord[3] * d; else dp += d;       \
  84.                                                                 \
  85.             if (dp < 0) {                                       \
  86.                nr++;                                            \
  87.                clipmask[i] |= CLIP_USER_BIT;                    \
  88.             }                                                   \
  89.                                                                 \
  90.             STRIDE_F(coord, stride);                            \
  91.          }                                                      \
  92.                                                                 \
  93.          if (nr > 0) {                                          \
  94.             *clipormask |= CLIP_USER_BIT;                       \
  95.             if (nr == count) {                                  \
  96.                *clipandmask |= CLIP_USER_BIT;                   \
  97.                return;                                          \
  98.             }                                                   \
  99.          }                                                      \
  100.       }                                                         \
  101. }
  102.  
  103.  
  104. USER_CLIPTEST(userclip2, 2)
  105. USER_CLIPTEST(userclip3, 3)
  106. USER_CLIPTEST(userclip4, 4)
  107.  
  108. static void (*(usercliptab[5]))( struct gl_context *,
  109.                                  GLvector4f *, GLubyte *,
  110.                                  GLubyte *, GLubyte * ) =
  111. {
  112.    NULL,
  113.    NULL,
  114.    userclip2,
  115.    userclip3,
  116.    userclip4
  117. };
  118.  
  119.  
  120. void
  121. tnl_clip_prepare(struct gl_context *ctx)
  122. {
  123.    /* Neither the x86 nor sparc asm cliptest functions have been updated
  124.     * for ARB_depth_clamp, so force the C paths.
  125.     */
  126.    if (ctx->Transform.DepthClamp) {
  127.       static GLboolean c_funcs_installed = GL_FALSE;
  128.       if (!c_funcs_installed) {
  129.          init_c_cliptest();
  130.          c_funcs_installed = GL_TRUE;
  131.       }
  132.    }
  133. }
  134.  
  135.  
  136.  
  137. static GLboolean run_vertex_stage( struct gl_context *ctx,
  138.                                    struct tnl_pipeline_stage *stage )
  139. {
  140.    struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr;
  141.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  142.    struct vertex_buffer *VB = &tnl->vb;
  143.  
  144.    if (ctx->VertexProgram._Current)
  145.       return GL_TRUE;
  146.  
  147.    tnl_clip_prepare(ctx);
  148.  
  149.    if (ctx->_NeedEyeCoords) {
  150.       /* Separate modelview transformation:
  151.        * Use combined ModelProject to avoid some depth artifacts
  152.        */
  153.       if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
  154.          VB->EyePtr = VB->AttribPtr[_TNL_ATTRIB_POS];
  155.       else
  156.          VB->EyePtr = TransformRaw( &store->eye,
  157.                                     ctx->ModelviewMatrixStack.Top,
  158.                                     VB->AttribPtr[_TNL_ATTRIB_POS]);
  159.    }
  160.  
  161.    VB->ClipPtr = TransformRaw( &store->clip,
  162.                                &ctx->_ModelProjectMatrix,
  163.                                VB->AttribPtr[_TNL_ATTRIB_POS] );
  164.  
  165.    /* Drivers expect this to be clean to element 4...
  166.     */
  167.    switch (VB->ClipPtr->size) {
  168.    case 1:                     
  169.       /* impossible */
  170.    case 2:
  171.       _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
  172.       /* fall-through */
  173.    case 3:
  174.       _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
  175.       /* fall-through */
  176.    case 4:
  177.       break;
  178.    }
  179.  
  180.  
  181.    /* Cliptest and perspective divide.  Clip functions must clear
  182.     * the clipmask.
  183.     */
  184.    store->ormask = 0;
  185.    store->andmask = CLIP_FRUSTUM_BITS;
  186.  
  187.    if (tnl->NeedNdcCoords) {
  188.       VB->NdcPtr =
  189.          _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
  190.                                             &store->proj,
  191.                                             store->clipmask,
  192.                                             &store->ormask,
  193.                                             &store->andmask,
  194.                                             !ctx->Transform.DepthClamp );
  195.    }
  196.    else {
  197.       VB->NdcPtr = NULL;
  198.       _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
  199.                                             NULL,
  200.                                             store->clipmask,
  201.                                             &store->ormask,
  202.                                             &store->andmask,
  203.                                             !ctx->Transform.DepthClamp );
  204.    }
  205.  
  206.    if (store->andmask)
  207.       return GL_FALSE;
  208.  
  209.  
  210.    /* Test userclip planes.  This contributes to VB->ClipMask, so
  211.     * is essentially required to be in this stage.
  212.     */
  213.    if (ctx->Transform.ClipPlanesEnabled) {
  214.       usercliptab[VB->ClipPtr->size]( ctx,
  215.                                       VB->ClipPtr,
  216.                                       store->clipmask,
  217.                                       &store->ormask,
  218.                                       &store->andmask );
  219.  
  220.       if (store->andmask)
  221.          return GL_FALSE;
  222.    }
  223.  
  224.    VB->ClipAndMask = store->andmask;
  225.    VB->ClipOrMask = store->ormask;
  226.    VB->ClipMask = store->clipmask;
  227.  
  228.    return GL_TRUE;
  229. }
  230.  
  231.  
  232. static GLboolean init_vertex_stage( struct gl_context *ctx,
  233.                                     struct tnl_pipeline_stage *stage )
  234. {
  235.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  236.    struct vertex_stage_data *store;
  237.    GLuint size = VB->Size;
  238.  
  239.    stage->privatePtr = CALLOC(sizeof(*store));
  240.    store = VERTEX_STAGE_DATA(stage);
  241.    if (!store)
  242.       return GL_FALSE;
  243.  
  244.    _mesa_vector4f_alloc( &store->eye, 0, size, 32 );
  245.    _mesa_vector4f_alloc( &store->clip, 0, size, 32 );
  246.    _mesa_vector4f_alloc( &store->proj, 0, size, 32 );
  247.  
  248.    store->clipmask = (GLubyte *) _mesa_align_malloc(sizeof(GLubyte)*size, 32 );
  249.  
  250.    if (!store->clipmask ||
  251.        !store->eye.data ||
  252.        !store->clip.data ||
  253.        !store->proj.data)
  254.       return GL_FALSE;
  255.  
  256.    return GL_TRUE;
  257. }
  258.  
  259. static void dtr( struct tnl_pipeline_stage *stage )
  260. {
  261.    struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage);
  262.  
  263.    if (store) {
  264.       _mesa_vector4f_free( &store->eye );
  265.       _mesa_vector4f_free( &store->clip );
  266.       _mesa_vector4f_free( &store->proj );
  267.       _mesa_align_free( store->clipmask );
  268.       FREE(store);
  269.       stage->privatePtr = NULL;
  270.       stage->run = init_vertex_stage;
  271.    }
  272. }
  273.  
  274.  
  275. const struct tnl_pipeline_stage _tnl_vertex_transform_stage =
  276. {
  277.    "modelview/project/cliptest/divide",
  278.    NULL,                        /* private data */
  279.    init_vertex_stage,
  280.    dtr,                         /* destructor */
  281.    NULL,
  282.    run_vertex_stage             /* run -- initially set to init */
  283. };
  284.