mesa: add ARB_vertex_attrib_64bit VertexArrayVertexAttribLOffsetEXT
[mesa.git] / src / mesa / main / varray.c
index cc9321a832799f7aba4bd1cc2c255858d2a83cad..8db6f13a3199a8024e6d88f88d02735d2a630561 100644 (file)
@@ -40,6 +40,7 @@
 #include "mtypes.h"
 #include "varray.h"
 #include "arrayobj.h"
+#include "get.h"
 #include "main/dispatch.h"
 
 
@@ -699,7 +700,34 @@ void GLAPIENTRY
 _mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
                                  GLenum type, GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   GLenum format = GL_RGBA;
+   GLbitfield legalTypes = (ctx->API == API_OPENGLES)
+      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
+      : (SHORT_BIT | INT_BIT | FLOAT_BIT |
+         DOUBLE_BIT | HALF_BIT |
+         UNSIGNED_INT_2_10_10_10_REV_BIT |
+         INT_2_10_10_10_REV_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayVertexOffsetEXT"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glVertexArrayVertexOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_POS, legalTypes, 2, 4, size,
+                                  type, stride, GL_FALSE, GL_FALSE, GL_FALSE,
+                                  format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_POS, format, 4, size, type, stride,
+                GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -744,7 +772,34 @@ void GLAPIENTRY
 _mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
                                  GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
+      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
+      : (BYTE_BIT | SHORT_BIT | INT_BIT |
+         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+         UNSIGNED_INT_2_10_10_10_REV_BIT |
+         INT_2_10_10_10_REV_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glNormalPointer"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glNormalPointer",
+                                  vao, vbo,
+                                  VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
+                                  type, stride, GL_TRUE, GL_FALSE,
+                                  GL_FALSE, format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
+                GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -794,7 +849,37 @@ void GLAPIENTRY
 _mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
                                 GLenum type, GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
+
+   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
+   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
+      ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
+      : (BYTE_BIT | UNSIGNED_BYTE_BIT |
+         SHORT_BIT | UNSIGNED_SHORT_BIT |
+         INT_BIT | UNSIGNED_INT_BIT |
+         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+         UNSIGNED_INT_2_10_10_10_REV_BIT |
+         INT_2_10_10_10_REV_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayColorOffsetEXT"))
+      return;
 
+   if (!validate_array_and_format(ctx, "glVertexArrayColorOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
+                                  BGRA_OR_4, size, type, stride, GL_TRUE,
+                                  GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
+                type, stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -834,7 +919,29 @@ void GLAPIENTRY
 _mesa_VertexArrayFogCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
                                    GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayFogCoordOffsetEXT"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glVertexArrayFogCoordOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
+                                  type, stride, GL_FALSE, GL_FALSE,
+                                  GL_FALSE, format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
+                GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -875,7 +982,30 @@ void GLAPIENTRY
 _mesa_VertexArrayIndexOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
                                 GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
+                                     FLOAT_BIT | DOUBLE_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayIndexOffsetEXT"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glVertexArrayIndexOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_COLOR_INDEX,
+                                  legalTypes, 1, 1, 1, type, stride,
+                                  GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
+                GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -923,7 +1053,34 @@ void GLAPIENTRY
 _mesa_VertexArraySecondaryColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
                                          GLenum type, GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
 
+   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
+   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
+                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
+                                  INT_BIT | UNSIGNED_INT_BIT |
+                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
+                                  INT_2_10_10_10_REV_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArraySecondaryColorOffsetEXT"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glVertexArraySecondaryColorOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_COLOR1, legalTypes, 3,
+                                  BGRA_OR_4, size, type, stride,
+                                  GL_TRUE, GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
+                stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -973,7 +1130,36 @@ void GLAPIENTRY
 _mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
                                    GLenum type, GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
+   const GLuint unit = ctx->Array.ActiveTexture;
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
+      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
+      : (SHORT_BIT | INT_BIT |
+         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+         UNSIGNED_INT_2_10_10_10_REV_BIT |
+         INT_2_10_10_10_REV_BIT);
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayTexCoordOffsetEXT"))
+      return;
+
+   if (!validate_array_and_format(ctx, "glVertexArrayTexCoordOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_TEX(unit), legalTypes,
+                                  sizeMin, 4, size, type, stride,
+                                  GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_TEX(unit), format, 4, size, type,
+                stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -982,7 +1168,42 @@ _mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texu
                                         GLint size, GLenum type, GLsizei stride,
                                         GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
+   const GLuint unit = texunit - GL_TEXTURE0;
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
+      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
+      : (SHORT_BIT | INT_BIT |
+         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+         UNSIGNED_INT_2_10_10_10_REV_BIT |
+         INT_2_10_10_10_REV_BIT);
 
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayMultiTexCoordOffsetEXT"))
+      return;
+
+   if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayMultiTexCoordOffsetEXT(texunit=%d)",
+         texunit);
+      return;
+   }
+
+   if (!validate_array_and_format(ctx, "glVertexArrayMultiTexCoordOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_TEX(unit), legalTypes,
+                                  sizeMin, 4, size, type, stride,
+                                  GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_TEX(unit), format, 4, size, type,
+                stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
 }
 
 
@@ -1026,7 +1247,31 @@ void GLAPIENTRY
 _mesa_VertexArrayEdgeFlagOffsetEXT(GLuint vaobj, GLuint buffer, GLsizei stride,
                                    GLintptr offset)
 {
+   /* this is the same type that glEdgeFlag uses */
+   const GLboolean integer = GL_FALSE;
+   GET_CURRENT_CONTEXT(ctx);
+
+   GLenum format = GL_RGBA;
+   const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayEdgeFlagOffsetEXT"))
+      return;
 
+   if (!validate_array_and_format(ctx, "glVertexArrayEdgeFlagOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_EDGEFLAG, legalTypes,
+                                  1, 1, 1, GL_UNSIGNED_BYTE, stride,
+                                  GL_FALSE, integer, GL_FALSE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
+                stride, GL_FALSE, integer, GL_FALSE, (void*) offset);
 }
 
 
@@ -1128,7 +1373,74 @@ _mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index
                                        GLenum type, GLboolean normalized,
                                        GLsizei stride, GLintptr offset)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayVertexAttribOffsetEXT"))
+      return;
+
+   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribOffsetEXT(idx)");
+      return;
+   }
+
+   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
+                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
+                                  INT_BIT | UNSIGNED_INT_BIT |
+                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+                                  FIXED_ES_BIT | FIXED_GL_BIT |
+                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
+                                  INT_2_10_10_10_REV_BIT |
+                                  UNSIGNED_INT_10F_11F_11F_REV_BIT);
+
+   if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_GENERIC(index), legalTypes,
+                                  1, BGRA_OR_4, size, type, stride,
+                                  normalized, GL_FALSE, GL_FALSE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
+                size, type, stride, normalized, GL_FALSE, GL_FALSE, (void*) offset);
+}
+
+
+void GLAPIENTRY
+_mesa_VertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
+                                        GLenum type, GLsizei stride, GLintptr offset)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLenum format = GL_RGBA;
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayVertexAttribLOffsetEXT"))
+      return;
+
+   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribLOffsetEXT(idx)");
+      return;
+   }
 
+   const GLbitfield legalTypes = DOUBLE_BIT;
+
+   if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribLOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_GENERIC(index), legalTypes,
+                                  1, 4, size, type, stride,
+                                  GL_FALSE, GL_FALSE, GL_TRUE, format, (void*) offset))
+      return;
+
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_GENERIC(index), format, 4,
+                size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, (void*) offset);
 }
 
 
@@ -1199,7 +1511,38 @@ void GLAPIENTRY
 _mesa_VertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
                                         GLenum type, GLsizei stride, GLintptr offset)
 {
+   const GLboolean normalized = GL_FALSE;
+   const GLboolean integer = GL_TRUE;
+   GET_CURRENT_CONTEXT(ctx);
+   GLenum format = GL_RGBA;
+
+   struct gl_vertex_array_object* vao;
+   struct gl_buffer_object* vbo;
+
+   if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
+                                &vao, &vbo,
+                                "glVertexArrayVertexAttribIOffsetEXT"))
+      return;
+
+   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribIOffsetEXT(index)");
+      return;
+   }
+
+   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
+                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
+                                  INT_BIT | UNSIGNED_INT_BIT);
+
+   if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribIOffsetEXT",
+                                  vao, vbo,
+                                  VERT_ATTRIB_GENERIC(index), legalTypes,
+                                  1, 4, size, type, stride,
+                                  normalized, integer, GL_FALSE, format, (void*) offset))
+      return;
 
+   update_array(ctx, vao, vbo,
+                VERT_ATTRIB_GENERIC(index), format, 4,  size, type,
+                stride, normalized, integer, GL_FALSE, (void*) offset);
 }
 
 
@@ -1304,6 +1647,19 @@ _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
    enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
 }
 
+void GLAPIENTRY
+_mesa_EnableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
+                                                             true,
+                                                             "glEnableVertexArrayAttribEXT");
+   if (!vao)
+      return;
+
+   enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttribEXT");
+}
+
 
 void GLAPIENTRY
 _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
@@ -1386,6 +1742,25 @@ _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
    _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
 }
 
+void GLAPIENTRY
+_mesa_DisableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
+                                                             true,
+                                                             "glEnableVertexArrayAttribEXT");
+   if (!vao)
+      return;
+
+   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
+      return;
+   }
+
+   const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
+   _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
+}
+
 
 void GLAPIENTRY
 _mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
@@ -2676,7 +3051,7 @@ vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
        *   VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
        *   zero or] the name of an existing vertex array object."
        */
-      vao = _mesa_lookup_vao_err(ctx, false, vaobj, func);
+      vao = _mesa_lookup_vao_err(ctx, vaobj, false, func);
       if (!vao)
          return;
 
@@ -3040,3 +3415,266 @@ _mesa_free_varray_data(struct gl_context *ctx)
    _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
    _mesa_DeleteHashTable(ctx->Array.Objects);
 }
+
+void GLAPIENTRY
+_mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao;
+   void* ptr;
+
+   vao = _mesa_lookup_vao_err(ctx, vaobj, true,
+                              "glGetVertexArrayIntegervEXT");
+   if (!vao)
+      return;
+
+   /* The EXT_direct_state_access spec says:
+    *
+    *    "For GetVertexArrayIntegervEXT, pname must be one of the "Get value" tokens
+    *    in tables 6.6, 6.7, 6.8, and 6.9 that use GetIntegerv, IsEnabled, or
+    *    GetPointerv for their "Get command" (so excluding the VERTEX_ATTRIB_*
+    *    tokens)."
+    */
+   switch (pname) {
+      /* Tokens using GetIntegerv */
+      case GL_CLIENT_ACTIVE_TEXTURE:
+         *param = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
+         break;
+      case GL_VERTEX_ARRAY_SIZE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Size;
+         break;
+      case GL_VERTEX_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Type;
+         break;
+      case GL_VERTEX_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_POS].Stride;
+         break;
+      case GL_VERTEX_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_POS].BufferObj->Name;
+         break;
+      case GL_COLOR_ARRAY_SIZE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Size;
+         break;
+      case GL_COLOR_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type;
+         break;
+      case GL_COLOR_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Stride;
+         break;
+      case GL_COLOR_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_COLOR0].BufferObj->Name;
+         break;
+      case GL_EDGE_FLAG_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Stride;
+         break;
+      case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_EDGEFLAG].BufferObj->Name;
+         break;
+      case GL_INDEX_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type;
+         break;
+      case GL_INDEX_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride;
+         break;
+      case GL_INDEX_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_COLOR_INDEX].BufferObj->Name;
+         break;
+      case GL_NORMAL_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type;
+         break;
+      case GL_NORMAL_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Stride;
+         break;
+      case GL_NORMAL_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_NORMAL].BufferObj->Name;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Size;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Type;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Stride;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
+         break;
+      case GL_FOG_COORD_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Format.Type;
+         break;
+      case GL_FOG_COORD_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Stride;
+         break;
+      case GL_FOG_COORD_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_FOG].BufferObj->Name;
+         break;
+      case GL_SECONDARY_COLOR_ARRAY_SIZE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Size;
+         break;
+      case GL_SECONDARY_COLOR_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type;
+         break;
+      case GL_SECONDARY_COLOR_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Stride;
+         break;
+      case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_COLOR1].BufferObj->Name;
+         break;
+
+      /* Tokens using IsEnabled */
+      case GL_VERTEX_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_POS);
+         break;
+      case GL_COLOR_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_COLOR0);
+         break;
+      case GL_EDGE_FLAG_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_EDGEFLAG);
+         break;
+      case GL_INDEX_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_COLOR_INDEX);
+         break;
+      case GL_NORMAL_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_NORMAL);
+         break;
+      case GL_TEXTURE_COORD_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_TEX(ctx->Array.ActiveTexture));
+         break;
+      case GL_FOG_COORD_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_FOG);
+         break;
+      case GL_SECONDARY_COLOR_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_COLOR1);
+         break;
+
+      /* Tokens using GetPointerv */
+      case GL_VERTEX_ARRAY_POINTER:
+      case GL_COLOR_ARRAY_POINTER:
+      case GL_EDGE_FLAG_ARRAY_POINTER:
+      case GL_INDEX_ARRAY_POINTER:
+      case GL_NORMAL_ARRAY_POINTER:
+      case GL_TEXTURE_COORD_ARRAY_POINTER:
+      case GL_FOG_COORD_ARRAY_POINTER:
+      case GL_SECONDARY_COLOR_ARRAY_POINTER:
+         _get_vao_pointerv(pname, vao, &ptr, "glGetVertexArrayIntegervEXT");
+         *param = (int) ((uint64_t) ptr & 0xFFFFFFFF);
+         break;
+
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIntegervEXT(pname)");
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, GLvoid** param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao;
+
+   vao = _mesa_lookup_vao_err(ctx, vaobj, true,
+                              "glGetVertexArrayPointervEXT");
+   if (!vao)
+      return;
+
+   /* The EXT_direct_state_access spec says:
+    *
+    *     "For GetVertexArrayPointervEXT, pname must be a *_ARRAY_POINTER token from
+    *     tables 6.6, 6.7, and 6.8 excluding VERTEX_ATTRIB_ARRAY_POINT."
+    */
+   switch (pname) {
+      case GL_VERTEX_ARRAY_POINTER:
+      case GL_COLOR_ARRAY_POINTER:
+      case GL_EDGE_FLAG_ARRAY_POINTER:
+      case GL_INDEX_ARRAY_POINTER:
+      case GL_NORMAL_ARRAY_POINTER:
+      case GL_TEXTURE_COORD_ARRAY_POINTER:
+      case GL_FOG_COORD_ARRAY_POINTER:
+      case GL_SECONDARY_COLOR_ARRAY_POINTER:
+         break;
+
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointervEXT(pname)");
+         return;
+   }
+
+   /* pname has been validated, we can now use the helper function */
+   _get_vao_pointerv(pname, vao, param, "glGetVertexArrayPointervEXT");
+}
+
+void GLAPIENTRY
+_mesa_GetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao;
+
+   vao = _mesa_lookup_vao_err(ctx, vaobj, true,
+                              "glGetVertexArrayIntegeri_vEXT");
+   if (!vao)
+      return;
+
+
+   /* The EXT_direct_state_access spec says:
+    *
+    *    "For GetVertexArrayIntegeri_vEXT, pname must be one of the
+    *    "Get value" tokens in tables 6.8 and 6.9 that use GetVertexAttribiv
+    *    or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_*
+    *    tokens) or a token of the form TEXTURE_COORD_ARRAY (the enable) or
+    *    TEXTURE_COORD_ARRAY_*; index identifies the vertex attribute
+    *    array to query or texture coordinate set index respectively."
+    */
+
+   switch (pname) {
+      case GL_TEXTURE_COORD_ARRAY:
+         *param = !!(vao->Enabled & VERT_BIT_TEX(index));
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Size;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Type;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Stride;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+         *param = vao->BufferBinding[VERT_ATTRIB_TEX(index)].BufferObj->Name;
+         break;
+      default:
+         *param = get_vertex_array_attrib(ctx, vao, index, pname, "glGetVertexArrayIntegeri_vEXT");
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLvoid** param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_vertex_array_object* vao;
+
+   vao = _mesa_lookup_vao_err(ctx, vaobj, true,
+                              "glGetVertexArrayPointeri_vEXT");
+   if (!vao)
+      return;
+
+   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayPointeri_vEXT(index)");
+      return;
+   }
+
+   /* The EXT_direct_state_access spec says:
+    *
+    *     "For GetVertexArrayPointeri_vEXT, pname must be VERTEX_ATTRIB_ARRAY_POINTER
+    *     or TEXTURE_COORD_ARRAY_POINTER with the index parameter indicating the vertex
+    *     attribute or texture coordindate set index."
+    */
+   switch(pname) {
+      case GL_VERTEX_ATTRIB_ARRAY_POINTER:
+         *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_POINTER:
+         *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Ptr;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointeri_vEXT(pname)");
+   }
+}