glsl: Added gl_shader_state::EmitContReturn field
[mesa.git] / src / mesa / main / varray.c
index a048509e515d1c1b3fdfa186a80d6731e67669cd..8f6621ee45fec9722fea211837ac1cf424b47ed2 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.1
+ * Version:  7.2
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  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"),
@@ -32,7 +32,7 @@
 #include "mtypes.h"
 #include "varray.h"
 #include "arrayobj.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 /**
 static void
 update_array(GLcontext *ctx, struct gl_client_array *array,
              GLbitfield dirtyBit, GLsizei elementSize,
-             GLint size, GLenum type,
+             GLint size, GLenum type, GLenum format,
              GLsizei stride, GLboolean normalized, const GLvoid *ptr)
 {
+   ASSERT(format == GL_RGBA || format == GL_BGRA);
    array->Size = size;
    array->Type = type;
+   array->Format = format;
    array->Stride = stride;
    array->StrideB = stride ? stride : elementSize;
    array->Normalized = normalized;
    array->Ptr = (const GLubyte *) ptr;
 #if FEATURE_ARB_vertex_buffer_object
-   array->BufferObj->RefCount--;
-   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++;
+   _mesa_reference_buffer_object(ctx, &array->BufferObj,
+                                 ctx->Array.ArrayBufferObj);
+
    /* Compute the index of the last array element that's inside the buffer.
     * Later in glDrawArrays we'll check if start + count > _MaxElement to
     * be sure we won't go out of bounds.
     */
    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 */
@@ -120,13 +118,23 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = size * sizeof(GLfixed);
+         break;
+#endif
+#if FEATURE_vertex_array_byte
+      case GL_BYTE:
+         elementSize = size * sizeof(GLbyte);
+         break;
+#endif
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
-                elementSize, size, type, stride, GL_FALSE, ptr);
+                elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.VertexPointer)
       ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
@@ -165,13 +173,18 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
       case GL_DOUBLE:
          elementSize = 3 * sizeof(GLdouble);
          break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = 3 * sizeof(GLfixed);
+         break;
+#endif
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
-                elementSize, 3, type, stride, GL_TRUE, ptr);
+                elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.NormalPointer)
       ctx->Driver.NormalPointer( ctx, type, stride, ptr );
@@ -182,12 +195,15 @@ void GLAPIENTRY
 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
 {
    GLsizei elementSize;
+   GLenum format;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (size < 3 || size > 4) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
-      return;
+      if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(size)");
+         return;
+      }
    }
    if (stride < 0) {
       _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
@@ -198,6 +214,18 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
       _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
                   _mesa_lookup_enum_by_nr( type ), stride);
 
+   if (size == GL_BGRA) {
+      if (type != GL_UNSIGNED_BYTE) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(GL_BGRA/GLubyte)");
+         return;
+      }
+      format = GL_BGRA;
+      size = 4;
+   }
+   else {
+      format = GL_RGBA;
+   }
+
    switch (type) {
       case GL_BYTE:
          elementSize = size * sizeof(GLbyte);
@@ -223,13 +251,18 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = size * sizeof(GLfixed);
+         break;
+#endif
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
          return;
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
-                elementSize, size, type, stride, GL_TRUE, ptr);
+                elementSize, size, type, format, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.ColorPointer)
       ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
@@ -261,7 +294,7 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
-                elementSize, 1, type, stride, GL_FALSE, ptr);
+                elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.FogCoordPointer)
       ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
@@ -302,7 +335,7 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
-                elementSize, 1, type, stride, GL_FALSE, ptr);
+                elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.IndexPointer)
       ctx->Driver.IndexPointer( ctx, type, stride, ptr );
@@ -314,12 +347,15 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
                               GLsizei stride, const GLvoid *ptr)
 {
    GLsizei elementSize;
+   GLenum format;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (size != 3 && size != 4) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
-      return;
+      if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)");
+         return;
+      }
    }
    if (stride < 0) {
       _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
@@ -330,6 +366,18 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
       _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
                   size, _mesa_lookup_enum_by_nr( type ), stride);
 
+   if (size == GL_BGRA) {
+      if (type != GL_UNSIGNED_BYTE) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(GL_BGRA/GLubyte)");
+         return;
+      }
+      format = GL_BGRA;
+      size = 4;
+   }
+   else {
+      format = GL_RGBA;
+   }
+
    switch (type) {
       case GL_BYTE:
          elementSize = size * sizeof(GLbyte);
@@ -361,7 +409,7 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
-                elementSize, size, type, stride, GL_TRUE, ptr);
+                elementSize, size, type, format, stride, GL_TRUE, ptr);
 
    if (ctx->Driver.SecondaryColorPointer)
       ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
@@ -404,6 +452,16 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = size * sizeof(GLfixed);
+         break;
+#endif
+#if FEATURE_vertex_array_byte
+      case GL_BYTE:
+         elementSize = size * sizeof(GLbyte);
+         break;
+#endif
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
          return;
@@ -411,7 +469,7 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
 
    update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
                 _NEW_ARRAY_TEXCOORD(unit),
-                elementSize, size, type, stride, GL_FALSE, ptr);
+                elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
 
    if (ctx->Driver.TexCoordPointer)
       ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
@@ -430,24 +488,57 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
    }
 
    update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
-                sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, ptr);
+                sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA,
+                stride, GL_FALSE, ptr);
 
    if (ctx->Driver.EdgeFlagPointer)
       ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
 }
 
 
+void GLAPIENTRY
+_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+   GLsizei elementSize;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glPointSizePointer(stride)" );
+      return;
+   }
+
+   switch (type) {
+      case GL_FLOAT:
+         elementSize = sizeof(GLfloat);
+         break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = sizeof(GLfixed);
+         break;
+#endif
+      default:
+         _mesa_error( ctx, GL_INVALID_ENUM, "glPointSizePointer(type)" );
+         return;
+   }
+
+   update_array(ctx, &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE,
+                elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
+}
+
+
 #if FEATURE_NV_vertex_program
 void GLAPIENTRY
 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
                             GLsizei stride, const GLvoid *ptr)
 {
-   const GLboolean normalized = GL_FALSE;
+   GLboolean normalized = GL_FALSE;
    GLsizei elementSize;
+   GLenum format;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
+   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
       return;
    }
@@ -467,9 +558,25 @@ _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:
+         normalized = GL_TRUE;
          elementSize = size * sizeof(GLubyte);
          break;
       case GL_SHORT:
@@ -488,7 +595,7 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
 
    update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
                 _NEW_ARRAY_ATTRIB(index),
-                elementSize, size, type, stride, normalized, ptr);
+                elementSize, size, type, format, stride, normalized, ptr);
 
    if (ctx->Driver.VertexAttribPointer)
       ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
@@ -503,6 +610,7 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
                              GLsizei stride, const GLvoid *ptr)
 {
    GLsizei elementSize;
+   GLenum format;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -512,8 +620,10 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
    }
 
    if (size < 1 || size > 4) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
-      return;
+      if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
+         return;
+      }
    }
 
    if (stride < 0) {
@@ -521,9 +631,23 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
       return;
    }
 
-   if (type == GL_UNSIGNED_BYTE && size != 4) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size!=4)");
-      return;
+   if (size == GL_BGRA) {
+      if (type != GL_UNSIGNED_BYTE) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "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;
+   }
+   else {
+      format = GL_RGBA;
    }
 
    /* check for valid 'type' and compute StrideB right away */
@@ -553,6 +677,11 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
       case GL_DOUBLE:
          elementSize = size * sizeof(GLdouble);
          break;
+#if FEATURE_fixedpt
+      case GL_FIXED:
+         elementSize = size * sizeof(GLfixed);
+         break;
+#endif
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" );
          return;
@@ -560,7 +689,7 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
 
    update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
                 _NEW_ARRAY_ATTRIB(index),
-                elementSize, size, type, stride, normalized, ptr);
+                elementSize, size, type, format, stride, normalized, ptr);
 
    if (ctx->Driver.VertexAttribPointer)
       ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr);
@@ -808,16 +937,22 @@ _mesa_LockArraysEXT(GLint first, GLsizei count)
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
 
-   if (first == 0 && count > 0 &&
-       count <= (GLint) ctx->Const.MaxArrayLockSize) {
-      ctx->Array.LockFirst = first;
-      ctx->Array.LockCount = count;
+   if (first < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
+      return;
    }
-   else {
-      ctx->Array.LockFirst = 0;
-      ctx->Array.LockCount = 0;
+   if (count <= 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
+      return;
+   }
+   if (ctx->Array.LockCount != 0) {
+      _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
+      return;
    }
 
+   ctx->Array.LockFirst = first;
+   ctx->Array.LockCount = count;
+
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
 
@@ -835,6 +970,11 @@ _mesa_UnlockArraysEXT( void )
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glUnlockArrays\n");
 
+   if (ctx->Array.LockCount == 0) {
+      _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
+      return;
+   }
+
    ctx->Array.LockFirst = 0;
    ctx->Array.LockCount = 0;
    ctx->NewState |= _NEW_ARRAY;
@@ -931,7 +1071,7 @@ void
 _mesa_init_varray(GLcontext *ctx)
 {
    ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
-   ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj;
-
+   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
+                                ctx->Array.DefaultArrayObj);
    ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
 }