Minor clean-up of polygon offset logic. Properly compute _MRD field.
[mesa.git] / src / mesa / main / varray.c
index dc6cb39adc7b99863152635454d26acb10789063..fe4a7c684f6344bd84aa8cb94324de71e3953419 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.5.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 
 #include "glheader.h"
 #include "imports.h"
+#include "bufferobj.h"
 #include "context.h"
 #include "enable.h"
 #include "enums.h"
-#include "dlist.h"
-#include "texstate.h"
 #include "mtypes.h"
 #include "varray.h"
-
-
-#ifndef GL_BOOLEAN
-#define GL_BOOLEAN 0x9999
-#endif
+#include "arrayobj.h"
+#include "glapi/dispatch.h"
 
 
 /**
- * Update the fields of a vertex array structure.
+ * Update the fields of a vertex array object.
  * We need to do a few special things for arrays that live in
  * vertex buffer objects.
+ *
+ * \param array  the array to update
+ * \param dirtyBit  which bit to set in ctx->Array.NewState for this array
+ * \param elementSize  size of each array element, in bytes
+ * \param size  components per element (1, 2, 3 or 4)
+ * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
+ * \param stride  stride between elements, in elements
+ * \param normalized  are integer types converted to floats in [-1, 1]?
+ * \param ptr  the address (or offset inside VBO) of the array data
  */
 static void
 update_array(GLcontext *ctx, struct gl_client_array *array,
-             GLuint dirtyFlag, GLsizei elementSize,
+             GLbitfield dirtyBit, GLsizei elementSize,
              GLint size, GLenum type,
              GLsizei stride, GLboolean normalized, const GLvoid *ptr)
 {
@@ -58,7 +63,11 @@ update_array(GLcontext *ctx, struct gl_client_array *array,
    array->Ptr = (const GLubyte *) ptr;
 #if FEATURE_ARB_vertex_buffer_object
    array->BufferObj->RefCount--;
-   /* XXX free buffer object if RefCount == 0 ? */
+   if (array->BufferObj->RefCount <= 0) {
+      ASSERT(array->BufferObj->Name);
+      _mesa_remove_buffer_object( ctx, array->BufferObj );
+      (*ctx->Driver.DeleteBuffer)( ctx, array->BufferObj );
+   }
    array->BufferObj = ctx->Array.ArrayBufferObj;
    array->BufferObj->RefCount++;
    /* Compute the index of the last array element that's inside the buffer.
@@ -67,13 +76,14 @@ update_array(GLcontext *ctx, struct gl_client_array *array,
     */
    if (ctx->Array.ArrayBufferObj->Name)
       array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size
-                            - (GLsizeiptrARB) array->Ptr) / array->StrideB;
+                            - (GLsizeiptrARB) array->Ptr + array->StrideB
+                            - elementSize) / array->StrideB;
    else
 #endif
       array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
 
    ctx->NewState |= _NEW_ARRAY;
-   ctx->Array.NewState |= dirtyFlag;
+   ctx->Array.NewState |= dirtyBit;
 }
 
 
@@ -116,7 +126,7 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
          return;
    }
 
-   update_array(ctx, &ctx->Array.Vertex, _NEW_ARRAY_VERTEX,
+   update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
                 elementSize, size, type, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.VertexPointer)
@@ -161,8 +171,8 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
          return;
    }
 
-   update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL,
-                elementSize, 3, type, stride, GL_FALSE, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
+                elementSize, 3, type, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.NormalPointer)
       ctx->Driver.NormalPointer( ctx, type, stride, ptr );
@@ -219,8 +229,8 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
          return;
    }
 
-   update_array(ctx, &ctx->Array.Color, _NEW_ARRAY_COLOR0,
-                elementSize, size, type, stride, GL_FALSE, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
+                elementSize, size, type, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.ColorPointer)
       ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
@@ -251,7 +261,7 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
          return;
    }
 
-   update_array(ctx, &ctx->Array.FogCoord, _NEW_ARRAY_FOGCOORD,
+   update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
                 elementSize, 1, type, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.FogCoordPointer)
@@ -292,7 +302,7 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
          return;
    }
 
-   update_array(ctx, &ctx->Array.Index, _NEW_ARRAY_INDEX,
+   update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
                 elementSize, 1, type, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.IndexPointer)
@@ -351,8 +361,8 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
          return;
    }
 
-   update_array(ctx, &ctx->Array.SecondaryColor, _NEW_ARRAY_COLOR1,
-                elementSize, size, type, stride, GL_FALSE, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
+                elementSize, size, type, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.SecondaryColorPointer)
       ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
@@ -400,7 +410,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
          return;
    }
 
-   update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit),
+   update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
+                _NEW_ARRAY_TEXCOORD(unit),
                 elementSize, size, type, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.TexCoordPointer)
@@ -419,8 +430,8 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
       return;
    }
 
-   update_array(ctx, &ctx->Array.EdgeFlag, _NEW_ARRAY_EDGEFLAG,
-                sizeof(GLboolean), 1, GL_BOOLEAN, stride, GL_FALSE, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
+                sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.EdgeFlagPointer)
       ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
@@ -432,11 +443,12 @@ void GLAPIENTRY
 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
                             GLsizei stride, const GLvoid *ptr)
 {
+   const GLboolean normalized = GL_FALSE;
    GLsizei elementSize;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (index >= VERT_ATTRIB_MAX) {
+   if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
       return;
    }
@@ -475,8 +487,9 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
          return;
    }
 
-   update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
-                elementSize, size, type, stride, GL_FALSE, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
+                _NEW_ARRAY_ATTRIB(index),
+                elementSize, size, type, stride, normalized, ptr);
 
    if (ctx->Driver.VertexAttribPointer)
       ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
@@ -494,7 +507,7 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (index >= ctx->Const.MaxVertexProgramAttribs) {
+   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
       return;
    }
@@ -546,13 +559,12 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
          return;
    }
 
-   update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
+   update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
+                _NEW_ARRAY_ATTRIB(index),
                 elementSize, size, type, stride, normalized, ptr);
 
-   /* XXX fix
    if (ctx->Driver.VertexAttribPointer)
-      ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
-   */
+      ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr);
 }
 #endif
 
@@ -621,7 +633,6 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
    const GLint toffset = 0;        /* always zero */
    GLint defstride;                /* default stride */
    GLint c, f;
-   GLint coordUnitSave;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
@@ -750,33 +761,17 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
 
    _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
    _mesa_DisableClientState( GL_INDEX_ARRAY );
+   /* XXX also disable secondary color and generic arrays? */
 
    /* Texcoords */
-   coordUnitSave = ctx->Array.ActiveTexture;
    if (tflag) {
-      GLuint i;
-      /* enable unit 0 texcoord array */
-      _mesa_ClientActiveTextureARB( GL_TEXTURE0_ARB );
       _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
       _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
-                             (GLubyte *) pointer + i * toffset );
-      /* disable all other texcoord arrays */
-      for (i = 1; i < ctx->Const.MaxTextureCoordUnits; i++) {
-         _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
-         _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
-      }
+                             (GLubyte *) pointer + toffset );
    }
    else {
-      /* disable all texcoord arrays */
-      GLuint i;
-      for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-         _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
-         _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
-      }
+      _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
    }
-   /* Restore texture coordinate unit index */
-   _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
-
 
    /* Color */
    if (cflag) {
@@ -864,7 +859,7 @@ _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
 
    for (i = 0; i < primcount; i++) {
       if (count[i] > 0) {
-         (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
+         CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
       }
    }
 }
@@ -882,7 +877,7 @@ _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
 
    for (i = 0; i < primcount; i++) {
       if (count[i] > 0) {
-         (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
+         CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i]));
       }
    }
 }
@@ -902,7 +897,7 @@ _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
          GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
-        (ctx->Exec->DrawArrays)( m, first[i], count[i] );
+        CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
       }
    }
 }
@@ -924,84 +919,20 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
          GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
-        (ctx->Exec->DrawElements)( m, count[i], type, indices[i] );
+        CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
       }
    }
 }
 
 
-/**********************************************************************/
-/*****                      Initialization                        *****/
-/**********************************************************************/
-
+/**
+ * Initialize vertex array state for given context.
+ */
 void 
-_mesa_init_varray( GLcontext * ctx )
+_mesa_init_varray(GLcontext *ctx)
 {
-   GLuint i;
-
-   /* Vertex arrays */
-   ctx->Array.Vertex.Size = 4;
-   ctx->Array.Vertex.Type = GL_FLOAT;
-   ctx->Array.Vertex.Stride = 0;
-   ctx->Array.Vertex.StrideB = 0;
-   ctx->Array.Vertex.Ptr = NULL;
-   ctx->Array.Vertex.Enabled = GL_FALSE;
-   ctx->Array.Vertex.Flags = CA_CLIENT_DATA;
-   ctx->Array.Normal.Type = GL_FLOAT;
-   ctx->Array.Normal.Stride = 0;
-   ctx->Array.Normal.StrideB = 0;
-   ctx->Array.Normal.Ptr = NULL;
-   ctx->Array.Normal.Enabled = GL_FALSE;
-   ctx->Array.Normal.Flags = CA_CLIENT_DATA;
-   ctx->Array.Color.Size = 4;
-   ctx->Array.Color.Type = GL_FLOAT;
-   ctx->Array.Color.Stride = 0;
-   ctx->Array.Color.StrideB = 0;
-   ctx->Array.Color.Ptr = NULL;
-   ctx->Array.Color.Enabled = GL_FALSE;
-   ctx->Array.Color.Flags = CA_CLIENT_DATA;
-   ctx->Array.SecondaryColor.Size = 4;
-   ctx->Array.SecondaryColor.Type = GL_FLOAT;
-   ctx->Array.SecondaryColor.Stride = 0;
-   ctx->Array.SecondaryColor.StrideB = 0;
-   ctx->Array.SecondaryColor.Ptr = NULL;
-   ctx->Array.SecondaryColor.Enabled = GL_FALSE;
-   ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA;
-   ctx->Array.FogCoord.Size = 1;
-   ctx->Array.FogCoord.Type = GL_FLOAT;
-   ctx->Array.FogCoord.Stride = 0;
-   ctx->Array.FogCoord.StrideB = 0;
-   ctx->Array.FogCoord.Ptr = NULL;
-   ctx->Array.FogCoord.Enabled = GL_FALSE;
-   ctx->Array.FogCoord.Flags = CA_CLIENT_DATA;
-   ctx->Array.Index.Type = GL_FLOAT;
-   ctx->Array.Index.Stride = 0;
-   ctx->Array.Index.StrideB = 0;
-   ctx->Array.Index.Ptr = NULL;
-   ctx->Array.Index.Enabled = GL_FALSE;
-   ctx->Array.Index.Flags = CA_CLIENT_DATA;
-   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      ctx->Array.TexCoord[i].Size = 4;
-      ctx->Array.TexCoord[i].Type = GL_FLOAT;
-      ctx->Array.TexCoord[i].Stride = 0;
-      ctx->Array.TexCoord[i].StrideB = 0;
-      ctx->Array.TexCoord[i].Ptr = NULL;
-      ctx->Array.TexCoord[i].Enabled = GL_FALSE;
-      ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
-   }
-   ctx->Array.EdgeFlag.Stride = 0;
-   ctx->Array.EdgeFlag.StrideB = 0;
-   ctx->Array.EdgeFlag.Ptr = NULL;
-   ctx->Array.EdgeFlag.Enabled = GL_FALSE;
-   ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA;
+   ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
+   ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj;
+
    ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
-   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
-      ctx->Array.VertexAttrib[i].Size = 4;
-      ctx->Array.VertexAttrib[i].Type = GL_FLOAT;
-      ctx->Array.VertexAttrib[i].Stride = 0;
-      ctx->Array.VertexAttrib[i].StrideB = 0;
-      ctx->Array.VertexAttrib[i].Ptr = NULL;
-      ctx->Array.VertexAttrib[i].Enabled = GL_FALSE;
-      ctx->Array.VertexAttrib[i].Flags = CA_CLIENT_DATA;
-   }
 }