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

  1. /* $Id: t_array_import.c,v 1.27 2002/10/29 20:29:01 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 "context.h"
  32. #include "macros.h"
  33. #include "imports.h"
  34. #include "mmath.h"
  35. #include "state.h"
  36. #include "mtypes.h"
  37.  
  38. #include "array_cache/acache.h"
  39. #include "math/m_translate.h"
  40.  
  41. #include "t_array_import.h"
  42. #include "t_context.h"
  43. #include "t_imm_debug.h"
  44.  
  45.  
  46. static void _tnl_import_vertex( GLcontext *ctx,
  47.                 GLboolean writeable,
  48.                 GLboolean stride )
  49. {
  50.    struct gl_client_array *tmp;
  51.    GLboolean is_writeable = 0;
  52.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  53.  
  54.    tmp = _ac_import_vertex(ctx,
  55.                GL_FLOAT,
  56.                stride ? 4*sizeof(GLfloat) : 0,
  57.                0,
  58.                writeable,
  59.                &is_writeable);
  60.  
  61.    inputs->Obj.data = (GLfloat (*)[4]) tmp->Ptr;
  62.    inputs->Obj.start = (GLfloat *) tmp->Ptr;
  63.    inputs->Obj.stride = tmp->StrideB;
  64.    inputs->Obj.size = tmp->Size;
  65.    inputs->Obj.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  66.    if (inputs->Obj.stride != 4*sizeof(GLfloat))
  67.       inputs->Obj.flags |= VEC_BAD_STRIDE;
  68.    if (!is_writeable)
  69.       inputs->Obj.flags |= VEC_NOT_WRITEABLE;
  70. }
  71.  
  72. static void _tnl_import_normal( GLcontext *ctx,
  73.                 GLboolean writeable,
  74.                 GLboolean stride )
  75. {
  76.    struct gl_client_array *tmp;
  77.    GLboolean is_writeable = 0;
  78.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  79.  
  80.    tmp = _ac_import_normal(ctx, GL_FLOAT,
  81.                stride ? 3*sizeof(GLfloat) : 0, writeable,
  82.                &is_writeable);
  83.  
  84.    inputs->Normal.data = (GLfloat (*)[4]) tmp->Ptr;
  85.    inputs->Normal.start = (GLfloat *) tmp->Ptr;
  86.    inputs->Normal.stride = tmp->StrideB;
  87.    inputs->Normal.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  88.    if (inputs->Normal.stride != 3*sizeof(GLfloat))
  89.       inputs->Normal.flags |= VEC_BAD_STRIDE;
  90.    if (!is_writeable)
  91.       inputs->Normal.flags |= VEC_NOT_WRITEABLE;
  92. }
  93.  
  94.  
  95. static void _tnl_import_color( GLcontext *ctx,
  96.                    GLenum type,
  97.                    GLboolean writeable,
  98.                    GLboolean stride )
  99. {
  100.    struct gl_client_array *tmp;
  101.    GLboolean is_writeable = 0;
  102.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  103.  
  104.    tmp = _ac_import_color(ctx,
  105.               type,
  106.               stride ? 4*sizeof(GLfloat) : 0,
  107.               4,
  108.               writeable,
  109.               &is_writeable);
  110.  
  111.    inputs->Color = *tmp;
  112. }
  113.  
  114.  
  115. static void _tnl_import_secondarycolor( GLcontext *ctx,
  116.                     GLenum type,
  117.                     GLboolean writeable,
  118.                     GLboolean stride )
  119. {
  120.    struct gl_client_array *tmp;
  121.    GLboolean is_writeable = 0;
  122.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  123.  
  124.    tmp = _ac_import_secondarycolor(ctx, 
  125.                    type,
  126.                    stride ? 4*sizeof(GLfloat) : 0,
  127.                    4,
  128.                    writeable,
  129.                    &is_writeable);
  130.  
  131.    inputs->SecondaryColor = *tmp;
  132. }
  133.  
  134. static void _tnl_import_fogcoord( GLcontext *ctx,
  135.                   GLboolean writeable,
  136.                   GLboolean stride )
  137. {
  138.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  139.     struct gl_client_array *tmp;
  140.    GLboolean is_writeable = 0;
  141.  
  142.    tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
  143.                  stride ? sizeof(GLfloat) : 0, writeable,
  144.                  &is_writeable);
  145.  
  146.    inputs->FogCoord.data = (GLfloat (*)[4]) tmp->Ptr;
  147.    inputs->FogCoord.start = (GLfloat *) tmp->Ptr;
  148.    inputs->FogCoord.stride = tmp->StrideB;
  149.    inputs->FogCoord.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  150.    if (inputs->FogCoord.stride != sizeof(GLfloat))
  151.       inputs->FogCoord.flags |= VEC_BAD_STRIDE;
  152.    if (!is_writeable)
  153.       inputs->FogCoord.flags |= VEC_NOT_WRITEABLE;
  154. }
  155.  
  156. static void _tnl_import_index( GLcontext *ctx,
  157.                    GLboolean writeable,
  158.                    GLboolean stride )
  159. {
  160.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  161.    struct gl_client_array *tmp;
  162.    GLboolean is_writeable = 0;
  163.  
  164.    tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
  165.               stride ? sizeof(GLuint) : 0, writeable,
  166.               &is_writeable);
  167.  
  168.    inputs->Index.data = (GLuint *) tmp->Ptr;
  169.    inputs->Index.start = (GLuint *) tmp->Ptr;
  170.    inputs->Index.stride = tmp->StrideB;
  171.    inputs->Index.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  172.    if (inputs->Index.stride != sizeof(GLuint))
  173.       inputs->Index.flags |= VEC_BAD_STRIDE;
  174.    if (!is_writeable)
  175.       inputs->Index.flags |= VEC_NOT_WRITEABLE;
  176. }
  177.  
  178.  
  179. static void _tnl_import_texcoord( GLcontext *ctx,
  180.                   GLuint unit,
  181.                   GLboolean writeable,
  182.                   GLboolean stride )
  183. {
  184.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  185.    struct gl_client_array *tmp;
  186.    GLboolean is_writeable = 0;
  187.  
  188.    tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
  189.                  stride ? 4 * sizeof(GLfloat) : 0,
  190.                  0,
  191.                  writeable,
  192.                  &is_writeable);
  193.  
  194.    inputs->TexCoord[unit].data = (GLfloat (*)[4]) tmp->Ptr;
  195.    inputs->TexCoord[unit].start = (GLfloat *) tmp->Ptr;
  196.    inputs->TexCoord[unit].stride = tmp->StrideB;
  197.    inputs->TexCoord[unit].size = tmp->Size;
  198.    inputs->TexCoord[unit].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  199.    if (inputs->TexCoord[unit].stride != 4*sizeof(GLfloat))
  200.       inputs->TexCoord[unit].flags |= VEC_BAD_STRIDE;
  201.    if (!is_writeable)
  202.       inputs->TexCoord[unit].flags |= VEC_NOT_WRITEABLE;
  203. }
  204.  
  205.  
  206. static void _tnl_import_edgeflag( GLcontext *ctx,
  207.                   GLboolean writeable,
  208.                   GLboolean stride )
  209. {
  210.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  211.    struct gl_client_array *tmp;
  212.    GLboolean is_writeable = 0;
  213.  
  214.    tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
  215.                  stride ? sizeof(GLubyte) : 0,
  216.                  0,
  217.                  &is_writeable);
  218.  
  219.    inputs->EdgeFlag.data = (GLubyte *) tmp->Ptr;
  220.    inputs->EdgeFlag.start = (GLubyte *) tmp->Ptr;
  221.    inputs->EdgeFlag.stride = tmp->StrideB;
  222.    inputs->EdgeFlag.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  223.    if (inputs->EdgeFlag.stride != sizeof(GLubyte))
  224.       inputs->EdgeFlag.flags |= VEC_BAD_STRIDE;
  225.    if (!is_writeable)
  226.       inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE;
  227. }
  228.  
  229.  
  230.  
  231. static void _tnl_import_attrib( GLcontext *ctx,
  232.                                 GLuint index,
  233.                                 GLboolean writeable,
  234.                                 GLboolean stride )
  235. {
  236.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  237.    struct gl_client_array *tmp;
  238.    GLboolean is_writeable = 0;
  239.  
  240.    tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
  241.                            stride ? 4 * sizeof(GLfloat) : 0,
  242.                            4,  /* want GLfloat[4] */
  243.                            writeable,
  244.                            &is_writeable);
  245.  
  246.    inputs->Attribs[index].data = (GLfloat (*)[4]) tmp->Ptr;
  247.    inputs->Attribs[index].start = (GLfloat *) tmp->Ptr;
  248.    inputs->Attribs[index].stride = tmp->StrideB;
  249.    inputs->Attribs[index].size = tmp->Size;
  250.    inputs->Attribs[index].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
  251.    if (inputs->Attribs[index].stride != 4 * sizeof(GLfloat))
  252.       inputs->Attribs[index].flags |= VEC_BAD_STRIDE;
  253.    if (!is_writeable)
  254.       inputs->Attribs[index].flags |= VEC_NOT_WRITEABLE;
  255. }
  256.  
  257.  
  258.  
  259. /**
  260.  * Callback for VB stages that need to improve the quality of arrays
  261.  * bound to the VB.  This is only necessary for client arrays which
  262.  * have not been transformed at any point in the pipeline.
  263.  * \param required - bitmask of VERT_*_BIT flags
  264.  * \param flags - bitmask of VEC_* flags (ex: VEC_NOT_WRITABLE)
  265.  */
  266. static void _tnl_upgrade_client_data( GLcontext *ctx,
  267.                       GLuint required,
  268.                       GLuint flags )
  269. {
  270.    GLuint i;
  271.    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
  272.    GLboolean writeable = (flags & VEC_NOT_WRITEABLE) != 0;
  273.    GLboolean stride = (flags & VEC_BAD_STRIDE) != 0;
  274.    struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
  275.    GLuint ca_flags = 0;
  276.    (void) inputs;
  277.  
  278.    if (writeable || stride) ca_flags |= CA_CLIENT_DATA;
  279.  
  280.    if ((required & VERT_BIT_CLIP) && VB->ClipPtr == VB->ObjPtr)
  281.       required |= VERT_BIT_POS;
  282.  
  283. /*     _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
  284.  
  285.    if ((required & VERT_BIT_POS) && (VB->ObjPtr->flags & flags)) {
  286.       ASSERT(VB->ObjPtr == &inputs->Obj);
  287.       _tnl_import_vertex( ctx, writeable, stride );
  288.       VB->importable_data &= ~(VERT_BIT_POS|VERT_BIT_CLIP);
  289.    }
  290.  
  291.    if ((required & VERT_BIT_NORMAL) && (VB->NormalPtr->flags & flags)) {
  292.       ASSERT(VB->NormalPtr == &inputs->Normal);
  293.       _tnl_import_normal( ctx, writeable, stride );
  294.       VB->importable_data &= ~VERT_BIT_NORMAL;
  295.    }
  296.  
  297.    if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & ca_flags)) {
  298.       ASSERT(VB->ColorPtr[0] == &inputs->Color);
  299.       _tnl_import_color( ctx, GL_FLOAT, writeable, stride );
  300.       VB->importable_data &= ~VERT_BIT_COLOR0;
  301.    }
  302.  
  303.    if ((required & VERT_BIT_COLOR1) && 
  304.        (VB->SecondaryColorPtr[0]->Flags & ca_flags)) {
  305.       ASSERT(VB->SecondaryColorPtr[0] == &inputs->SecondaryColor);
  306.       _tnl_import_secondarycolor( ctx, GL_FLOAT, writeable, stride );
  307.       VB->importable_data &= ~VERT_BIT_COLOR1;
  308.    }
  309.  
  310.    if ((required & VERT_BIT_FOG)
  311.        && (VB->FogCoordPtr->flags & flags)) {
  312.       ASSERT(VB->FogCoordPtr == &inputs->FogCoord);
  313.       _tnl_import_fogcoord( ctx, writeable, stride );
  314.       VB->importable_data &= ~VERT_BIT_FOG;
  315.    }
  316.  
  317.    if ((required & VERT_BIT_INDEX) && (VB->IndexPtr[0]->flags & flags)) {
  318.       ASSERT(VB->IndexPtr[0] == &inputs->Index);
  319.       _tnl_import_index( ctx, writeable, stride );
  320.       VB->importable_data &= ~VERT_BIT_INDEX;
  321.    }
  322.  
  323.    if (required & VERT_BITS_TEX_ANY)
  324.       for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
  325.      if ((required & VERT_BIT_TEX(i)) && (VB->TexCoordPtr[i]->flags & flags)) {
  326.         ASSERT(VB->TexCoordPtr[i] == &inputs->TexCoord[i]);
  327.         _tnl_import_texcoord( ctx, i, writeable, stride );
  328.         VB->importable_data &= ~VERT_BIT_TEX(i);
  329.      }
  330.  
  331.    /* XXX not sure what to do here for vertex program arrays */
  332. }
  333.  
  334.  
  335.  
  336. void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
  337. {
  338.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  339.    struct vertex_buffer *VB = &tnl->vb;
  340.    GLuint inputs = tnl->pipeline.inputs;
  341.    struct vertex_arrays *tmp = &tnl->array_inputs;
  342.  
  343. /*        _mesa_debug(ctx, "%s %d..%d // %d..%d\n", __FUNCTION__, */
  344. /*            start, count, ctx->Array.LockFirst, ctx->Array.LockCount);  */
  345. /*        _tnl_print_vert_flags("    inputs", inputs);  */
  346. /*        _tnl_print_vert_flags("    _Enabled", ctx->Array._Enabled); */
  347. /*        _tnl_print_vert_flags("    importable", inputs & VERT_BITS_FIXUP); */
  348.  
  349.    VB->Count = count - start;
  350.    VB->FirstClipped = VB->Count;
  351.    VB->Elts = NULL;
  352.    VB->MaterialMask = NULL;
  353.    VB->Material = NULL;
  354.    VB->Flag = NULL;
  355.    VB->Primitive = tnl->tmp_primitive;
  356.    VB->PrimitiveLength = tnl->tmp_primitive_length;
  357.    VB->import_data = _tnl_upgrade_client_data;
  358.    VB->importable_data = inputs & VERT_BITS_FIXUP;
  359.  
  360.    if (ctx->Array.LockCount) {
  361.       ASSERT(start == (GLint) ctx->Array.LockFirst);
  362.       ASSERT(count == (GLint) ctx->Array.LockCount);
  363.    }
  364.  
  365.    _ac_import_range( ctx, start, count );
  366.  
  367.    if (inputs & VERT_BIT_POS) {
  368.       _tnl_import_vertex( ctx, 0, 0 );
  369.       tmp->Obj.count = VB->Count;
  370.       VB->ObjPtr = &tmp->Obj;
  371.    }
  372.  
  373.    if (inputs & VERT_BIT_NORMAL) {
  374.       _tnl_import_normal( ctx, 0, 0 );
  375.       tmp->Normal.count = VB->Count;
  376.       VB->NormalPtr = &tmp->Normal;
  377.    }
  378.  
  379.    if (inputs & VERT_BIT_COLOR0) {
  380.       _tnl_import_color( ctx, 0, 0, 0 );
  381.       VB->ColorPtr[0] = &tmp->Color;
  382.       VB->ColorPtr[1] = 0;
  383.    }
  384.  
  385.    if (inputs & VERT_BITS_TEX_ANY) {
  386.       GLuint unit;
  387.       for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  388.      if (inputs & VERT_BIT_TEX(unit)) {
  389.         _tnl_import_texcoord( ctx, unit, GL_FALSE, GL_FALSE );
  390.         tmp->TexCoord[unit].count = VB->Count;
  391.         VB->TexCoordPtr[unit] = &tmp->TexCoord[unit];
  392.      }
  393.       }
  394.    }
  395.  
  396.    if (inputs & (VERT_BIT_INDEX | VERT_BIT_FOG |
  397.                  VERT_BIT_EDGEFLAG | VERT_BIT_COLOR1)) {
  398.       if (inputs & VERT_BIT_INDEX) {
  399.      _tnl_import_index( ctx, 0, 0 );
  400.      tmp->Index.count = VB->Count;
  401.      VB->IndexPtr[0] = &tmp->Index;
  402.      VB->IndexPtr[1] = 0;
  403.       }
  404.  
  405.       if (inputs & VERT_BIT_FOG) {
  406.      _tnl_import_fogcoord( ctx, 0, 0 );
  407.      tmp->FogCoord.count = VB->Count;
  408.      VB->FogCoordPtr = &tmp->FogCoord;
  409.       }
  410.  
  411.       if (inputs & VERT_BIT_EDGEFLAG) {
  412.      _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
  413.      VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
  414.       }
  415.  
  416.       if (inputs & VERT_BIT_COLOR1) {
  417.      _tnl_import_secondarycolor( ctx, 0, 0, 0 );
  418.      VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
  419.      VB->SecondaryColorPtr[1] = 0;
  420.       }
  421.    }
  422.  
  423.    /* XXX not 100% sure this is finished.  Keith should probably inspect. */
  424.    if (ctx->VertexProgram.Enabled) {
  425.       GLuint index;
  426.       for (index = 0; index < VERT_ATTRIB_MAX; index++) {
  427.          /* XXX check program->InputsRead to reduce work here */
  428.          _tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE );
  429.          VB->AttribPtr[index] = &tmp->Attribs[index];
  430.       }
  431.    }
  432. }
  433.