home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / array_cache / ac_import.cpp < prev    next >
C/C++ Source or Header  |  2002-10-29  |  25KB  |  930 lines

  1. /* $Id: ac_import.c,v 1.21 2002/10/29 20:28:58 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  * Authors:
  27.  *    Keith Whitwell <keith@tungstengraphics.com>
  28.  */
  29.  
  30. #include "glheader.h"
  31. #include "macros.h"
  32. #include "imports.h"
  33. #include "mmath.h"
  34. #include "mtypes.h"
  35.  
  36. #include "math/m_translate.h"
  37. #include "array_cache/ac_context.h"
  38. #include "math/m_translate.h"
  39.  
  40. #define STRIDE_ARRAY( array, offset )         \
  41. do {                        \
  42.    char *tmp = (char *) (array).Ptr;        \
  43.    tmp += (offset) * (array).StrideB;        \
  44.    (array).Ptr = tmp;                \
  45. } while (0)
  46.  
  47. /* Set the array pointer back to its source when the cached data is
  48.  * invalidated:
  49.  */
  50.  
  51. static void reset_texcoord( GLcontext *ctx, GLuint unit )
  52. {
  53.    ACcontext *ac = AC_CONTEXT(ctx);
  54.  
  55.    if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) {
  56.       ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
  57.       STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
  58.    }
  59.    else {
  60.       ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
  61.  
  62.       if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0)
  63.      ac->Raw.TexCoord[unit].Size = 4;
  64.       else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0)
  65.      ac->Raw.TexCoord[unit].Size = 3;
  66.       else
  67.      ac->Raw.TexCoord[unit].Size = 2;
  68.    }
  69.  
  70.    ac->IsCached.TexCoord[unit] = GL_FALSE;
  71.    ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
  72. }
  73.  
  74. static void reset_vertex( GLcontext *ctx )
  75. {
  76.    ACcontext *ac = AC_CONTEXT(ctx);
  77.    ASSERT(ctx->Array.Vertex.Enabled
  78.           || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled));
  79.    ac->Raw.Vertex = ctx->Array.Vertex;
  80.    STRIDE_ARRAY(ac->Raw.Vertex, ac->start);
  81.    ac->IsCached.Vertex = GL_FALSE;
  82.    ac->NewArrayState &= ~_NEW_ARRAY_VERTEX;
  83. }
  84.  
  85.  
  86. static void reset_normal( GLcontext *ctx )
  87. {
  88.    ACcontext *ac = AC_CONTEXT(ctx);
  89.  
  90.    if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) {
  91.       ac->Raw.Normal = ctx->Array.Normal;
  92.       STRIDE_ARRAY(ac->Raw.Normal, ac->start);
  93.    }
  94.    else {
  95.       ac->Raw.Normal = ac->Fallback.Normal;
  96.    }
  97.  
  98.    ac->IsCached.Normal = GL_FALSE;
  99.    ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
  100. }
  101.  
  102.  
  103. static void reset_color( GLcontext *ctx )
  104. {
  105.    ACcontext *ac = AC_CONTEXT(ctx);
  106.  
  107.  
  108.    if (ctx->Array._Enabled & _NEW_ARRAY_COLOR0) {
  109.       ac->Raw.Color = ctx->Array.Color;
  110.       STRIDE_ARRAY(ac->Raw.Color, ac->start);
  111.    }
  112.    else
  113.       ac->Raw.Color = ac->Fallback.Color;
  114.  
  115.    ac->IsCached.Color = GL_FALSE;
  116.    ac->NewArrayState &= ~_NEW_ARRAY_COLOR0;
  117. }
  118.  
  119.  
  120. static void reset_secondarycolor( GLcontext *ctx )
  121. {
  122.    ACcontext *ac = AC_CONTEXT(ctx);
  123.  
  124.    if (ctx->Array._Enabled & _NEW_ARRAY_COLOR1) {
  125.       ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
  126.       STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
  127.    }
  128.    else
  129.       ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
  130.  
  131.    ac->IsCached.SecondaryColor = GL_FALSE;
  132.    ac->NewArrayState &= ~_NEW_ARRAY_COLOR1;
  133. }
  134.  
  135.  
  136. static void reset_index( GLcontext *ctx )
  137. {
  138.    ACcontext *ac = AC_CONTEXT(ctx);
  139.  
  140.    if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) {
  141.       ac->Raw.Index = ctx->Array.Index;
  142.       STRIDE_ARRAY(ac->Raw.Index, ac->start);
  143.    }
  144.    else
  145.       ac->Raw.Index = ac->Fallback.Index;
  146.  
  147.    ac->IsCached.Index = GL_FALSE;
  148.    ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
  149. }
  150.  
  151.  
  152. static void reset_fogcoord( GLcontext *ctx )
  153. {
  154.    ACcontext *ac = AC_CONTEXT(ctx);
  155.  
  156.    if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) {
  157.       ac->Raw.FogCoord = ctx->Array.FogCoord;
  158.       STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
  159.    }
  160.    else
  161.       ac->Raw.FogCoord = ac->Fallback.FogCoord;
  162.  
  163.    ac->IsCached.FogCoord = GL_FALSE;
  164.    ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
  165. }
  166.  
  167.  
  168. static void reset_edgeflag( GLcontext *ctx )
  169. {
  170.    ACcontext *ac = AC_CONTEXT(ctx);
  171.  
  172.    if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) {
  173.       ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
  174.       STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
  175.    }
  176.    else
  177.       ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
  178.  
  179.    ac->IsCached.EdgeFlag = GL_FALSE;
  180.    ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
  181. }
  182.  
  183.  
  184. static void reset_attrib( GLcontext *ctx, GLuint index )
  185. {
  186.    ACcontext *ac = AC_CONTEXT(ctx);
  187.    GLboolean fallback = GL_FALSE;
  188.  
  189.    /*
  190.     * The 16 NV vertex attribute arrays have top priority.  If one of those
  191.     * is not enabled, look if a corresponding conventional array is enabled.
  192.     * If nothing else, use the fallback (ctx->Current.Attrib) values.
  193.     */
  194.    if (ctx->Array._Enabled & _NEW_ARRAY_ATTRIB(index)) {
  195.       ac->Raw.Attrib[index] = ctx->Array.VertexAttrib[index];
  196.       STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
  197.    }
  198.    else if (ctx->Array._Enabled & (1 << index)) {
  199.       /* use conventional vertex array if possible */
  200.       if (index == VERT_ATTRIB_POS) {
  201.          ac->Raw.Attrib[index] = ctx->Array.Vertex;
  202.       }
  203.       else if (index == VERT_ATTRIB_NORMAL) {
  204.          ac->Raw.Attrib[index] = ctx->Array.Normal;
  205.       }
  206.       else if (index == VERT_ATTRIB_COLOR0) {
  207.          ac->Raw.Attrib[index] = ctx->Array.Color;
  208.       }
  209.       else if (index == VERT_ATTRIB_COLOR1) {
  210.          ac->Raw.Attrib[index] = ctx->Array.SecondaryColor;
  211.       }
  212.       else if (index == VERT_ATTRIB_FOG) {
  213.          ac->Raw.Attrib[index] = ctx->Array.FogCoord;
  214.       }
  215.       else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
  216.          GLuint unit = index - VERT_ATTRIB_TEX0;
  217.          ASSERT(unit < MAX_TEXTURE_UNITS);
  218.          ac->Raw.Attrib[index] = ctx->Array.TexCoord[unit];
  219.       }
  220.       else {
  221.          /* missing conventional array (vertex weight, for example) */
  222.          fallback = GL_TRUE;
  223.       }
  224.       if (!fallback)
  225.          STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
  226.    }
  227.    else {
  228.       fallback = GL_TRUE;
  229.    }
  230.  
  231.    if (fallback) {
  232.       /* fallback to ctx->Current.Attrib values */
  233.       ac->Raw.Attrib[index] = ac->Fallback.Attrib[index];
  234.  
  235.       if (ctx->Current.Attrib[index][3] != 1.0)
  236.      ac->Raw.Attrib[index].Size = 4;
  237.       else if (ctx->Current.Attrib[index][2] != 0.0)
  238.      ac->Raw.Attrib[index].Size = 3;
  239.       else
  240.      ac->Raw.Attrib[index].Size = 2;
  241.    }
  242.  
  243.    ac->IsCached.Attrib[index] = GL_FALSE;
  244.    ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index);
  245. }
  246.  
  247.  
  248. /*
  249.  * Generic import function for color data
  250.  */
  251. static void import( GLcontext *ctx,
  252.             GLenum type,
  253.             struct gl_client_array *to,
  254.             struct gl_client_array *from )
  255. {
  256.    ACcontext *ac = AC_CONTEXT(ctx);
  257.  
  258.    if (type == 0) 
  259.       type = from->Type;
  260.  
  261.    switch (type) {
  262.    case GL_FLOAT:
  263.       _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
  264.               from->Ptr,
  265.               from->StrideB,
  266.               from->Type,
  267.               from->Size,
  268.               0,
  269.               ac->count - ac->start);
  270.  
  271.       to->StrideB = 4 * sizeof(GLfloat);
  272.       to->Type = GL_FLOAT;
  273.       break;
  274.       
  275.    case GL_UNSIGNED_BYTE:
  276.       _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
  277.                from->Ptr,
  278.                from->StrideB,
  279.                from->Type,
  280.                from->Size,
  281.                0,
  282.                ac->count - ac->start);
  283.  
  284.       to->StrideB = 4 * sizeof(GLubyte);
  285.       to->Type = GL_UNSIGNED_BYTE;
  286.       break;
  287.  
  288.    case GL_UNSIGNED_SHORT:
  289.       _math_trans_4us( (GLushort (*)[4]) to->Ptr,
  290.                from->Ptr,
  291.                from->StrideB,
  292.                from->Type,
  293.                from->Size,
  294.                0,
  295.                ac->count - ac->start);
  296.  
  297.       to->StrideB = 4 * sizeof(GLushort);
  298.       to->Type = GL_UNSIGNED_SHORT;
  299.       break;
  300.       
  301.    default:
  302.       ASSERT(0);
  303.       break;
  304.    }
  305. }
  306.  
  307.  
  308.  
  309. /*
  310.  * Functions to import array ranges with specified types and strides.
  311.  * For example, if the vertex data is GLshort[2] and we want GLfloat[3]
  312.  * we'll use an import function to do the data conversion.
  313.  */
  314.  
  315. static void import_texcoord( GLcontext *ctx, GLuint unit,
  316.                  GLenum type, GLuint stride )
  317. {
  318.    ACcontext *ac = AC_CONTEXT(ctx);
  319.    struct gl_client_array *from = &ac->Raw.TexCoord[unit];
  320.    struct gl_client_array *to = &ac->Cache.TexCoord[unit];
  321.  
  322.    ASSERT(unit < ctx->Const.MaxTextureUnits);
  323.  
  324.    /* Limited choices at this stage:
  325.     */
  326.    ASSERT(type == GL_FLOAT);
  327.    ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
  328.    ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
  329.  
  330.    _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
  331.            from->Ptr,
  332.            from->StrideB,
  333.            from->Type,
  334.            from->Size,
  335.            0,
  336.            ac->count - ac->start);
  337.  
  338.    to->Size = from->Size;
  339.    to->StrideB = 4 * sizeof(GLfloat);
  340.    to->Type = GL_FLOAT;
  341.    ac->IsCached.TexCoord[unit] = GL_TRUE;
  342. }
  343.  
  344. static void import_vertex( GLcontext *ctx,
  345.                GLenum type, GLuint stride )
  346. {
  347.    ACcontext *ac = AC_CONTEXT(ctx);
  348.    struct gl_client_array *from = &ac->Raw.Vertex;
  349.    struct gl_client_array *to = &ac->Cache.Vertex;
  350.  
  351.    /* Limited choices at this stage:
  352.     */
  353.    ASSERT(type == GL_FLOAT);
  354.    ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
  355.  
  356.    _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
  357.            from->Ptr,
  358.            from->StrideB,
  359.            from->Type,
  360.            from->Size,
  361.            0,
  362.            ac->count - ac->start);
  363.  
  364.    to->Size = from->Size;
  365.    to->StrideB = 4 * sizeof(GLfloat);
  366.    to->Type = GL_FLOAT;
  367.    ac->IsCached.Vertex = GL_TRUE;
  368. }
  369.  
  370. static void import_normal( GLcontext *ctx,
  371.                GLenum type, GLuint stride )
  372. {
  373.    ACcontext *ac = AC_CONTEXT(ctx);
  374.    struct gl_client_array *from = &ac->Raw.Normal;
  375.    struct gl_client_array *to = &ac->Cache.Normal;
  376.  
  377.    /* Limited choices at this stage:
  378.     */
  379.    ASSERT(type == GL_FLOAT);
  380.    ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
  381.  
  382.    _math_trans_3f( (GLfloat (*)[3]) to->Ptr,
  383.            from->Ptr,
  384.            from->StrideB,
  385.            from->Type,
  386.            0,
  387.            ac->count - ac->start);
  388.  
  389.    to->StrideB = 3 * sizeof(GLfloat);
  390.    to->Type = GL_FLOAT;
  391.    ac->IsCached.Normal = GL_TRUE;
  392. }
  393.  
  394. static void import_color( GLcontext *ctx,
  395.               GLenum type, GLuint stride )
  396. {
  397.    ACcontext *ac = AC_CONTEXT(ctx);
  398.    struct gl_client_array *from = &ac->Raw.Color;
  399.    struct gl_client_array *to = &ac->Cache.Color;
  400.  
  401.    import( ctx, type, to, from );
  402.    
  403.    ac->IsCached.Color = GL_TRUE;
  404. }
  405.  
  406. static void import_index( GLcontext *ctx,
  407.               GLenum type, GLuint stride )
  408. {
  409.    ACcontext *ac = AC_CONTEXT(ctx);
  410.    struct gl_client_array *from = &ac->Raw.Index;
  411.    struct gl_client_array *to = &ac->Cache.Index;
  412.  
  413.    /* Limited choices at this stage:
  414.     */
  415.    ASSERT(type == GL_UNSIGNED_INT);
  416.    ASSERT(stride == sizeof(GLuint) || stride == 0);
  417.  
  418.    _math_trans_1ui( (GLuint *) to->Ptr,
  419.             from->Ptr,
  420.             from->StrideB,
  421.             from->Type,
  422.             0,
  423.             ac->count - ac->start);
  424.  
  425.    to->StrideB = sizeof(GLuint);
  426.    to->Type = GL_UNSIGNED_INT;
  427.    ac->IsCached.Index = GL_TRUE;
  428. }
  429.  
  430. static void import_secondarycolor( GLcontext *ctx,
  431.                    GLenum type, GLuint stride )
  432. {
  433.    ACcontext *ac = AC_CONTEXT(ctx);
  434.    struct gl_client_array *from = &ac->Raw.SecondaryColor;
  435.    struct gl_client_array *to = &ac->Cache.SecondaryColor;
  436.  
  437.    import( ctx, type, to, from );
  438.  
  439.    ac->IsCached.SecondaryColor = GL_TRUE;
  440. }
  441.  
  442. static void import_fogcoord( GLcontext *ctx,
  443.                  GLenum type, GLuint stride )
  444. {
  445.    ACcontext *ac = AC_CONTEXT(ctx);
  446.    struct gl_client_array *from = &ac->Raw.FogCoord;
  447.    struct gl_client_array *to = &ac->Cache.FogCoord;
  448.  
  449.    /* Limited choices at this stage:
  450.     */
  451.    ASSERT(type == GL_FLOAT);
  452.    ASSERT(stride == sizeof(GLfloat) || stride == 0);
  453.  
  454.    _math_trans_1f( (GLfloat *) to->Ptr,
  455.            from->Ptr,
  456.            from->StrideB,
  457.            from->Type,
  458.            0,
  459.            ac->count - ac->start);
  460.  
  461.    to->StrideB = sizeof(GLfloat);
  462.    to->Type = GL_FLOAT;
  463.    ac->IsCached.FogCoord = GL_TRUE;
  464. }
  465.  
  466. static void import_edgeflag( GLcontext *ctx,
  467.                  GLenum type, GLuint stride )
  468. {
  469.    ACcontext *ac = AC_CONTEXT(ctx);
  470.    struct gl_client_array *from = &ac->Raw.EdgeFlag;
  471.    struct gl_client_array *to = &ac->Cache.EdgeFlag;
  472.  
  473.    /* Limited choices at this stage:
  474.     */
  475.    ASSERT(type == GL_UNSIGNED_BYTE);
  476.    ASSERT(stride == sizeof(GLubyte) || stride == 0);
  477.  
  478.    _math_trans_1ub( (GLubyte *) to->Ptr,
  479.             from->Ptr,
  480.             from->StrideB,
  481.             from->Type,
  482.             0,
  483.             ac->count - ac->start);
  484.  
  485.    to->StrideB = sizeof(GLubyte);
  486.    to->Type = GL_UNSIGNED_BYTE;
  487.    ac->IsCached.EdgeFlag = GL_TRUE;
  488. }
  489.  
  490. static void import_attrib( GLcontext *ctx, GLuint index,
  491.                            GLenum type, GLuint stride )
  492. {
  493.    ACcontext *ac = AC_CONTEXT(ctx);
  494.    struct gl_client_array *from = &ac->Raw.Attrib[index];
  495.    struct gl_client_array *to = &ac->Cache.Attrib[index];
  496.  
  497.    ASSERT(index < VERT_ATTRIB_MAX);
  498.  
  499.    /* Limited choices at this stage:
  500.     */
  501.    ASSERT(type == GL_FLOAT);
  502.    ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
  503.    ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
  504.  
  505.    _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
  506.            from->Ptr,
  507.            from->StrideB,
  508.            from->Type,
  509.            from->Size,
  510.            0,
  511.            ac->count - ac->start);
  512.  
  513.    to->Size = from->Size;
  514.    to->StrideB = 4 * sizeof(GLfloat);
  515.    to->Type = GL_FLOAT;
  516.    ac->IsCached.Attrib[index] = GL_TRUE;
  517. }
  518.  
  519.  
  520.  
  521. /*
  522.  * Externals to request arrays with specific properties:
  523.  */
  524.  
  525.  
  526. struct gl_client_array *_ac_import_texcoord( GLcontext *ctx,
  527.                          GLuint unit,
  528.                          GLenum type,
  529.                          GLuint reqstride,
  530.                          GLuint reqsize,
  531.                          GLboolean reqwriteable,
  532.                          GLboolean *writeable )
  533. {
  534.    ACcontext *ac = AC_CONTEXT(ctx);
  535.  
  536.    ASSERT(unit < ctx->Const.MaxTextureUnits);
  537.  
  538.    /* Can we keep the existing version?
  539.     */
  540.    if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
  541.       reset_texcoord( ctx, unit );
  542.  
  543.    /* Is the request impossible?
  544.     */
  545.    if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize)
  546.       return 0;
  547.  
  548.    /* Do we need to pull in a copy of the client data:
  549.     */
  550.    if (ac->Raw.TexCoord[unit].Type != type ||
  551.        (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) ||
  552.        reqwriteable)
  553.    {
  554.       if (!ac->IsCached.TexCoord[unit])
  555.      import_texcoord(ctx, unit, type, reqstride );
  556.       *writeable = GL_TRUE;
  557.       return &ac->Cache.TexCoord[unit];
  558.    }
  559.    else {
  560.       *writeable = GL_FALSE;
  561.       return &ac->Raw.TexCoord[unit];
  562.    }
  563. }
  564.  
  565. struct gl_client_array *_ac_import_vertex( GLcontext *ctx,
  566.                        GLenum type,
  567.                        GLuint reqstride,
  568.                        GLuint reqsize,
  569.                        GLboolean reqwriteable,
  570.                        GLboolean *writeable )
  571. {
  572.    ACcontext *ac = AC_CONTEXT(ctx);
  573.  
  574.    /* Can we keep the existing version?
  575.     */
  576.    if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
  577.       reset_vertex( ctx );
  578.  
  579.    /* Is the request impossible?
  580.     */
  581.    if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize)
  582.       return 0;
  583.  
  584.    /* Do we need to pull in a copy of the client data:
  585.     */
  586.    if (ac->Raw.Vertex.Type != type ||
  587.        (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) ||
  588.        reqwriteable)
  589.    {
  590.       if (!ac->IsCached.Vertex)
  591.      import_vertex(ctx, type, reqstride );
  592.       *writeable = GL_TRUE;
  593.       return &ac->Cache.Vertex;
  594.    }
  595.    else {
  596.       *writeable = GL_FALSE;
  597.       return &ac->Raw.Vertex;
  598.    }
  599. }
  600.  
  601. struct gl_client_array *_ac_import_normal( GLcontext *ctx,
  602.                        GLenum type,
  603.                        GLuint reqstride,
  604.                        GLboolean reqwriteable,
  605.                        GLboolean *writeable )
  606. {
  607.    ACcontext *ac = AC_CONTEXT(ctx);
  608.  
  609.    /* Can we keep the existing version?
  610.     */
  611.    if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
  612.       reset_normal( ctx );
  613.  
  614.    /* Do we need to pull in a copy of the client data:
  615.     */
  616.    if (ac->Raw.Normal.Type != type ||
  617.        (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) ||
  618.        reqwriteable)
  619.    {
  620.       if (!ac->IsCached.Normal)
  621.      import_normal(ctx, type, reqstride );
  622.       *writeable = GL_TRUE;
  623.       return &ac->Cache.Normal;
  624.    }
  625.    else {
  626.       *writeable = GL_FALSE;
  627.       return &ac->Raw.Normal;
  628.    }
  629. }
  630.  
  631. struct gl_client_array *_ac_import_color( GLcontext *ctx,
  632.                       GLenum type,
  633.                       GLuint reqstride,
  634.                       GLuint reqsize,
  635.                       GLboolean reqwriteable,
  636.                       GLboolean *writeable )
  637. {
  638.    ACcontext *ac = AC_CONTEXT(ctx);
  639.  
  640.    /* Can we keep the existing version?
  641.     */
  642.    if (ac->NewArrayState & _NEW_ARRAY_COLOR0)
  643.       reset_color( ctx );
  644.  
  645.    /* Is the request impossible?
  646.     */
  647.    if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) {
  648.       return 0;
  649.    }
  650.  
  651.    /* Do we need to pull in a copy of the client data:
  652.     */
  653.    if ((type != 0 && ac->Raw.Color.Type != type) ||
  654.        (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) ||
  655.        reqwriteable)
  656.    {
  657.       if (!ac->IsCached.Color)
  658.      import_color(ctx, type, reqstride );
  659.       *writeable = GL_TRUE;
  660.       return &ac->Cache.Color;
  661.    }
  662.    else {
  663.       *writeable = GL_FALSE;
  664.       return &ac->Raw.Color;
  665.    }
  666. }
  667.  
  668. struct gl_client_array *_ac_import_index( GLcontext *ctx,
  669.                       GLenum type,
  670.                       GLuint reqstride,
  671.                       GLboolean reqwriteable,
  672.                       GLboolean *writeable )
  673. {
  674.    ACcontext *ac = AC_CONTEXT(ctx);
  675.  
  676.    /* Can we keep the existing version?
  677.     */
  678.    if (ac->NewArrayState & _NEW_ARRAY_INDEX)
  679.       reset_index( ctx );
  680.  
  681.  
  682.    /* Do we need to pull in a copy of the client data:
  683.     */
  684.    if (ac->Raw.Index.Type != type ||
  685.        (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) ||
  686.        reqwriteable)
  687.    {
  688.       if (!ac->IsCached.Index)
  689.      import_index(ctx, type, reqstride );
  690.       *writeable = GL_TRUE;
  691.       return &ac->Cache.Index;
  692.    }
  693.    else {
  694.       *writeable = GL_FALSE;
  695.       return &ac->Raw.Index;
  696.    }
  697. }
  698.  
  699. struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx,
  700.                            GLenum type,
  701.                            GLuint reqstride,
  702.                            GLuint reqsize,
  703.                            GLboolean reqwriteable,
  704.                            GLboolean *writeable )
  705. {
  706.    ACcontext *ac = AC_CONTEXT(ctx);
  707.  
  708.    /* Can we keep the existing version?
  709.     */
  710.    if (ac->NewArrayState & _NEW_ARRAY_COLOR1)
  711.       reset_secondarycolor( ctx );
  712.  
  713.    /* Is the request impossible?
  714.     */
  715.    if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize)
  716.       return 0;
  717.  
  718.    /* Do we need to pull in a copy of the client data:
  719.     */
  720.    if ((type != 0 && ac->Raw.SecondaryColor.Type != type) ||
  721.        (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) ||
  722.        reqwriteable)
  723.    {
  724.       if (!ac->IsCached.SecondaryColor)
  725.      import_secondarycolor(ctx, type, reqstride );
  726.       *writeable = GL_TRUE;
  727.       return &ac->Cache.SecondaryColor;
  728.    }
  729.    else {
  730.       *writeable = GL_FALSE;
  731.       return &ac->Raw.SecondaryColor;
  732.    }
  733. }
  734.  
  735. struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx,
  736.                          GLenum type,
  737.                          GLuint reqstride,
  738.                          GLboolean reqwriteable,
  739.                          GLboolean *writeable )
  740. {
  741.    ACcontext *ac = AC_CONTEXT(ctx);
  742.  
  743.    /* Can we keep the existing version?
  744.     */
  745.    if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
  746.       reset_fogcoord( ctx );
  747.  
  748.    /* Do we need to pull in a copy of the client data:
  749.     */
  750.    if (ac->Raw.FogCoord.Type != type ||
  751.        (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) ||
  752.        reqwriteable)
  753.    {
  754.       if (!ac->IsCached.FogCoord)
  755.      import_fogcoord(ctx, type, reqstride );
  756.       *writeable = GL_TRUE;
  757.       return &ac->Cache.FogCoord;
  758.    }
  759.    else {
  760.       *writeable = GL_FALSE;
  761.       return &ac->Raw.FogCoord;
  762.    }
  763. }
  764.  
  765. struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx,
  766.                          GLenum type,
  767.                          GLuint reqstride,
  768.                          GLboolean reqwriteable,
  769.                          GLboolean *writeable )
  770. {
  771.    ACcontext *ac = AC_CONTEXT(ctx);
  772.  
  773.    /* Can we keep the existing version?
  774.     */
  775.    if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
  776.       reset_edgeflag( ctx );
  777.  
  778.    /* Do we need to pull in a copy of the client data:
  779.     */
  780.    if (ac->Raw.EdgeFlag.Type != type ||
  781.        (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) ||
  782.        reqwriteable)
  783.    {
  784.       if (!ac->IsCached.EdgeFlag)
  785.      import_edgeflag(ctx, type, reqstride );
  786.       *writeable = GL_TRUE;
  787.       return &ac->Cache.EdgeFlag;
  788.    }
  789.    else {
  790.       *writeable = GL_FALSE;
  791.       return &ac->Raw.EdgeFlag;
  792.    }
  793. }
  794.  
  795. /* GL_NV_vertex_program */
  796. struct gl_client_array *_ac_import_attrib( GLcontext *ctx,
  797.                                            GLuint index,
  798.                                            GLenum type,
  799.                                            GLuint reqstride,
  800.                                            GLuint reqsize,
  801.                                            GLboolean reqwriteable,
  802.                                            GLboolean *writeable )
  803. {
  804.    ACcontext *ac = AC_CONTEXT(ctx);
  805.  
  806.    ASSERT(index < VERT_ATTRIB_MAX);
  807.  
  808.    /* Can we keep the existing version?
  809.     */
  810.    if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index)) {
  811.       reset_attrib( ctx, index );
  812.    }
  813.    else if (ac->NewArrayState & (1 << index)) {
  814.       /* Also need to check conventional attributes */
  815.       reset_attrib( ctx, index );
  816.    }
  817.  
  818.    /* Is the request impossible?
  819.     */
  820.    if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize)
  821.       return NULL;
  822.  
  823.    /* Do we need to pull in a copy of the client data:
  824.     */
  825.    if (ac->Raw.Attrib[index].Type != type ||
  826.        (reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) ||
  827.        reqwriteable)
  828.    {
  829.       if (!ac->IsCached.Attrib[index])
  830.      import_attrib(ctx, index, type, reqstride );
  831.       *writeable = GL_TRUE;
  832.       return &ac->Cache.Attrib[index];
  833.    }
  834.    else {
  835.       *writeable = GL_FALSE;
  836.       return &ac->Raw.Attrib[index];
  837.    }
  838. }
  839.  
  840.  
  841. /* Clients must call this function to validate state and set bounds
  842.  * before importing any data:
  843.  */
  844. void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
  845. {
  846.    ACcontext *ac = AC_CONTEXT(ctx);
  847.  
  848.    if (!ctx->Array.LockCount) {
  849.       /* Not locked, discard cached data.  Changes to lock
  850.        * status are caught via. _ac_invalidate_state().
  851.        */
  852.       ac->NewArrayState = _NEW_ARRAY_ALL;
  853.       ac->start = start;
  854.       ac->count = count;
  855.    }
  856.    else {
  857.       /* Locked, discard data for any disabled arrays.  Require that
  858.        * the whole locked range always be dealt with, otherwise hard to
  859.        * maintain cached data in the face of clipping.
  860.        */
  861.       ac->NewArrayState |= ~ctx->Array._Enabled;
  862.       ac->start = ctx->Array.LockFirst;
  863.       ac->count = ctx->Array.LockCount;
  864.       ASSERT(ac->start == start); /* hmm? */
  865.       ASSERT(ac->count == count);
  866.    }
  867. }
  868.  
  869.  
  870.  
  871. /* Additional convienence function for importing the element list
  872.  * for glDrawElements() and glDrawRangeElements().
  873.  */
  874. CONST void *
  875. _ac_import_elements( GLcontext *ctx,
  876.              GLenum new_type,
  877.              GLuint count,
  878.              GLenum old_type,
  879.              CONST void *indices )
  880. {
  881.    ACcontext *ac = AC_CONTEXT(ctx);
  882.  
  883.    if (old_type == new_type)
  884.       return indices;
  885.  
  886.    if (ac->elt_size < count * sizeof(GLuint)) {
  887.       if (ac->Elts) FREE(ac->Elts);
  888.       while (ac->elt_size < count * sizeof(GLuint))
  889.      ac->elt_size *= 2;
  890.       ac->Elts = (GLuint *) MALLOC(ac->elt_size);
  891.    }
  892.  
  893.    switch (new_type) {
  894.    case GL_UNSIGNED_BYTE:
  895.       ASSERT(0);
  896.       return 0;
  897.    case GL_UNSIGNED_SHORT:
  898.       ASSERT(0);
  899.       return 0;
  900.    case GL_UNSIGNED_INT: {
  901.       GLuint *out = (GLuint *)ac->Elts;
  902.       GLuint i;
  903.  
  904.       switch (old_type) {
  905.       case GL_UNSIGNED_BYTE: {
  906.      CONST GLubyte *in = (CONST GLubyte *)indices;
  907.      for (i = 0 ; i < count ; i++)
  908.         out[i] = in[i];
  909.      break;
  910.       }
  911.       case GL_UNSIGNED_SHORT: {
  912.      CONST GLushort *in = (CONST GLushort *)indices;
  913.      for (i = 0 ; i < count ; i++)
  914.            out[i] = in[i];
  915.      break;
  916.       }
  917.       default:
  918.      ASSERT(0);
  919.       }
  920.  
  921.       return (CONST void *)out;
  922.    }
  923.    default:
  924.       ASSERT(0);
  925.       break;
  926.    }
  927.  
  928.    return 0;
  929. }
  930.