X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fvarray.c;h=3c9c6f3d31ad11db02c71cb0872258d2ebcdad39;hp=e6057c7f88153f89bef530010a40e825d5794cb2;hb=e5339fe4a47c242693962c9f90bbab8b74935cba;hpb=e727f8c8b814b9c36d4a8b52829c2bf7281765be diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index e6057c7f881..3c9c6f3d31a 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -28,7 +28,7 @@ #include /* for PRId64 macro */ #include "glheader.h" -#include "imports.h" +#include "util/imports.h" #include "bufferobj.h" #include "context.h" #include "enable.h" @@ -40,6 +40,7 @@ #include "mtypes.h" #include "varray.h" #include "arrayobj.h" +#include "get.h" #include "main/dispatch.h" @@ -173,14 +174,17 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx, else vao->VertexAttribBufferMask &= ~array_bit; + if (vao->BufferBinding[bindingIndex].InstanceDivisor) + vao->NonZeroDivisorMask |= array_bit; + else + vao->NonZeroDivisorMask &= ~array_bit; + vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit; vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit; array->BufferBindingIndex = bindingIndex; vao->NewArrays |= vao->Enabled & array_bit; - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; } } @@ -200,6 +204,20 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, assert(!vao->SharedAndImmutable); struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index]; + if (ctx->Const.VertexBufferOffsetIsInt32 && (int)offset < 0 && + _mesa_is_bufferobj(vbo)) { + /* The offset will be interpreted as a signed int, so make sure + * the user supplied offset is not negative (driver limitation). + */ + _mesa_warning(ctx, "Received negative int32 vertex buffer offset. " + "(driver limitation)\n"); + + /* We can't disable this binding, so use a non-negative offset value + * instead. + */ + offset = 0; + } + if (binding->BufferObj != vbo || binding->Offset != offset || binding->Stride != stride) { @@ -217,8 +235,6 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, } vao->NewArrays |= vao->Enabled & binding->_BoundArrays; - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; } } @@ -239,12 +255,269 @@ vertex_binding_divisor(struct gl_context *ctx, if (binding->InstanceDivisor != divisor) { binding->InstanceDivisor = divisor; + + if (divisor) + vao->NonZeroDivisorMask |= binding->_BoundArrays; + else + vao->NonZeroDivisorMask &= ~binding->_BoundArrays; + vao->NewArrays |= vao->Enabled & binding->_BoundArrays; - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; } } +/* vertex_formats[gltype - GL_BYTE][integer*2 + normalized][size - 1] */ +static const uint16_t vertex_formats[][4][4] = { + { /* GL_BYTE */ + { + PIPE_FORMAT_R8_SSCALED, + PIPE_FORMAT_R8G8_SSCALED, + PIPE_FORMAT_R8G8B8_SSCALED, + PIPE_FORMAT_R8G8B8A8_SSCALED + }, + { + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM + }, + { + PIPE_FORMAT_R8_SINT, + PIPE_FORMAT_R8G8_SINT, + PIPE_FORMAT_R8G8B8_SINT, + PIPE_FORMAT_R8G8B8A8_SINT + }, + }, + { /* GL_UNSIGNED_BYTE */ + { + PIPE_FORMAT_R8_USCALED, + PIPE_FORMAT_R8G8_USCALED, + PIPE_FORMAT_R8G8B8_USCALED, + PIPE_FORMAT_R8G8B8A8_USCALED + }, + { + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM + }, + { + PIPE_FORMAT_R8_UINT, + PIPE_FORMAT_R8G8_UINT, + PIPE_FORMAT_R8G8B8_UINT, + PIPE_FORMAT_R8G8B8A8_UINT + }, + }, + { /* GL_SHORT */ + { + PIPE_FORMAT_R16_SSCALED, + PIPE_FORMAT_R16G16_SSCALED, + PIPE_FORMAT_R16G16B16_SSCALED, + PIPE_FORMAT_R16G16B16A16_SSCALED + }, + { + PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM + }, + { + PIPE_FORMAT_R16_SINT, + PIPE_FORMAT_R16G16_SINT, + PIPE_FORMAT_R16G16B16_SINT, + PIPE_FORMAT_R16G16B16A16_SINT + }, + }, + { /* GL_UNSIGNED_SHORT */ + { + PIPE_FORMAT_R16_USCALED, + PIPE_FORMAT_R16G16_USCALED, + PIPE_FORMAT_R16G16B16_USCALED, + PIPE_FORMAT_R16G16B16A16_USCALED + }, + { + PIPE_FORMAT_R16_UNORM, + PIPE_FORMAT_R16G16_UNORM, + PIPE_FORMAT_R16G16B16_UNORM, + PIPE_FORMAT_R16G16B16A16_UNORM + }, + { + PIPE_FORMAT_R16_UINT, + PIPE_FORMAT_R16G16_UINT, + PIPE_FORMAT_R16G16B16_UINT, + PIPE_FORMAT_R16G16B16A16_UINT + }, + }, + { /* GL_INT */ + { + PIPE_FORMAT_R32_SSCALED, + PIPE_FORMAT_R32G32_SSCALED, + PIPE_FORMAT_R32G32B32_SSCALED, + PIPE_FORMAT_R32G32B32A32_SSCALED + }, + { + PIPE_FORMAT_R32_SNORM, + PIPE_FORMAT_R32G32_SNORM, + PIPE_FORMAT_R32G32B32_SNORM, + PIPE_FORMAT_R32G32B32A32_SNORM + }, + { + PIPE_FORMAT_R32_SINT, + PIPE_FORMAT_R32G32_SINT, + PIPE_FORMAT_R32G32B32_SINT, + PIPE_FORMAT_R32G32B32A32_SINT + }, + }, + { /* GL_UNSIGNED_INT */ + { + PIPE_FORMAT_R32_USCALED, + PIPE_FORMAT_R32G32_USCALED, + PIPE_FORMAT_R32G32B32_USCALED, + PIPE_FORMAT_R32G32B32A32_USCALED + }, + { + PIPE_FORMAT_R32_UNORM, + PIPE_FORMAT_R32G32_UNORM, + PIPE_FORMAT_R32G32B32_UNORM, + PIPE_FORMAT_R32G32B32A32_UNORM + }, + { + PIPE_FORMAT_R32_UINT, + PIPE_FORMAT_R32G32_UINT, + PIPE_FORMAT_R32G32B32_UINT, + PIPE_FORMAT_R32G32B32A32_UINT + }, + }, + { /* GL_FLOAT */ + { + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT + }, + { + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT + }, + }, + {{0}}, /* GL_2_BYTES */ + {{0}}, /* GL_3_BYTES */ + {{0}}, /* GL_4_BYTES */ + { /* GL_DOUBLE */ + { + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT + }, + { + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT + }, + }, + { /* GL_HALF_FLOAT */ + { + PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R16G16B16_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT + }, + { + PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R16G16B16_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT + }, + }, + { /* GL_FIXED */ + { + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED + }, + { + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED + }, + }, +}; + +/** + * Return a PIPE_FORMAT_x for the given GL datatype and size. + */ +static enum pipe_format +vertex_format_to_pipe_format(GLubyte size, GLenum16 type, GLenum16 format, + GLboolean normalized, GLboolean integer, + GLboolean doubles) +{ + assert(size >= 1 && size <= 4); + assert(format == GL_RGBA || format == GL_BGRA); + + /* 64-bit attributes are translated by drivers. */ + if (doubles) + return PIPE_FORMAT_NONE; + + switch (type) { + case GL_HALF_FLOAT_OES: + type = GL_HALF_FLOAT; + break; + + case GL_INT_2_10_10_10_REV: + assert(size == 4 && !integer); + + if (format == GL_BGRA) { + if (normalized) + return PIPE_FORMAT_B10G10R10A2_SNORM; + else + return PIPE_FORMAT_B10G10R10A2_SSCALED; + } else { + if (normalized) + return PIPE_FORMAT_R10G10B10A2_SNORM; + else + return PIPE_FORMAT_R10G10B10A2_SSCALED; + } + break; + + case GL_UNSIGNED_INT_2_10_10_10_REV: + assert(size == 4 && !integer); + + if (format == GL_BGRA) { + if (normalized) + return PIPE_FORMAT_B10G10R10A2_UNORM; + else + return PIPE_FORMAT_B10G10R10A2_USCALED; + } else { + if (normalized) + return PIPE_FORMAT_R10G10B10A2_UNORM; + else + return PIPE_FORMAT_R10G10B10A2_USCALED; + } + break; + + case GL_UNSIGNED_INT_10F_11F_11F_REV: + assert(size == 3 && !integer && format == GL_RGBA); + return PIPE_FORMAT_R11G11B10_FLOAT; + + case GL_UNSIGNED_BYTE: + if (format == GL_BGRA) { + /* this is an odd-ball case */ + assert(normalized); + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + break; + } + + unsigned index = integer*2 + normalized; + assert(index <= 2); + assert(type >= GL_BYTE && type <= GL_FIXED); + return vertex_formats[type - GL_BYTE][index][size-1]; +} void _mesa_set_vertex_format(struct gl_vertex_format *vertex_format, @@ -261,6 +534,9 @@ _mesa_set_vertex_format(struct gl_vertex_format *vertex_format, vertex_format->Doubles = doubles; vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type); assert(vertex_format->_ElementSize <= 4*sizeof(double)); + vertex_format->_PipeFormat = + vertex_format_to_pipe_format(size, type, format, normalized, integer, + doubles); } @@ -360,8 +636,6 @@ _mesa_update_array_format(struct gl_context *ctx, normalized, integer, doubles); vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; } /** @@ -492,6 +766,8 @@ validate_array_format(struct gl_context *ctx, const char *func, * Do error checking for glVertex/Color/TexCoord/...Pointer functions. * * \param func name of calling function used for error reporting + * \param vao the vao to update + * \param obj the bound buffer object * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value @@ -506,14 +782,14 @@ validate_array_format(struct gl_context *ctx, const char *func, */ static void validate_array(struct gl_context *ctx, const char *func, + struct gl_vertex_array_object *vao, + struct gl_buffer_object *obj, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, GLboolean doubles, const GLvoid *ptr) { - struct gl_vertex_array_object *vao = ctx->Array.VAO; - /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says: * * "Client vertex arrays - all vertex array attribute pointers must @@ -555,7 +831,7 @@ validate_array(struct gl_context *ctx, const char *func, * 2.9.6), and the pointer argument is not NULL." */ if (ptr != NULL && vao != ctx->Array.DefaultVAO && - !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { + !_mesa_is_bufferobj(obj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); return; } @@ -564,15 +840,16 @@ validate_array(struct gl_context *ctx, const char *func, static bool validate_array_and_format(struct gl_context *ctx, const char *func, + struct gl_vertex_array_object *vao, + struct gl_buffer_object *obj, GLuint attrib, GLbitfield legalTypes, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, - GLboolean doubles, GLenum format, const GLvoid *ptr, - struct gl_vertex_array_object *vao) + GLboolean doubles, GLenum format, const GLvoid *ptr) { - validate_array(ctx, func, attrib, legalTypes, sizeMin, sizeMax, size, - type, stride, normalized, integer, doubles, ptr); + validate_array(ctx, func, vao, obj, attrib, legalTypes, sizeMin, sizeMax, + size, type, stride, normalized, integer, doubles, ptr); return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin, sizeMax, size, type, normalized, integer, @@ -583,6 +860,8 @@ validate_array_and_format(struct gl_context *ctx, const char *func, /** * Update state for glVertex/Color/TexCoord/...Pointer functions. * + * \param vao the vao to update + * \param obj the bound buffer object * \param attrib the attribute array index to update * \param format Either GL_RGBA or GL_BGRA. * \param sizeMax max allowable size value (may also be BGRA_OR_4) @@ -596,14 +875,14 @@ validate_array_and_format(struct gl_context *ctx, const char *func, */ static void update_array(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + struct gl_buffer_object *obj, GLuint attrib, GLenum format, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, GLboolean doubles, const GLvoid *ptr) { - struct gl_vertex_array_object *vao = ctx->Array.VAO; - _mesa_update_array_format(ctx, vao, attrib, size, type, format, normalized, integer, doubles, 0); @@ -624,17 +903,50 @@ update_array(struct gl_context *ctx, GLsizei effectiveStride = stride != 0 ? stride : array->Format._ElementSize; _mesa_bind_vertex_buffer(ctx, vao, attrib, - ctx->Array.ArrayBufferObj, (GLintptr) ptr, + obj, (GLintptr) ptr, effectiveStride); } + +/* Helper function for all EXT_direct_state_access glVertexArray* functions */ +static bool +_lookup_vao_and_vbo_dsa(struct gl_context *ctx, + GLuint vaobj, GLuint buffer, + GLintptr offset, + struct gl_vertex_array_object** vao, + struct gl_buffer_object** vbo, + const char* caller) +{ + *vao = _mesa_lookup_vao_err(ctx, vaobj, true, caller); + if (!(*vao)) + return false; + + if (buffer != 0) { + *vbo = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller)) + return false; + + if (offset < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(negative offset with non-0 buffer)", caller); + return false; + } + } else { + *vbo = ctx->Shared->NullBufferObj; + } + + return true; +} + + void GLAPIENTRY _mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -652,23 +964,61 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) UNSIGNED_INT_2_10_10_10_REV_BIT | INT_2_10_10_10_REV_BIT); - if (!validate_array_and_format(ctx, "glVertexPointer", VERT_ATTRIB_POS, - legalTypes, 2, 4, size, type, stride, - GL_FALSE, GL_FALSE, GL_FALSE, format, - ptr, ctx->Array.VAO)) + if (!validate_array_and_format(ctx, "glVertexPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_POS, legalTypes, 2, 4, size, + type, stride, GL_FALSE, GL_FALSE, GL_FALSE, + format, ptr)) return; - update_array(ctx, VERT_ATTRIB_POS, format, 4, size, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_POS, format, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr ) { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } @@ -687,16 +1037,53 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) INT_2_10_10_10_REV_BIT); if (!validate_array_and_format(ctx, "glNormalPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, type, stride, GL_TRUE, GL_FALSE, - GL_FALSE, format, ptr, ctx->Array.VAO)) + GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) @@ -704,7 +1091,8 @@ _mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride, GET_CURRENT_CONTEXT(ctx); GLenum format = get_array_format(ctx, BGRA_OR_4, &size); - update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } @@ -726,23 +1114,63 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) INT_2_10_10_10_REV_BIT); if (!validate_array_and_format(ctx, "glColorPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_COLOR0, legalTypes, sizeMin, BGRA_OR_4, size, type, stride, GL_TRUE, - GL_FALSE, GL_FALSE, format, ptr, - ctx->Array.VAO)) + GL_FALSE, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -756,22 +1184,55 @@ _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); if (!validate_array_and_format(ctx, "glFogCoordPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_FOG, legalTypes, 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, - GL_FALSE, format, ptr, ctx->Array.VAO)) + GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -786,17 +1247,49 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) FLOAT_BIT | DOUBLE_BIT); if (!validate_array_and_format(ctx, "glIndexPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_COLOR_INDEX, legalTypes, 1, 1, 1, type, stride, - GL_FALSE, GL_FALSE, GL_FALSE, format, - ptr, ctx->Array.VAO)) + GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_SecondaryColorPointer_no_error(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) @@ -804,7 +1297,8 @@ _mesa_SecondaryColorPointer_no_error(GLint size, GLenum type, GET_CURRENT_CONTEXT(ctx); GLenum format = get_array_format(ctx, BGRA_OR_4, &size); - update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } @@ -824,17 +1318,53 @@ _mesa_SecondaryColorPointer(GLint size, GLenum type, INT_2_10_10_10_REV_BIT); if (!validate_array_and_format(ctx, "glSecondaryColorPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_COLOR1, legalTypes, 3, BGRA_OR_4, size, type, stride, - GL_TRUE, GL_FALSE, GL_FALSE, format, ptr, - ctx->Array.VAO)) + GL_TRUE, GL_FALSE, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) @@ -842,7 +1372,8 @@ _mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride, GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; - update_array(ctx, VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -864,17 +1395,99 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, INT_2_10_10_10_REV_BIT); if (!validate_array_and_format(ctx, "glTexCoordPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_TEX(unit), legalTypes, sizeMin, 4, size, type, stride, - GL_FALSE, GL_FALSE, GL_FALSE, format, ptr, - ctx->Array.VAO)) + GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_TEX(unit), format, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_TEX(unit), format, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } +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); +} + + +void GLAPIENTRY +_mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texunit, + 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); +} + + void GLAPIENTRY _mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr) { @@ -882,7 +1495,8 @@ _mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr) const GLboolean integer = GL_FALSE; GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, GL_FALSE, ptr); } @@ -898,24 +1512,58 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; if (!validate_array_and_format(ctx, "glEdgeFlagPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_EDGEFLAG, legalTypes, 1, 1, 1, GL_UNSIGNED_BYTE, stride, - GL_FALSE, integer, GL_FALSE, format, ptr, - ctx->Array.VAO)) + GL_FALSE, integer, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, GL_FALSE, ptr); } +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); +} + + void GLAPIENTRY _mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -935,12 +1583,14 @@ _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr) const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT); if (!validate_array_and_format(ctx, "glPointSizePointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_POINT_SIZE, legalTypes, 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, - GL_FALSE, format, ptr, ctx->Array.VAO)) + GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -953,7 +1603,8 @@ _mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type, GET_CURRENT_CONTEXT(ctx); GLenum format = get_array_format(ctx, BGRA_OR_4, &size); - update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); } @@ -986,17 +1637,94 @@ _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type, UNSIGNED_INT_10F_11F_11F_REV_BIT); if (!validate_array_and_format(ctx, "glVertexAttribPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_GENERIC(index), legalTypes, 1, BGRA_OR_4, size, type, stride, - normalized, GL_FALSE, GL_FALSE, format, - ptr, ctx->Array.VAO)) + normalized, GL_FALSE, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, + 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); +} + + void GLAPIENTRY _mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) @@ -1005,7 +1733,8 @@ _mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type, const GLboolean integer = GL_TRUE; GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, stride, normalized, integer, GL_FALSE, ptr); } @@ -1035,13 +1764,14 @@ _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, INT_BIT | UNSIGNED_INT_BIT); if (!validate_array_and_format(ctx, "glVertexAttribIPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_GENERIC(index), legalTypes, 1, 4, size, type, stride, - normalized, integer, GL_FALSE, format, - ptr, ctx->Array.VAO)) + normalized, integer, GL_FALSE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), format, 4, size, type, stride, normalized, integer, GL_FALSE, ptr); } @@ -1052,11 +1782,51 @@ _mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type, { GET_CURRENT_CONTEXT(ctx); - update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); } +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); +} + + void GLAPIENTRY _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) @@ -1072,13 +1842,14 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, const GLbitfield legalTypes = DOUBLE_BIT; if (!validate_array_and_format(ctx, "glVertexAttribLPointer", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, VERT_ATTRIB_GENERIC(index), legalTypes, 1, 4, size, type, stride, - GL_FALSE, GL_FALSE, GL_TRUE, format, - ptr, ctx->Array.VAO)) + GL_FALSE, GL_FALSE, GL_TRUE, format, ptr)) return; - update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type, + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_GENERIC(index), format, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); } @@ -1098,9 +1869,6 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx, vao->Enabled |= attrib_bits; vao->NewArrays |= attrib_bits; - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; - /* Update the map mode if needed */ if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) update_attribute_map_mode(ctx, vao); @@ -1153,13 +1921,26 @@ _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index) * [compatibility profile: zero or] the name of an existing vertex * array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glEnableVertexArrayAttrib"); if (!vao) return; 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) @@ -1185,9 +1966,6 @@ _mesa_disable_vertex_array_attribs(struct gl_context *ctx, vao->Enabled &= ~attrib_bits; vao->NewArrays |= attrib_bits; - if (vao == ctx->Array.VAO) - ctx->NewState |= _NEW_ARRAY; - /* Update the map mode if needed */ if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) update_attribute_map_mode(ctx, vao); @@ -1232,7 +2010,26 @@ _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index) * [compatibility profile: zero or] the name of an existing vertex * array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glDisableVertexArrayAttrib"); + 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_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; @@ -1539,7 +2336,7 @@ _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index, * [compatibility profile: zero or] the name of an existing * vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexediv"); if (!vao) return; @@ -1602,7 +2399,7 @@ _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, * [compatibility profile: zero or] the name of an existing * vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexed64iv"); if (!vao) return; @@ -1687,6 +2484,33 @@ _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, } +void GLAPIENTRY +_mesa_MultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + const GLint sizeMin = 1; + const GLuint unit = texunit - GL_TEXTURE0; + + GLenum format = GL_RGBA; + const GLbitfield legalTypes = (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); + + if (!validate_array_and_format(ctx, "glMultiTexCoordPointerEXT", + ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_TEX(unit), legalTypes, + sizeMin, 4, size, type, stride, + GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) + return; + + update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, + VERT_ATTRIB_TEX(unit), format, 4, size, type, + stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); +} + + void GLAPIENTRY _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) { @@ -1894,8 +2718,6 @@ _mesa_LockArraysEXT(GLint first, GLsizei count) ctx->Array.LockFirst = first; ctx->Array.LockCount = count; - - ctx->NewState |= _NEW_ARRAY; } @@ -1914,7 +2736,6 @@ _mesa_UnlockArraysEXT( void ) ctx->Array.LockFirst = 0; ctx->Array.LockCount = 0; - ctx->NewState |= _NEW_ARRAY; } @@ -2018,6 +2839,55 @@ _mesa_VertexAttribDivisor(GLuint index, GLuint divisor) } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor) +{ + GET_CURRENT_CONTEXT(ctx); + + const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); + struct gl_vertex_array_object * vao; + /* The ARB_instanced_arrays spec says: + * + * "The vertex array object named by vaobj must + * be generated by GenVertexArrays (and not since deleted); + * otherwise an INVALID_OPERATION error is generated." + */ + vao = _mesa_lookup_vao_err(ctx, vaobj, + false, + "glVertexArrayVertexAttribDivisorEXT"); + if (!vao) + return; + + if (!ctx->Extensions.ARB_instanced_arrays) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayVertexAttribDivisorEXT()"); + return; + } + + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glVertexArrayVertexAttribDivisorEXT(index = %u)", index); + return; + } + + assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); + + /* The ARB_vertex_attrib_binding spec says: + * + * "The command + * + * void VertexAttribDivisor(uint index, uint divisor); + * + * is equivalent to (assuming no errors are generated): + * + * VertexAttribBinding(index, index); + * VertexBindingDivisor(index, divisor);" + */ + _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); + vertex_binding_divisor(ctx, vao, genericIndex, divisor); +} + + + static ALWAYS_INLINE void vertex_array_vertex_buffer(struct gl_context *ctx, struct gl_vertex_array_object *vao, @@ -2177,7 +3047,7 @@ _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer, * if is not [compatibility profile: zero or] the name of an * existing vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffer"); if (!vao) return; @@ -2186,6 +3056,21 @@ _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer, } +void GLAPIENTRY +_mesa_VertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingIndex, GLuint buffer, + GLintptr offset, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_vertex_array_object *vao; + vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayBindVertexBufferEXT"); + if (!vao) + return; + + vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset, + stride, "glVertexArrayBindVertexBufferEXT"); +} + + static ALWAYS_INLINE void vertex_array_vertex_buffers(struct gl_context *ctx, struct gl_vertex_array_object *vao, @@ -2383,7 +3268,7 @@ _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, * if is not [compatibility profile: zero or] the name of an * existing vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffers"); if (!vao) return; @@ -2487,8 +3372,8 @@ _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type, static void -vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size, - GLenum type, GLboolean normalized, +vertex_array_attrib_format(GLuint vaobj, bool isExtDsa, GLuint attribIndex, + GLint size, GLenum type, GLboolean normalized, GLboolean integer, GLboolean doubles, GLbitfield legalTypes, GLsizei sizeMax, GLuint relativeOffset, const char *func) @@ -2505,13 +3390,7 @@ vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size, if (!vao) return; } else { - /* The ARB_direct_state_access spec says: - * - * "An INVALID_OPERATION error is generated by - * VertexArrayAttrib*Format if is not [compatibility profile: - * zero or] the name of an existing vertex array object." - */ - vao = _mesa_lookup_vao_err(ctx, vaobj, func); + vao = _mesa_lookup_vao_err(ctx, vaobj, isExtDsa, func); if (!vao) return; @@ -2547,37 +3426,73 @@ _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size, GLenum type, GLboolean normalized, GLuint relativeOffset) { - vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized, + vertex_array_attrib_format(vaobj, false, attribIndex, size, type, normalized, GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, BGRA_OR_4, relativeOffset, "glVertexArrayAttribFormat"); } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribIndex, GLint size, + GLenum type, GLboolean normalized, + GLuint relativeOffset) +{ + vertex_array_attrib_format(vaobj, true, attribIndex, size, type, normalized, + GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, + BGRA_OR_4, relativeOffset, + "glVertexArrayVertexAttribFormatEXT"); +} + + void GLAPIENTRY _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex, GLint size, GLenum type, GLuint relativeOffset) { - vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE, + vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE, GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4, relativeOffset, "glVertexArrayAttribIFormat"); } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribIndex, + GLint size, GLenum type, + GLuint relativeOffset) +{ + vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE, + GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, + 4, relativeOffset, + "glVertexArrayVertexAttribIFormatEXT"); +} + + void GLAPIENTRY _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex, GLint size, GLenum type, GLuint relativeOffset) { - vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE, + vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE, GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4, relativeOffset, "glVertexArrayAttribLFormat"); } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribIndex, + GLint size, GLenum type, + GLuint relativeOffset) +{ + vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE, + GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, + 4, relativeOffset, + "glVertexArrayVertexAttribLFormatEXT"); +} + + static void vertex_array_attrib_binding(struct gl_context *ctx, struct gl_vertex_array_object *vao, @@ -2675,7 +3590,7 @@ _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingI * if is not [compatibility profile: zero or] the name of an * existing vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayAttribBinding"); if (!vao) return; @@ -2684,6 +3599,20 @@ _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingI } +void GLAPIENTRY +_mesa_VertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_vertex_array_object *vao; + vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexAttribBindingEXT"); + if (!vao) + return; + + vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex, + "glVertexArrayVertexAttribBindingEXT"); +} + + static void vertex_array_binding_divisor(struct gl_context *ctx, struct gl_vertex_array_object *vao, @@ -2770,7 +3699,7 @@ _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, * if is not [compatibility profile: zero or] the name of an * existing vertex array object." */ - vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor"); + vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayBindingDivisor"); if (!vao) return; @@ -2779,6 +3708,28 @@ _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, } +void GLAPIENTRY +_mesa_VertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingIndex, + GLuint divisor) +{ + struct gl_vertex_array_object *vao; + GET_CURRENT_CONTEXT(ctx); + + /* The ARB_direct_state_access specification says: + * + * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor + * if is not [compatibility profile: zero or] the name of an + * existing vertex array object." + */ + vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexBindingDivisorEXT"); + if (!vao) + return; + + vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor, + "glVertexArrayVertexBindingDivisorEXT"); +} + + void _mesa_copy_vertex_attrib_array(struct gl_context *ctx, struct gl_array_attributes *dst, @@ -2875,3 +3826,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) ((intptr_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)"); + } +}