X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fvarray.c;h=2f6aefc9ccb86106918e6eadb7959f5fd2239d00;hb=fd6636ebc06d55b59851701c436b8b97f50fd7f4;hp=b268aaa9a3c5f6fc7b67a663da4f6d8376244873;hpb=e8a9473d32149ed0f8b9b188652a7ef951324f72;p=mesa.git diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index b268aaa9a3c..2f6aefc9ccb 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -33,12 +33,14 @@ #include "context.h" #include "enable.h" #include "enums.h" +#include "glformats.h" #include "hash.h" #include "image.h" #include "macros.h" #include "mtypes.h" #include "varray.h" #include "arrayobj.h" +#include "get.h" #include "main/dispatch.h" @@ -141,7 +143,7 @@ update_attribute_map_mode(const struct gl_context *ctx, if (ctx->API != API_OPENGL_COMPAT) return; /* The generic0 attribute superseeds the position attribute */ - const GLbitfield enabled = vao->_Enabled; + const GLbitfield enabled = vao->Enabled; if (enabled & VERT_BIT_GENERIC0) vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0; else if (enabled & VERT_BIT_POS) @@ -155,28 +157,34 @@ update_attribute_map_mode(const struct gl_context *ctx, * Sets the BufferBindingIndex field for the vertex attribute given by * attribIndex. */ -static void -vertex_attrib_binding(struct gl_context *ctx, - struct gl_vertex_array_object *vao, - gl_vert_attrib attribIndex, - GLuint bindingIndex) +void +_mesa_vertex_attrib_binding(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + gl_vert_attrib attribIndex, + GLuint bindingIndex) { struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex]; + assert(!vao->SharedAndImmutable); if (array->BufferBindingIndex != bindingIndex) { const GLbitfield array_bit = VERT_BIT(attribIndex); if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj)) vao->VertexAttribBufferMask |= array_bit; + else + vao->VertexAttribBufferMask &= ~array_bit; - FLUSH_VERTICES(ctx, _NEW_ARRAY); + 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 |= array_bit; + vao->NewArrays |= vao->Enabled & array_bit; } } @@ -193,25 +201,40 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, GLintptr offset, GLsizei stride) { assert(index < ARRAY_SIZE(vao->BufferBinding)); + 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) { - FLUSH_VERTICES(ctx, _NEW_ARRAY); - _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo); binding->Offset = offset; binding->Stride = stride; - if (!_mesa_is_bufferobj(vbo)) + if (!_mesa_is_bufferobj(vbo)) { vao->VertexAttribBufferMask &= ~binding->_BoundArrays; - else + } else { vao->VertexAttribBufferMask |= binding->_BoundArrays; + vbo->UsageHistory |= USAGE_ARRAY_BUFFER; + } - vao->NewArrays |= binding->_BoundArrays; + vao->NewArrays |= vao->Enabled & binding->_BoundArrays; } } @@ -228,12 +251,292 @@ vertex_binding_divisor(struct gl_context *ctx, { struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[bindingIndex]; + assert(!vao->SharedAndImmutable); if (binding->InstanceDivisor != divisor) { - FLUSH_VERTICES(ctx, _NEW_ARRAY); binding->InstanceDivisor = divisor; - vao->NewArrays |= binding->_BoundArrays; + + if (divisor) + vao->NonZeroDivisorMask |= binding->_BoundArrays; + else + vao->NonZeroDivisorMask &= ~binding->_BoundArrays; + + vao->NewArrays |= vao->Enabled & binding->_BoundArrays; + } +} + +/* 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, + GLubyte size, GLenum16 type, GLenum16 format, + GLboolean normalized, GLboolean integer, + GLboolean doubles) +{ + assert(size <= 4); + vertex_format->Type = type; + vertex_format->Format = format; + vertex_format->Size = size; + vertex_format->Normalized = normalized; + vertex_format->Integer = integer; + 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); } @@ -314,8 +617,6 @@ get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size) * \param doubles Double values not reduced to floats * \param relativeOffset Offset of the first element relative to the binding * offset. - * \param flush_verties Should \c FLUSH_VERTICES be invoked before updating - * state? */ void _mesa_update_array_format(struct gl_context *ctx, @@ -326,24 +627,15 @@ _mesa_update_array_format(struct gl_context *ctx, GLuint relativeOffset) { struct gl_array_attributes *const array = &vao->VertexAttrib[attrib]; - GLint elementSize; + assert(!vao->SharedAndImmutable); assert(size <= 4); - elementSize = _mesa_bytes_per_vertex_attrib(size, type); - assert(elementSize != -1); - - array->Size = size; - array->Type = type; - array->Format = format; - array->Normalized = normalized; - array->Integer = integer; - array->Doubles = doubles; array->RelativeOffset = relativeOffset; - array->_ElementSize = elementSize; + _mesa_set_vertex_format(&array->Format, size, type, format, + normalized, integer, doubles); - vao->NewArrays |= VERT_BIT(attrib); - ctx->NewState |= _NEW_ARRAY; + vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); } /** @@ -474,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 @@ -488,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 @@ -517,7 +811,7 @@ validate_array(struct gl_context *ctx, const char *func, return; } - if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 && + if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && stride > ctx->Const.MaxVertexAttribStride) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); @@ -537,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; } @@ -546,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, @@ -565,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) @@ -578,40 +875,78 @@ 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); /* Reset the vertex attrib binding */ - vertex_attrib_binding(ctx, vao, attrib, attrib); + _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib); /* The Stride and Ptr fields are not set by update_array_format() */ struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; array->Stride = stride; + /* For updating the pointer we would need to add the vao->NewArrays flag + * to the VAO. But but that is done already unconditionally in + * _mesa_update_array_format called above. + */ + assert((vao->NewArrays | ~vao->Enabled) & VERT_BIT(attrib)); array->Ptr = ptr; /* Update the vertex buffer binding */ - GLsizei effectiveStride = stride != 0 ? stride : array->_ElementSize; + 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); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -621,8 +956,6 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; GLbitfield legalTypes = (ctx->API == API_OPENGLES) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) @@ -631,24 +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); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -658,8 +1028,6 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; const GLbitfield legalTypes = (ctx->API == API_OPENGLES) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) @@ -669,25 +1037,62 @@ _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) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); 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); } @@ -698,8 +1103,6 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) GET_CURRENT_CONTEXT(ctx); const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; - FLUSH_VERTICES(ctx, 0); - 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) @@ -711,24 +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); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -738,29 +1180,59 @@ _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; 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); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -770,33 +1242,63 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | 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) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); 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); } @@ -807,8 +1309,6 @@ _mesa_SecondaryColorPointer(GLint size, GLenum type, { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = get_array_format(ctx, BGRA_OR_4, &size); const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | SHORT_BIT | UNSIGNED_SHORT_BIT | @@ -818,26 +1318,62 @@ _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) { GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; - FLUSH_VERTICES(ctx, 0); - 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); } @@ -850,8 +1386,6 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; const GLuint unit = ctx->Array.ActiveTexture; - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; const GLbitfield legalTypes = (ctx->API == API_OPENGLES) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) @@ -861,26 +1395,108 @@ _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) { /* this is the same type that glEdgeFlag uses */ const GLboolean integer = GL_FALSE; GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -892,31 +1508,62 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) const GLboolean integer = GL_FALSE; GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; 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); - FLUSH_VERTICES(ctx, 0); - 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); } @@ -926,8 +1573,6 @@ _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - GLenum format = GL_RGBA; if (ctx->API != API_OPENGLES) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -938,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); } @@ -956,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); } @@ -989,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) @@ -1008,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); } @@ -1038,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); } @@ -1055,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) @@ -1075,34 +1842,35 @@ _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); } void -_mesa_enable_vertex_array_attrib(struct gl_context *ctx, - struct gl_vertex_array_object *vao, - gl_vert_attrib attrib) +_mesa_enable_vertex_array_attribs(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + GLbitfield attrib_bits) { - assert(attrib < ARRAY_SIZE(vao->VertexAttrib)); + assert((attrib_bits & ~VERT_BIT_ALL) == 0); + assert(!vao->SharedAndImmutable); - if (!vao->VertexAttrib[attrib].Enabled) { + /* Only work on bits that are disabled */ + attrib_bits &= ~vao->Enabled; + if (attrib_bits) { /* was disabled, now being enabled */ - FLUSH_VERTICES(ctx, _NEW_ARRAY); - vao->VertexAttrib[attrib].Enabled = GL_TRUE; - const GLbitfield array_bit = VERT_BIT(attrib); - vao->_Enabled |= array_bit; - vao->NewArrays |= array_bit; + vao->Enabled |= attrib_bits; + vao->NewArrays |= attrib_bits; /* Update the map mode if needed */ - if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0)) + 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) @@ -1171,22 +1952,22 @@ _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index) void -_mesa_disable_vertex_array_attrib(struct gl_context *ctx, - struct gl_vertex_array_object *vao, - gl_vert_attrib attrib) +_mesa_disable_vertex_array_attribs(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + GLbitfield attrib_bits) { - assert(attrib < ARRAY_SIZE(vao->VertexAttrib)); + assert((attrib_bits & ~VERT_BIT_ALL) == 0); + assert(!vao->SharedAndImmutable); - if (vao->VertexAttrib[attrib].Enabled) { + /* Only work on bits that are enabled */ + attrib_bits &= vao->Enabled; + if (attrib_bits) { /* was enabled, now being disabled */ - FLUSH_VERTICES(ctx, _NEW_ARRAY); - vao->VertexAttrib[attrib].Enabled = GL_FALSE; - const GLbitfield array_bit = VERT_BIT(attrib); - vao->_Enabled &= ~array_bit; - vao->NewArrays |= array_bit; + vao->Enabled &= ~attrib_bits; + vao->NewArrays |= attrib_bits; /* Update the map mode if needed */ - if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0)) + if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) update_attribute_map_mode(ctx, vao); } } @@ -1229,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; @@ -1277,27 +2077,27 @@ get_vertex_array_attrib(struct gl_context *ctx, switch (pname) { case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: - return array->Enabled; + return !!(vao->Enabled & VERT_BIT_GENERIC(index)); case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: - return (array->Format == GL_BGRA) ? GL_BGRA : array->Size; + return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size; case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: return array->Stride; case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: - return array->Type; + return array->Format.Type; case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: - return array->Normalized; + return array->Format.Normalized; case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name; case GL_VERTEX_ATTRIB_ARRAY_INTEGER: if ((_mesa_is_desktop_gl(ctx) && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4)) || _mesa_is_gles3(ctx)) { - return array->Integer; + return array->Format.Integer; } goto error; case GL_VERTEX_ATTRIB_ARRAY_LONG: if (_mesa_is_desktop_gl(ctx)) { - return array->Doubles; + return array->Format.Doubles; } goto error; case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: @@ -1536,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; @@ -1599,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; @@ -1684,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) { @@ -1704,8 +2531,6 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) GLint defstride; /* default stride */ GLint c, f; - FLUSH_VERTICES(ctx, 0); - f = sizeof(GLfloat); c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); @@ -1875,8 +2700,6 @@ _mesa_LockArraysEXT(GLint first, GLsizei count) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); @@ -1895,8 +2718,6 @@ _mesa_LockArraysEXT(GLint first, GLsizei count) ctx->Array.LockFirst = first; ctx->Array.LockCount = count; - - ctx->NewState |= _NEW_ARRAY; } @@ -1905,8 +2726,6 @@ _mesa_UnlockArraysEXT( void ) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glUnlockArrays\n"); @@ -1917,60 +2736,13 @@ _mesa_UnlockArraysEXT( void ) ctx->Array.LockFirst = 0; ctx->Array.LockCount = 0; - ctx->NewState |= _NEW_ARRAY; -} - - -/* GL_IBM_multimode_draw_arrays */ -void GLAPIENTRY -_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, - const GLsizei * count, - GLsizei primcount, GLint modestride ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - FLUSH_VERTICES(ctx, 0); - - for ( i = 0 ; i < primcount ; i++ ) { - if ( count[i] > 0 ) { - GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); - CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] )); - } - } -} - - -/* GL_IBM_multimode_draw_arrays */ -void GLAPIENTRY -_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, - GLenum type, const GLvoid * const * indices, - GLsizei primcount, GLint modestride ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - FLUSH_VERTICES(ctx, 0); - - /* XXX not sure about ARB_vertex_buffer_object handling here */ - - for ( i = 0 ; i < primcount ; i++ ) { - if ( count[i] > 0 ) { - GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); - CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type, - indices[i] )); - } - } } static void primitive_restart_index(struct gl_context *ctx, GLuint index) { - if (ctx->Array.RestartIndex != index) { - FLUSH_VERTICES(ctx, 0); - ctx->Array.RestartIndex = index; - } + ctx->Array.RestartIndex = index; } @@ -2020,7 +2792,7 @@ _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor) * VertexAttribBinding(index, index); * VertexBindingDivisor(index, divisor);" */ - vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); + _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); vertex_binding_divisor(ctx, vao, genericIndex, divisor); } @@ -2062,11 +2834,60 @@ _mesa_VertexAttribDivisor(GLuint index, GLuint divisor) * VertexAttribBinding(index, index); * VertexBindingDivisor(index, divisor);" */ - vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); + _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); + vertex_binding_divisor(ctx, vao, genericIndex, 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, @@ -2153,7 +2974,7 @@ vertex_array_vertex_buffer_err(struct gl_context *ctx, return; } - if (((ctx->API == API_OPENGL_CORE && ctx->Version >= 44) || _mesa_is_gles31(ctx)) && + if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) && stride > ctx->Const.MaxVertexAttribStride) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); @@ -2226,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; @@ -2235,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, @@ -2307,7 +3143,7 @@ vertex_array_vertex_buffers(struct gl_context *ctx, continue; } - if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 && + if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && strides[i] > ctx->Const.MaxVertexAttribStride) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(strides[%u]=%d > " @@ -2432,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; @@ -2497,8 +3333,6 @@ vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type, } } - FLUSH_VERTICES(ctx, 0); - _mesa_update_array_format(ctx, ctx->Array.VAO, VERT_ATTRIB_GENERIC(attribIndex), size, type, format, normalized, integer, doubles, @@ -2538,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) @@ -2556,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; @@ -2587,8 +3415,6 @@ vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size, } } - FLUSH_VERTICES(ctx, 0); - _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size, type, format, normalized, integer, doubles, relativeOffset); @@ -2600,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, @@ -2664,9 +3526,9 @@ vertex_array_attrib_binding(struct gl_context *ctx, assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib)); - vertex_attrib_binding(ctx, vao, - VERT_ATTRIB_GENERIC(attribIndex), - VERT_ATTRIB_GENERIC(bindingIndex)); + _mesa_vertex_attrib_binding(ctx, vao, + VERT_ATTRIB_GENERIC(attribIndex), + VERT_ATTRIB_GENERIC(bindingIndex)); } @@ -2674,9 +3536,9 @@ void GLAPIENTRY _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex) { GET_CURRENT_CONTEXT(ctx); - vertex_attrib_binding(ctx, ctx->Array.VAO, - VERT_ATTRIB_GENERIC(attribIndex), - VERT_ATTRIB_GENERIC(bindingIndex)); + _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO, + VERT_ATTRIB_GENERIC(attribIndex), + VERT_ATTRIB_GENERIC(bindingIndex)); } @@ -2710,9 +3572,9 @@ _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex, GET_CURRENT_CONTEXT(ctx); struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); - vertex_attrib_binding(ctx, vao, - VERT_ATTRIB_GENERIC(attribIndex), - VERT_ATTRIB_GENERIC(bindingIndex)); + _mesa_vertex_attrib_binding(ctx, vao, + VERT_ATTRIB_GENERIC(attribIndex), + VERT_ATTRIB_GENERIC(bindingIndex)); } @@ -2728,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; @@ -2737,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, @@ -2823,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; @@ -2832,44 +3708,40 @@ _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, } -/** - * Copy one vertex array to another. - */ -void -_mesa_copy_vertex_array(struct gl_context *ctx, - struct gl_vertex_array *dst, - struct gl_vertex_array *src) -{ - dst->Size = src->Size; - dst->Type = src->Type; - dst->Format = src->Format; - dst->StrideB = src->StrideB; - dst->Ptr = src->Ptr; - dst->Normalized = src->Normalized; - dst->Integer = src->Integer; - dst->Doubles = src->Doubles; - dst->InstanceDivisor = src->InstanceDivisor; - dst->_ElementSize = src->_ElementSize; - _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); +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, const struct gl_array_attributes *src) { - dst->Size = src->Size; - dst->Type = src->Type; - dst->Format = src->Format; - dst->BufferBindingIndex = src->BufferBindingIndex; + dst->Ptr = src->Ptr; dst->RelativeOffset = src->RelativeOffset; dst->Format = src->Format; - dst->Integer = src->Integer; - dst->Doubles = src->Doubles; - dst->Normalized = src->Normalized; - dst->Ptr = src->Ptr; - dst->Enabled = src->Enabled; - dst->_ElementSize = src->_ElementSize; + dst->Stride = src->Stride; + dst->BufferBindingIndex = src->BufferBindingIndex; + dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex; + dst->_EffRelativeOffset = src->_EffRelativeOffset; } void @@ -2881,6 +3753,8 @@ _mesa_copy_vertex_buffer_binding(struct gl_context *ctx, dst->Stride = src->Stride; dst->InstanceDivisor = src->InstanceDivisor; dst->_BoundArrays = src->_BoundArrays; + dst->_EffBoundArrays = src->_EffBoundArrays; + dst->_EffOffset = src->_EffOffset; _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); } @@ -2895,11 +3769,10 @@ _mesa_print_arrays(struct gl_context *ctx) fprintf(stderr, "Array Object %u\n", vao->Name); - gl_vert_attrib i; - for (i = 0; i < VERT_ATTRIB_MAX; ++i) { + GLbitfield mask = vao->Enabled; + while (mask) { + const gl_vert_attrib i = u_bit_scan(&mask); const struct gl_array_attributes *array = &vao->VertexAttrib[i]; - if (!array->Enabled) - continue; const struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[array->BufferBindingIndex]; @@ -2908,8 +3781,9 @@ _mesa_print_arrays(struct gl_context *ctx) fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, " "Stride=%d, Buffer=%u(Size %lu)\n", gl_vert_attrib_name((gl_vert_attrib)i), - array->Ptr, _mesa_enum_to_string(array->Type), array->Size, - array->_ElementSize, binding->Stride, bo->Name, + array->Ptr, _mesa_enum_to_string(array->Format.Type), + array->Format.Size, + array->Format._ElementSize, binding->Stride, bo->Name, (unsigned long) bo->Size); } } @@ -2923,6 +3797,8 @@ _mesa_init_varray(struct gl_context *ctx) { ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0); _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO); + ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u); + _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ ctx->Array.Objects = _mesa_NewHashTable(); @@ -2950,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)"); + } +}