Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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