mesa: Fix SCons build.
[mesa.git] / src / mesa / main / varray.c
index ff3128b8beb40c00a5bafc2626bc2071a92c0a03..86878d6a8ac9ae09ed30aba372e94947523ca5d6 100644 (file)
@@ -30,6 +30,7 @@
 #include "context.h"
 #include "enable.h"
 #include "enums.h"
+#include "hash.h"
 #include "mtypes.h"
 #include "varray.h"
 #include "arrayobj.h"
@@ -38,6 +39,8 @@
 
 /**
  * Set the fields of a vertex array.
+ * Also do an error check for GL_ARB_vertex_array_object: check that
+ * all arrays reside in VBOs when using a vertex array object.
  *
  * \param array  the array to update
  * \param dirtyBit  which bit to set in ctx->Array.NewState for this array
@@ -56,6 +59,17 @@ update_array(GLcontext *ctx, struct gl_client_array *array,
              GLsizei stride, GLboolean normalized, const GLvoid *ptr)
 {
    ASSERT(format == GL_RGBA || format == GL_BGRA);
+
+   if (ctx->Array.ArrayObj->VBOonly &&
+       ctx->Array.ArrayBufferObj->Name == 0) {
+      /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs.
+       * Generate GL_INVALID_OPERATION if that's not true.
+       */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glVertex/Normal/EtcPointer(non-VBO array)");
+      return;
+   }
+
    array->Size = size;
    array->Type = type;
    array->Format = format;
@@ -107,6 +121,9 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = size * sizeof(GLhalfARB);
+         break;
 #if FEATURE_fixedpt
       case GL_FIXED:
          elementSize = size * sizeof(GLfixed);
@@ -118,15 +135,13 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
          break;
 #endif
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
                 elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
-
-   if (ctx->Driver.VertexPointer)
-      ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -162,21 +177,22 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
       case GL_DOUBLE:
          elementSize = 3 * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = 3 * sizeof(GLhalfARB);
+         break;
 #if FEATURE_fixedpt
       case GL_FIXED:
          elementSize = 3 * sizeof(GLfixed);
          break;
 #endif
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
                 elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr);
-
-   if (ctx->Driver.NormalPointer)
-      ctx->Driver.NormalPointer( ctx, type, stride, ptr );
 }
 
 
@@ -240,21 +256,22 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = size * sizeof(GLhalfARB);
+         break;
 #if FEATURE_fixedpt
       case GL_FIXED:
          elementSize = size * sizeof(GLfixed);
          break;
 #endif
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
                 elementSize, size, type, format, stride, GL_TRUE, ptr);
-
-   if (ctx->Driver.ColorPointer)
-      ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -277,6 +294,9 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
       case GL_DOUBLE:
          elementSize = sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = sizeof(GLhalfARB);
+         break;
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
          return;
@@ -284,9 +304,6 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
 
    update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
                 elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
-
-   if (ctx->Driver.FogCoordPointer)
-      ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
 }
 
 
@@ -325,9 +342,6 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
 
    update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
                 elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
-
-   if (ctx->Driver.IndexPointer)
-      ctx->Driver.IndexPointer( ctx, type, stride, ptr );
 }
 
 
@@ -392,16 +406,17 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = size * sizeof(GLhalfARB);
+         break;
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
                 elementSize, size, type, format, stride, GL_TRUE, ptr);
-
-   if (ctx->Driver.SecondaryColorPointer)
-      ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -441,6 +456,9 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = size * sizeof(GLhalfARB);
+         break;
 #if FEATURE_fixedpt
       case GL_FIXED:
          elementSize = size * sizeof(GLfixed);
@@ -452,16 +470,16 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
          break;
 #endif
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
+   ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord));
+
    update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
                 _NEW_ARRAY_TEXCOORD(unit),
                 elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
-
-   if (ctx->Driver.TexCoordPointer)
-      ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -479,9 +497,6 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
    update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
                 sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA,
                 stride, GL_FALSE, ptr);
-
-   if (ctx->Driver.EdgeFlagPointer)
-      ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
 }
 
 
@@ -529,6 +544,7 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
 {
    GLboolean normalized = GL_FALSE;
    GLsizei elementSize;
+   GLenum format;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -552,6 +568,21 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
       return;
    }
 
+   if (size == GL_BGRA) {
+      if (type != GL_UNSIGNED_BYTE) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glVertexAttribPointerNV(GL_BGRA/type)");
+         return;
+      }
+
+      format = GL_BGRA;
+      size = 4;
+      normalized = GL_TRUE;
+   }
+   else {
+      format = GL_RGBA;
+   }
+
    /* check for valid 'type' and compute StrideB right away */
    switch (type) {
       case GL_UNSIGNED_BYTE:
@@ -568,16 +599,14 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
          elementSize = size * sizeof(GLdouble);
          break;
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)",
+                      _mesa_lookup_enum_by_nr(type));
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
                 _NEW_ARRAY_ATTRIB(index),
-                elementSize, size, type, GL_RGBA, stride, normalized, ptr);
-
-   if (ctx->Driver.VertexAttribPointer)
-      ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
+                elementSize, size, type, format, stride, normalized, ptr);
 }
 #endif
 
@@ -621,9 +650,14 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
                      "glVertexAttribPointerARB(GL_BGRA/type)");
          return;
       }
+      if (normalized != GL_TRUE) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glVertexAttribPointerARB(GL_BGRA/normalized)");
+         return;
+      }
+
       format = GL_BGRA;
       size = 4;
-      normalized = GL_TRUE;
    }
    else {
       format = GL_RGBA;
@@ -656,6 +690,9 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+      case GL_HALF_FLOAT:
+         elementSize = size * sizeof(GLhalfARB);
+         break;
 #if FEATURE_fixedpt
       case GL_FIXED:
          elementSize = size * sizeof(GLfixed);
@@ -668,10 +705,7 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
 
    update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
                 _NEW_ARRAY_ATTRIB(index),
-                elementSize, size, type, GL_RGBA, stride, normalized, ptr);
-
-   if (ctx->Driver.VertexAttribPointer)
-      ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr);
+                elementSize, size, type, format, stride, normalized, ptr);
 }
 #endif
 
@@ -934,9 +968,6 @@ _mesa_LockArraysEXT(GLint first, GLsizei count)
 
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
-
-   if (ctx->Driver.LockArraysEXT)
-      ctx->Driver.LockArraysEXT( ctx, first, count );
 }
 
 
@@ -958,9 +989,6 @@ _mesa_UnlockArraysEXT( void )
    ctx->Array.LockCount = 0;
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
-
-   if (ctx->Driver.UnlockArraysEXT)
-      ctx->Driver.UnlockArraysEXT( ctx );
 }
 
 
@@ -983,24 +1011,6 @@ _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
 }
 
 
-/* GL_EXT_multi_draw_arrays */
-void GLAPIENTRY
-_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
-                            const GLvoid **indices, GLsizei primcount )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint i;
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   for (i = 0; i < primcount; i++) {
-      if (count[i] > 0) {
-         CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i]));
-      }
-   }
-}
-
-
 /* GL_IBM_multimode_draw_arrays */
 void GLAPIENTRY
 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
@@ -1043,6 +1053,29 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
 }
 
 
+/**
+ * Copy one client vertex array to another.
+ */
+void
+_mesa_copy_client_array(GLcontext *ctx,
+                        struct gl_client_array *dst,
+                        struct gl_client_array *src)
+{
+   dst->Size = src->Size;
+   dst->Type = src->Type;
+   dst->Format = src->Format;
+   dst->Stride = src->Stride;
+   dst->StrideB = src->StrideB;
+   dst->Ptr = src->Ptr;
+   dst->Enabled = src->Enabled;
+   dst->Normalized = src->Normalized;
+   dst->_ElementSize = src->_ElementSize;
+   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
+   dst->_MaxElement = src->_MaxElement;
+}
+
+
+
 /**
  * Print vertex array's fields.
  */
@@ -1050,14 +1083,14 @@ static void
 print_array(const char *name, GLint index, const struct gl_client_array *array)
 {
    if (index >= 0)
-      _mesa_printf("  %s[%d]: ", name, index);
+      printf("  %s[%d]: ", name, index);
    else
-      _mesa_printf("  %s: ", name);
-   _mesa_printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %u), MaxElem=%u\n",
-                array->Ptr, array->Type, array->Size,
-                array->_ElementSize, array->StrideB,
-                array->BufferObj->Name, array->BufferObj->Size,
-                array->_MaxElement);
+      printf("  %s: ", name);
+   printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %u), MaxElem=%u\n",
+         array->Ptr, array->Type, array->Size,
+         array->_ElementSize, array->StrideB,
+         array->BufferObj->Name, array->BufferObj->Size,
+         array->_MaxElement);
 }
 
 
@@ -1072,7 +1105,7 @@ _mesa_print_arrays(GLcontext *ctx)
 
    _mesa_update_array_object_max_element(ctx, arrayObj);
 
-   _mesa_printf("Array Object %u\n", arrayObj->Name);
+   printf("Array Object %u\n", arrayObj->Name);
    if (arrayObj->Vertex.Enabled)
       print_array("Vertex", -1, &arrayObj->Vertex);
    if (arrayObj->Normal.Enabled)
@@ -1085,7 +1118,7 @@ _mesa_print_arrays(GLcontext *ctx)
    for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
       if (arrayObj->VertexAttrib[i].Enabled)
          print_array("Attrib", i, &arrayObj->VertexAttrib[i]);
-   _mesa_printf("  _MaxElement = %u\n", arrayObj->_MaxElement);
+   printf("  _MaxElement = %u\n", arrayObj->_MaxElement);
 }
 
 
@@ -1099,4 +1132,29 @@ _mesa_init_varray(GLcontext *ctx)
    _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
                                 ctx->Array.DefaultArrayObj);
    ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
+
+   ctx->Array.Objects = _mesa_NewHashTable();
+}
+
+
+/**
+ * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_arrayobj_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
+   GLcontext *ctx = (GLcontext *) userData;
+   _mesa_delete_array_object(ctx, arrayObj);
+}
+
+
+/**
+ * Free vertex array state for given context.
+ */
+void 
+_mesa_free_varray_data(GLcontext *ctx)
+{
+   _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
+   _mesa_DeleteHashTable(ctx->Array.Objects);
 }