varray.c revision 01e04c3f
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 54a49301eSmrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 67117f1b4Smrg * 77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 97117f1b4Smrg * to deal in the Software without restriction, including without limitation 107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 127117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 137117f1b4Smrg * 147117f1b4Smrg * The above copyright notice and this permission notice shall be included 157117f1b4Smrg * in all copies or substantial portions of the Software. 167117f1b4Smrg * 177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 247117f1b4Smrg */ 257117f1b4Smrg 267117f1b4Smrg 2701e04c3fSmrg#include <stdio.h> 28af69d88dSmrg#include <inttypes.h> /* for PRId64 macro */ 29af69d88dSmrg 307117f1b4Smrg#include "glheader.h" 317117f1b4Smrg#include "imports.h" 327117f1b4Smrg#include "bufferobj.h" 337117f1b4Smrg#include "context.h" 347117f1b4Smrg#include "enable.h" 357117f1b4Smrg#include "enums.h" 364a49301eSmrg#include "hash.h" 373464ebd5Sriastradh#include "image.h" 383464ebd5Sriastradh#include "macros.h" 397117f1b4Smrg#include "mtypes.h" 407117f1b4Smrg#include "varray.h" 417117f1b4Smrg#include "arrayobj.h" 42cdc920a0Smrg#include "main/dispatch.h" 437117f1b4Smrg 447117f1b4Smrg 453464ebd5Sriastradh/** Used to do error checking for GL_EXT_vertex_array_bgra */ 463464ebd5Sriastradh#define BGRA_OR_4 5 473464ebd5Sriastradh 483464ebd5Sriastradh 493464ebd5Sriastradh/** Used to indicate which GL datatypes are accepted by each of the 503464ebd5Sriastradh * glVertex/Color/Attrib/EtcPointer() functions. 513464ebd5Sriastradh */ 52af69d88dSmrg#define BOOL_BIT (1 << 0) 53af69d88dSmrg#define BYTE_BIT (1 << 1) 54af69d88dSmrg#define UNSIGNED_BYTE_BIT (1 << 2) 55af69d88dSmrg#define SHORT_BIT (1 << 3) 56af69d88dSmrg#define UNSIGNED_SHORT_BIT (1 << 4) 57af69d88dSmrg#define INT_BIT (1 << 5) 58af69d88dSmrg#define UNSIGNED_INT_BIT (1 << 6) 59af69d88dSmrg#define HALF_BIT (1 << 7) 60af69d88dSmrg#define FLOAT_BIT (1 << 8) 61af69d88dSmrg#define DOUBLE_BIT (1 << 9) 62af69d88dSmrg#define FIXED_ES_BIT (1 << 10) 63af69d88dSmrg#define FIXED_GL_BIT (1 << 11) 64af69d88dSmrg#define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12) 65af69d88dSmrg#define INT_2_10_10_10_REV_BIT (1 << 13) 66af69d88dSmrg#define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14) 67af69d88dSmrg#define ALL_TYPE_BITS ((1 << 15) - 1) 683464ebd5Sriastradh 6901e04c3fSmrg#define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \ 7001e04c3fSmrg SHORT_BIT | UNSIGNED_SHORT_BIT | \ 7101e04c3fSmrg INT_BIT | UNSIGNED_INT_BIT | \ 7201e04c3fSmrg HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \ 7301e04c3fSmrg FIXED_GL_BIT | \ 7401e04c3fSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | \ 7501e04c3fSmrg INT_2_10_10_10_REV_BIT | \ 7601e04c3fSmrg UNSIGNED_INT_10F_11F_11F_REV_BIT) 7701e04c3fSmrg 7801e04c3fSmrg#define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \ 7901e04c3fSmrg SHORT_BIT | UNSIGNED_SHORT_BIT | \ 8001e04c3fSmrg INT_BIT | UNSIGNED_INT_BIT) 8101e04c3fSmrg 8201e04c3fSmrg#define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT 8301e04c3fSmrg 843464ebd5Sriastradh 853464ebd5Sriastradh/** Convert GL datatype enum into a <type>_BIT value seen above */ 863464ebd5Sriastradhstatic GLbitfield 873464ebd5Sriastradhtype_to_bit(const struct gl_context *ctx, GLenum type) 883464ebd5Sriastradh{ 893464ebd5Sriastradh switch (type) { 903464ebd5Sriastradh case GL_BOOL: 913464ebd5Sriastradh return BOOL_BIT; 923464ebd5Sriastradh case GL_BYTE: 933464ebd5Sriastradh return BYTE_BIT; 943464ebd5Sriastradh case GL_UNSIGNED_BYTE: 953464ebd5Sriastradh return UNSIGNED_BYTE_BIT; 963464ebd5Sriastradh case GL_SHORT: 973464ebd5Sriastradh return SHORT_BIT; 983464ebd5Sriastradh case GL_UNSIGNED_SHORT: 993464ebd5Sriastradh return UNSIGNED_SHORT_BIT; 1003464ebd5Sriastradh case GL_INT: 1013464ebd5Sriastradh return INT_BIT; 1023464ebd5Sriastradh case GL_UNSIGNED_INT: 1033464ebd5Sriastradh return UNSIGNED_INT_BIT; 1043464ebd5Sriastradh case GL_HALF_FLOAT: 10501e04c3fSmrg case GL_HALF_FLOAT_OES: 1063464ebd5Sriastradh if (ctx->Extensions.ARB_half_float_vertex) 1073464ebd5Sriastradh return HALF_BIT; 1083464ebd5Sriastradh else 1093464ebd5Sriastradh return 0x0; 1103464ebd5Sriastradh case GL_FLOAT: 1113464ebd5Sriastradh return FLOAT_BIT; 1123464ebd5Sriastradh case GL_DOUBLE: 1133464ebd5Sriastradh return DOUBLE_BIT; 1143464ebd5Sriastradh case GL_FIXED: 115af69d88dSmrg return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT; 116af69d88dSmrg case GL_UNSIGNED_INT_2_10_10_10_REV: 117af69d88dSmrg return UNSIGNED_INT_2_10_10_10_REV_BIT; 118af69d88dSmrg case GL_INT_2_10_10_10_REV: 119af69d88dSmrg return INT_2_10_10_10_REV_BIT; 120af69d88dSmrg case GL_UNSIGNED_INT_10F_11F_11F_REV: 121af69d88dSmrg return UNSIGNED_INT_10F_11F_11F_REV_BIT; 1223464ebd5Sriastradh default: 1233464ebd5Sriastradh return 0; 1243464ebd5Sriastradh } 1253464ebd5Sriastradh} 1263464ebd5Sriastradh 1273464ebd5Sriastradh 1287117f1b4Smrg/** 12901e04c3fSmrg * Depending on the position and generic0 attributes enable flags select 13001e04c3fSmrg * the one that is used for both attributes. 13101e04c3fSmrg * The generic0 attribute takes precedence. 1327117f1b4Smrg */ 13301e04c3fSmrgstatic inline void 13401e04c3fSmrgupdate_attribute_map_mode(const struct gl_context *ctx, 13501e04c3fSmrg struct gl_vertex_array_object *vao) 136af69d88dSmrg{ 13701e04c3fSmrg /* 13801e04c3fSmrg * There is no need to change the mapping away from the 13901e04c3fSmrg * identity mapping if we are not in compat mode. 14001e04c3fSmrg */ 14101e04c3fSmrg if (ctx->API != API_OPENGL_COMPAT) 14201e04c3fSmrg return; 14301e04c3fSmrg /* The generic0 attribute superseeds the position attribute */ 14401e04c3fSmrg const GLbitfield enabled = vao->_Enabled; 14501e04c3fSmrg if (enabled & VERT_BIT_GENERIC0) 14601e04c3fSmrg vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0; 14701e04c3fSmrg else if (enabled & VERT_BIT_POS) 14801e04c3fSmrg vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION; 14901e04c3fSmrg else 15001e04c3fSmrg vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY; 15101e04c3fSmrg} 15201e04c3fSmrg 153af69d88dSmrg 15401e04c3fSmrg/** 15501e04c3fSmrg * Sets the BufferBindingIndex field for the vertex attribute given by 15601e04c3fSmrg * attribIndex. 15701e04c3fSmrg */ 15801e04c3fSmrgvoid 15901e04c3fSmrg_mesa_vertex_attrib_binding(struct gl_context *ctx, 16001e04c3fSmrg struct gl_vertex_array_object *vao, 16101e04c3fSmrg gl_vert_attrib attribIndex, 16201e04c3fSmrg GLuint bindingIndex) 16301e04c3fSmrg{ 16401e04c3fSmrg struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex]; 16501e04c3fSmrg assert(!vao->SharedAndImmutable); 166af69d88dSmrg 16701e04c3fSmrg if (array->BufferBindingIndex != bindingIndex) { 16801e04c3fSmrg const GLbitfield array_bit = VERT_BIT(attribIndex); 169af69d88dSmrg 17001e04c3fSmrg if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj)) 17101e04c3fSmrg vao->VertexAttribBufferMask |= array_bit; 17201e04c3fSmrg else 17301e04c3fSmrg vao->VertexAttribBufferMask &= ~array_bit; 174af69d88dSmrg 17501e04c3fSmrg vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit; 17601e04c3fSmrg vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit; 177af69d88dSmrg 17801e04c3fSmrg array->BufferBindingIndex = bindingIndex; 17901e04c3fSmrg 18001e04c3fSmrg vao->NewArrays |= vao->_Enabled & array_bit; 18101e04c3fSmrg if (vao == ctx->Array.VAO) 18201e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 183af69d88dSmrg } 184af69d88dSmrg} 185af69d88dSmrg 186af69d88dSmrg 187af69d88dSmrg/** 188af69d88dSmrg * Binds a buffer object to the vertex buffer binding point given by index, 189af69d88dSmrg * and sets the Offset and Stride fields. 190af69d88dSmrg */ 19101e04c3fSmrgvoid 19201e04c3fSmrg_mesa_bind_vertex_buffer(struct gl_context *ctx, 19301e04c3fSmrg struct gl_vertex_array_object *vao, 19401e04c3fSmrg GLuint index, 19501e04c3fSmrg struct gl_buffer_object *vbo, 19601e04c3fSmrg GLintptr offset, GLsizei stride) 197af69d88dSmrg{ 19801e04c3fSmrg assert(index < ARRAY_SIZE(vao->BufferBinding)); 19901e04c3fSmrg assert(!vao->SharedAndImmutable); 20001e04c3fSmrg struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index]; 201af69d88dSmrg 202af69d88dSmrg if (binding->BufferObj != vbo || 203af69d88dSmrg binding->Offset != offset || 204af69d88dSmrg binding->Stride != stride) { 205af69d88dSmrg 206af69d88dSmrg _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo); 207af69d88dSmrg 208af69d88dSmrg binding->Offset = offset; 209af69d88dSmrg binding->Stride = stride; 210af69d88dSmrg 21101e04c3fSmrg if (!_mesa_is_bufferobj(vbo)) 21201e04c3fSmrg vao->VertexAttribBufferMask &= ~binding->_BoundArrays; 21301e04c3fSmrg else 21401e04c3fSmrg vao->VertexAttribBufferMask |= binding->_BoundArrays; 21501e04c3fSmrg 21601e04c3fSmrg vao->NewArrays |= vao->_Enabled & binding->_BoundArrays; 21701e04c3fSmrg if (vao == ctx->Array.VAO) 21801e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 219af69d88dSmrg } 220af69d88dSmrg} 221af69d88dSmrg 222af69d88dSmrg 223af69d88dSmrg/** 224af69d88dSmrg * Sets the InstanceDivisor field in the vertex buffer binding point 225af69d88dSmrg * given by bindingIndex. 226af69d88dSmrg */ 227af69d88dSmrgstatic void 22801e04c3fSmrgvertex_binding_divisor(struct gl_context *ctx, 22901e04c3fSmrg struct gl_vertex_array_object *vao, 23001e04c3fSmrg GLuint bindingIndex, 231af69d88dSmrg GLuint divisor) 232af69d88dSmrg{ 233af69d88dSmrg struct gl_vertex_buffer_binding *binding = 23401e04c3fSmrg &vao->BufferBinding[bindingIndex]; 23501e04c3fSmrg assert(!vao->SharedAndImmutable); 236af69d88dSmrg 237af69d88dSmrg if (binding->InstanceDivisor != divisor) { 238af69d88dSmrg binding->InstanceDivisor = divisor; 23901e04c3fSmrg vao->NewArrays |= vao->_Enabled & binding->_BoundArrays; 24001e04c3fSmrg if (vao == ctx->Array.VAO) 24101e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 242af69d88dSmrg } 243af69d88dSmrg} 244af69d88dSmrg 245af69d88dSmrg 246af69d88dSmrg/** 247af69d88dSmrg * Examine the API profile and extensions to determine which types are legal 248af69d88dSmrg * for vertex arrays. This is called once from update_array_format(). 249af69d88dSmrg */ 250af69d88dSmrgstatic GLbitfield 251af69d88dSmrgget_legal_types_mask(const struct gl_context *ctx) 252af69d88dSmrg{ 253af69d88dSmrg GLbitfield legalTypesMask = ALL_TYPE_BITS; 254af69d88dSmrg 255af69d88dSmrg if (_mesa_is_gles(ctx)) { 256af69d88dSmrg legalTypesMask &= ~(FIXED_GL_BIT | 257af69d88dSmrg DOUBLE_BIT | 258af69d88dSmrg UNSIGNED_INT_10F_11F_11F_REV_BIT); 259af69d88dSmrg 260af69d88dSmrg /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until 261af69d88dSmrg * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or 262af69d88dSmrg * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed 263af69d88dSmrg * until 3.0 or with the GL_OES_vertex_half float extension, which isn't 264af69d88dSmrg * quite as trivial as we'd like because it uses a different enum value 265af69d88dSmrg * for GL_HALF_FLOAT_OES. 266af69d88dSmrg */ 267af69d88dSmrg if (ctx->Version < 30) { 268af69d88dSmrg legalTypesMask &= ~(UNSIGNED_INT_BIT | 269af69d88dSmrg INT_BIT | 270af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 27101e04c3fSmrg INT_2_10_10_10_REV_BIT); 27201e04c3fSmrg 27301e04c3fSmrg if (!_mesa_has_OES_vertex_half_float(ctx)) 27401e04c3fSmrg legalTypesMask &= ~HALF_BIT; 275af69d88dSmrg } 276af69d88dSmrg } 277af69d88dSmrg else { 278af69d88dSmrg legalTypesMask &= ~FIXED_ES_BIT; 279af69d88dSmrg 280af69d88dSmrg if (!ctx->Extensions.ARB_ES2_compatibility) 281af69d88dSmrg legalTypesMask &= ~FIXED_GL_BIT; 282af69d88dSmrg 283af69d88dSmrg if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) 284af69d88dSmrg legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | 285af69d88dSmrg INT_2_10_10_10_REV_BIT); 286af69d88dSmrg 287af69d88dSmrg if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev) 288af69d88dSmrg legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT; 289af69d88dSmrg } 290af69d88dSmrg 291af69d88dSmrg return legalTypesMask; 292af69d88dSmrg} 293af69d88dSmrg 29401e04c3fSmrgstatic GLenum 29501e04c3fSmrgget_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size) 29601e04c3fSmrg{ 29701e04c3fSmrg GLenum format = GL_RGBA; 29801e04c3fSmrg 29901e04c3fSmrg /* Do size parameter checking. 30001e04c3fSmrg * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and 30101e04c3fSmrg * must be handled specially. 30201e04c3fSmrg */ 30301e04c3fSmrg if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && 30401e04c3fSmrg *size == GL_BGRA) { 30501e04c3fSmrg format = GL_BGRA; 30601e04c3fSmrg *size = 4; 30701e04c3fSmrg } 30801e04c3fSmrg 30901e04c3fSmrg return format; 31001e04c3fSmrg} 31101e04c3fSmrg 31201e04c3fSmrg 31301e04c3fSmrg/** 31401e04c3fSmrg * \param attrib The index of the attribute array 31501e04c3fSmrg * \param size Components per element (1, 2, 3 or 4) 31601e04c3fSmrg * \param type Datatype of each component (GL_FLOAT, GL_INT, etc) 31701e04c3fSmrg * \param format Either GL_RGBA or GL_BGRA. 31801e04c3fSmrg * \param normalized Whether integer types are converted to floats in [-1, 1] 31901e04c3fSmrg * \param integer Integer-valued values (will not be normalized to [-1, 1]) 32001e04c3fSmrg * \param doubles Double values not reduced to floats 32101e04c3fSmrg * \param relativeOffset Offset of the first element relative to the binding 32201e04c3fSmrg * offset. 32301e04c3fSmrg */ 32401e04c3fSmrgvoid 32501e04c3fSmrg_mesa_update_array_format(struct gl_context *ctx, 32601e04c3fSmrg struct gl_vertex_array_object *vao, 32701e04c3fSmrg gl_vert_attrib attrib, GLint size, GLenum type, 32801e04c3fSmrg GLenum format, GLboolean normalized, 32901e04c3fSmrg GLboolean integer, GLboolean doubles, 33001e04c3fSmrg GLuint relativeOffset) 33101e04c3fSmrg{ 33201e04c3fSmrg struct gl_array_attributes *const array = &vao->VertexAttrib[attrib]; 33301e04c3fSmrg GLint elementSize; 33401e04c3fSmrg 33501e04c3fSmrg assert(!vao->SharedAndImmutable); 33601e04c3fSmrg assert(size <= 4); 33701e04c3fSmrg 33801e04c3fSmrg elementSize = _mesa_bytes_per_vertex_attrib(size, type); 33901e04c3fSmrg assert(elementSize != -1); 34001e04c3fSmrg 34101e04c3fSmrg array->Size = size; 34201e04c3fSmrg array->Type = type; 34301e04c3fSmrg array->Format = format; 34401e04c3fSmrg array->Normalized = normalized; 34501e04c3fSmrg array->Integer = integer; 34601e04c3fSmrg array->Doubles = doubles; 34701e04c3fSmrg array->RelativeOffset = relativeOffset; 34801e04c3fSmrg array->_ElementSize = elementSize; 34901e04c3fSmrg 35001e04c3fSmrg vao->NewArrays |= vao->_Enabled & VERT_BIT(attrib); 35101e04c3fSmrg if (vao == ctx->Array.VAO) 35201e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 35301e04c3fSmrg} 354af69d88dSmrg 355af69d88dSmrg/** 35601e04c3fSmrg * Does error checking of the format in an attrib array. 357af69d88dSmrg * 35801e04c3fSmrg * Called by *Pointer() and VertexAttrib*Format(). 359af69d88dSmrg * 360af69d88dSmrg * \param func Name of calling function used for error reporting 361af69d88dSmrg * \param attrib The index of the attribute array 362af69d88dSmrg * \param legalTypes Bitmask of *_BIT above indicating legal datatypes 363af69d88dSmrg * \param sizeMin Min allowable size value 364af69d88dSmrg * \param sizeMax Max allowable size value (may also be BGRA_OR_4) 365af69d88dSmrg * \param size Components per element (1, 2, 3 or 4) 366af69d88dSmrg * \param type Datatype of each component (GL_FLOAT, GL_INT, etc) 367af69d88dSmrg * \param normalized Whether integer types are converted to floats in [-1, 1] 368af69d88dSmrg * \param integer Integer-valued values (will not be normalized to [-1, 1]) 36901e04c3fSmrg * \param doubles Double values not reduced to floats 370af69d88dSmrg * \param relativeOffset Offset of the first element relative to the binding offset. 37101e04c3fSmrg * \return bool True if validation is successful, False otherwise. 372af69d88dSmrg */ 373af69d88dSmrgstatic bool 37401e04c3fSmrgvalidate_array_format(struct gl_context *ctx, const char *func, 37501e04c3fSmrg struct gl_vertex_array_object *vao, 37601e04c3fSmrg GLuint attrib, GLbitfield legalTypesMask, 37701e04c3fSmrg GLint sizeMin, GLint sizeMax, 37801e04c3fSmrg GLint size, GLenum type, GLboolean normalized, 37901e04c3fSmrg GLboolean integer, GLboolean doubles, 38001e04c3fSmrg GLuint relativeOffset, GLenum format) 38101e04c3fSmrg{ 3823464ebd5Sriastradh GLbitfield typeBit; 3833464ebd5Sriastradh 38401e04c3fSmrg /* at most, one of these bools can be true */ 38501e04c3fSmrg assert((int) normalized + (int) integer + (int) doubles <= 1); 38601e04c3fSmrg 38701e04c3fSmrg if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) { 38801e04c3fSmrg /* Compute the LegalTypesMask only once, unless the context API has 38901e04c3fSmrg * changed, in which case we want to compute it again. We can't do this 39001e04c3fSmrg * in _mesa_init_varrays() below because extensions are not yet enabled 39101e04c3fSmrg * at that point. 392af69d88dSmrg */ 393af69d88dSmrg ctx->Array.LegalTypesMask = get_legal_types_mask(ctx); 39401e04c3fSmrg ctx->Array.LegalTypesMaskAPI = ctx->API; 3953464ebd5Sriastradh } 396af69d88dSmrg 397af69d88dSmrg legalTypesMask &= ctx->Array.LegalTypesMask; 398af69d88dSmrg 399af69d88dSmrg if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) { 400af69d88dSmrg /* BGRA ordering is not supported in ES contexts. 401af69d88dSmrg */ 402af69d88dSmrg sizeMax = 4; 4033464ebd5Sriastradh } 4043464ebd5Sriastradh 4053464ebd5Sriastradh typeBit = type_to_bit(ctx, type); 4063464ebd5Sriastradh if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { 4073464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", 40801e04c3fSmrg func, _mesa_enum_to_string(type)); 409af69d88dSmrg return false; 4103464ebd5Sriastradh } 4113464ebd5Sriastradh 41201e04c3fSmrg if (format == GL_BGRA) { 413af69d88dSmrg /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says: 414af69d88dSmrg * 415af69d88dSmrg * "An INVALID_OPERATION error is generated under any of the following 416af69d88dSmrg * conditions: 417af69d88dSmrg * ... 418af69d88dSmrg * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV 419af69d88dSmrg * or UNSIGNED_INT_2_10_10_10_REV; 420af69d88dSmrg * ... 421af69d88dSmrg * • size is BGRA and normalized is FALSE;" 422af69d88dSmrg */ 423af69d88dSmrg bool bgra_error = false; 424af69d88dSmrg 425af69d88dSmrg if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { 426af69d88dSmrg if (type != GL_UNSIGNED_INT_2_10_10_10_REV && 427af69d88dSmrg type != GL_INT_2_10_10_10_REV && 428af69d88dSmrg type != GL_UNSIGNED_BYTE) 429af69d88dSmrg bgra_error = true; 430af69d88dSmrg } else if (type != GL_UNSIGNED_BYTE) 431af69d88dSmrg bgra_error = true; 432af69d88dSmrg 433af69d88dSmrg if (bgra_error) { 434af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)", 43501e04c3fSmrg func, _mesa_enum_to_string(type)); 436af69d88dSmrg return false; 437af69d88dSmrg } 438af69d88dSmrg 439af69d88dSmrg if (!normalized) { 440af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 441af69d88dSmrg "%s(size=GL_BGRA and normalized=GL_FALSE)", func); 442af69d88dSmrg return false; 4433464ebd5Sriastradh } 4443464ebd5Sriastradh } 4453464ebd5Sriastradh else if (size < sizeMin || size > sizeMax || size > 4) { 4463464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); 447af69d88dSmrg return false; 448af69d88dSmrg } 449af69d88dSmrg 450af69d88dSmrg if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && 451af69d88dSmrg (type == GL_UNSIGNED_INT_2_10_10_10_REV || 452af69d88dSmrg type == GL_INT_2_10_10_10_REV) && size != 4) { 453af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); 454af69d88dSmrg return false; 455af69d88dSmrg } 456af69d88dSmrg 457af69d88dSmrg /* The ARB_vertex_attrib_binding_spec says: 458af69d88dSmrg * 459af69d88dSmrg * An INVALID_VALUE error is generated if <relativeoffset> is larger than 460af69d88dSmrg * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET. 461af69d88dSmrg */ 462af69d88dSmrg if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) { 463af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 464af69d88dSmrg "%s(relativeOffset=%d > " 465af69d88dSmrg "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)", 466af69d88dSmrg func, relativeOffset); 467af69d88dSmrg return false; 468af69d88dSmrg } 469af69d88dSmrg 470af69d88dSmrg if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev && 471af69d88dSmrg type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) { 472af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); 473af69d88dSmrg return false; 4743464ebd5Sriastradh } 4753464ebd5Sriastradh 476af69d88dSmrg return true; 477af69d88dSmrg} 478af69d88dSmrg 479af69d88dSmrg/** 48001e04c3fSmrg * Do error checking for glVertex/Color/TexCoord/...Pointer functions. 481af69d88dSmrg * 482af69d88dSmrg * \param func name of calling function used for error reporting 483af69d88dSmrg * \param attrib the attribute array index to update 484af69d88dSmrg * \param legalTypes bitmask of *_BIT above indicating legal datatypes 485af69d88dSmrg * \param sizeMin min allowable size value 486af69d88dSmrg * \param sizeMax max allowable size value (may also be BGRA_OR_4) 487af69d88dSmrg * \param size components per element (1, 2, 3 or 4) 488af69d88dSmrg * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 489af69d88dSmrg * \param stride stride between elements, in elements 490af69d88dSmrg * \param normalized are integer types converted to floats in [-1, 1]? 491af69d88dSmrg * \param integer integer-valued values (will not be normalized to [-1,1]) 49201e04c3fSmrg * \param doubles Double values not reduced to floats 493af69d88dSmrg * \param ptr the address (or offset inside VBO) of the array data 494af69d88dSmrg */ 495af69d88dSmrgstatic void 49601e04c3fSmrgvalidate_array(struct gl_context *ctx, const char *func, 49701e04c3fSmrg GLuint attrib, GLbitfield legalTypesMask, 49801e04c3fSmrg GLint sizeMin, GLint sizeMax, 49901e04c3fSmrg GLint size, GLenum type, GLsizei stride, 50001e04c3fSmrg GLboolean normalized, GLboolean integer, GLboolean doubles, 50101e04c3fSmrg const GLvoid *ptr) 502af69d88dSmrg{ 50301e04c3fSmrg struct gl_vertex_array_object *vao = ctx->Array.VAO; 504af69d88dSmrg 505af69d88dSmrg /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says: 506af69d88dSmrg * 507af69d88dSmrg * "Client vertex arrays - all vertex array attribute pointers must 508af69d88dSmrg * refer to buffer objects (section 2.9.2). The default vertex array 509af69d88dSmrg * object (the name zero) is also deprecated. Calling 510af69d88dSmrg * VertexAttribPointer when no buffer object or no vertex array object 511af69d88dSmrg * is bound will generate an INVALID_OPERATION error..." 512af69d88dSmrg * 513af69d88dSmrg * The check for VBOs is handled below. 514af69d88dSmrg */ 51501e04c3fSmrg if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) { 516af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)", 517af69d88dSmrg func); 518af69d88dSmrg return; 519af69d88dSmrg } 520af69d88dSmrg 5213464ebd5Sriastradh if (stride < 0) { 5223464ebd5Sriastradh _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); 5233464ebd5Sriastradh return; 5243464ebd5Sriastradh } 5254a49301eSmrg 52601e04c3fSmrg if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && 52701e04c3fSmrg stride > ctx->Const.MaxVertexAttribStride) { 52801e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " 52901e04c3fSmrg "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); 53001e04c3fSmrg return; 53101e04c3fSmrg } 53201e04c3fSmrg 533af69d88dSmrg /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says: 534af69d88dSmrg * 535af69d88dSmrg * "An INVALID_OPERATION error is generated under any of the following 536af69d88dSmrg * conditions: 537af69d88dSmrg * 538af69d88dSmrg * ... 539af69d88dSmrg * 540af69d88dSmrg * * any of the *Pointer commands specifying the location and 541af69d88dSmrg * organization of vertex array data are called while zero is bound 542af69d88dSmrg * to the ARRAY_BUFFER buffer object binding point (see section 543af69d88dSmrg * 2.9.6), and the pointer argument is not NULL." 544af69d88dSmrg */ 54501e04c3fSmrg if (ptr != NULL && vao != ctx->Array.DefaultVAO && 546af69d88dSmrg !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { 5473464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); 5484a49301eSmrg return; 5494a49301eSmrg } 55001e04c3fSmrg} 5514a49301eSmrg 55201e04c3fSmrg 55301e04c3fSmrgstatic bool 55401e04c3fSmrgvalidate_array_and_format(struct gl_context *ctx, const char *func, 55501e04c3fSmrg GLuint attrib, GLbitfield legalTypes, 55601e04c3fSmrg GLint sizeMin, GLint sizeMax, 55701e04c3fSmrg GLint size, GLenum type, GLsizei stride, 55801e04c3fSmrg GLboolean normalized, GLboolean integer, 55901e04c3fSmrg GLboolean doubles, GLenum format, const GLvoid *ptr, 56001e04c3fSmrg struct gl_vertex_array_object *vao) 56101e04c3fSmrg{ 56201e04c3fSmrg validate_array(ctx, func, attrib, legalTypes, sizeMin, sizeMax, size, 56301e04c3fSmrg type, stride, normalized, integer, doubles, ptr); 56401e04c3fSmrg 56501e04c3fSmrg return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin, 56601e04c3fSmrg sizeMax, size, type, normalized, integer, 56701e04c3fSmrg doubles, 0, format); 56801e04c3fSmrg} 56901e04c3fSmrg 57001e04c3fSmrg 57101e04c3fSmrg/** 57201e04c3fSmrg * Update state for glVertex/Color/TexCoord/...Pointer functions. 57301e04c3fSmrg * 57401e04c3fSmrg * \param attrib the attribute array index to update 57501e04c3fSmrg * \param format Either GL_RGBA or GL_BGRA. 57601e04c3fSmrg * \param sizeMax max allowable size value (may also be BGRA_OR_4) 57701e04c3fSmrg * \param size components per element (1, 2, 3 or 4) 57801e04c3fSmrg * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 57901e04c3fSmrg * \param stride stride between elements, in elements 58001e04c3fSmrg * \param normalized are integer types converted to floats in [-1, 1]? 58101e04c3fSmrg * \param integer integer-valued values (will not be normalized to [-1,1]) 58201e04c3fSmrg * \param doubles Double values not reduced to floats 58301e04c3fSmrg * \param ptr the address (or offset inside VBO) of the array data 58401e04c3fSmrg */ 58501e04c3fSmrgstatic void 58601e04c3fSmrgupdate_array(struct gl_context *ctx, 58701e04c3fSmrg GLuint attrib, GLenum format, 58801e04c3fSmrg GLint sizeMax, 58901e04c3fSmrg GLint size, GLenum type, GLsizei stride, 59001e04c3fSmrg GLboolean normalized, GLboolean integer, GLboolean doubles, 59101e04c3fSmrg const GLvoid *ptr) 59201e04c3fSmrg{ 59301e04c3fSmrg struct gl_vertex_array_object *vao = ctx->Array.VAO; 59401e04c3fSmrg 59501e04c3fSmrg _mesa_update_array_format(ctx, vao, attrib, size, type, format, 59601e04c3fSmrg normalized, integer, doubles, 0); 5973464ebd5Sriastradh 598af69d88dSmrg /* Reset the vertex attrib binding */ 59901e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib); 6004a49301eSmrg 601af69d88dSmrg /* The Stride and Ptr fields are not set by update_array_format() */ 60201e04c3fSmrg struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 603af69d88dSmrg array->Stride = stride; 60401e04c3fSmrg /* For updating the pointer we would need to add the vao->NewArrays flag 60501e04c3fSmrg * to the VAO. But but that is done already unconditionally in 60601e04c3fSmrg * _mesa_update_array_format called above. 60701e04c3fSmrg */ 60801e04c3fSmrg assert((vao->NewArrays | ~vao->_Enabled) & VERT_BIT(attrib)); 60901e04c3fSmrg array->Ptr = ptr; 610c1f859d4Smrg 611af69d88dSmrg /* Update the vertex buffer binding */ 61201e04c3fSmrg GLsizei effectiveStride = stride != 0 ? stride : array->_ElementSize; 61301e04c3fSmrg _mesa_bind_vertex_buffer(ctx, vao, attrib, 61401e04c3fSmrg ctx->Array.ArrayBufferObj, (GLintptr) ptr, 61501e04c3fSmrg effectiveStride); 61601e04c3fSmrg} 61701e04c3fSmrg 61801e04c3fSmrgvoid GLAPIENTRY 61901e04c3fSmrg_mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride, 62001e04c3fSmrg const GLvoid *ptr) 62101e04c3fSmrg{ 62201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 62301e04c3fSmrg 62401e04c3fSmrg update_array(ctx, VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, 62501e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 6267117f1b4Smrg} 6277117f1b4Smrg 6287117f1b4Smrg 6297117f1b4Smrgvoid GLAPIENTRY 6307117f1b4Smrg_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 6317117f1b4Smrg{ 6327117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 63301e04c3fSmrg 63401e04c3fSmrg GLenum format = GL_RGBA; 635af69d88dSmrg GLbitfield legalTypes = (ctx->API == API_OPENGLES) 636af69d88dSmrg ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 637af69d88dSmrg : (SHORT_BIT | INT_BIT | FLOAT_BIT | 638af69d88dSmrg DOUBLE_BIT | HALF_BIT | 639af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 640af69d88dSmrg INT_2_10_10_10_REV_BIT); 6417117f1b4Smrg 64201e04c3fSmrg if (!validate_array_and_format(ctx, "glVertexPointer", VERT_ATTRIB_POS, 64301e04c3fSmrg legalTypes, 2, 4, size, type, stride, 64401e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, format, 64501e04c3fSmrg ptr, ctx->Array.VAO)) 64601e04c3fSmrg return; 64701e04c3fSmrg 64801e04c3fSmrg update_array(ctx, VERT_ATTRIB_POS, format, 4, size, type, stride, 64901e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 65001e04c3fSmrg} 65101e04c3fSmrg 65201e04c3fSmrg 65301e04c3fSmrgvoid GLAPIENTRY 65401e04c3fSmrg_mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr ) 65501e04c3fSmrg{ 65601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 6577117f1b4Smrg 65801e04c3fSmrg update_array(ctx, VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, 65901e04c3fSmrg GL_FALSE, GL_FALSE, ptr); 6607117f1b4Smrg} 6617117f1b4Smrg 6627117f1b4Smrg 6637117f1b4Smrgvoid GLAPIENTRY 6647117f1b4Smrg_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) 6657117f1b4Smrg{ 6667117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 66701e04c3fSmrg 66801e04c3fSmrg GLenum format = GL_RGBA; 669af69d88dSmrg const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 670af69d88dSmrg ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 671af69d88dSmrg : (BYTE_BIT | SHORT_BIT | INT_BIT | 672af69d88dSmrg HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 673af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 674af69d88dSmrg INT_2_10_10_10_REV_BIT); 675af69d88dSmrg 67601e04c3fSmrg if (!validate_array_and_format(ctx, "glNormalPointer", 67701e04c3fSmrg VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, 67801e04c3fSmrg type, stride, GL_TRUE, GL_FALSE, 67901e04c3fSmrg GL_FALSE, format, ptr, ctx->Array.VAO)) 68001e04c3fSmrg return; 68101e04c3fSmrg 68201e04c3fSmrg update_array(ctx, VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, 68301e04c3fSmrg GL_FALSE, GL_FALSE, ptr); 68401e04c3fSmrg} 68501e04c3fSmrg 68601e04c3fSmrg 68701e04c3fSmrgvoid GLAPIENTRY 68801e04c3fSmrg_mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride, 68901e04c3fSmrg const GLvoid *ptr) 69001e04c3fSmrg{ 69101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 6927117f1b4Smrg 69301e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 69401e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, 69501e04c3fSmrg type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 6967117f1b4Smrg} 6977117f1b4Smrg 6987117f1b4Smrg 6997117f1b4Smrgvoid GLAPIENTRY 7007117f1b4Smrg_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 7017117f1b4Smrg{ 7027117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 70301e04c3fSmrg const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; 70401e04c3fSmrg 70501e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 706af69d88dSmrg const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 707af69d88dSmrg ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT) 708af69d88dSmrg : (BYTE_BIT | UNSIGNED_BYTE_BIT | 709af69d88dSmrg SHORT_BIT | UNSIGNED_SHORT_BIT | 710af69d88dSmrg INT_BIT | UNSIGNED_INT_BIT | 711af69d88dSmrg HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 712af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 713af69d88dSmrg INT_2_10_10_10_REV_BIT); 714af69d88dSmrg 71501e04c3fSmrg if (!validate_array_and_format(ctx, "glColorPointer", 71601e04c3fSmrg VERT_ATTRIB_COLOR0, legalTypes, sizeMin, 71701e04c3fSmrg BGRA_OR_4, size, type, stride, GL_TRUE, 71801e04c3fSmrg GL_FALSE, GL_FALSE, format, ptr, 71901e04c3fSmrg ctx->Array.VAO)) 72001e04c3fSmrg return; 72101e04c3fSmrg 72201e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, 72301e04c3fSmrg type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 72401e04c3fSmrg} 72501e04c3fSmrg 72601e04c3fSmrg 72701e04c3fSmrgvoid GLAPIENTRY 72801e04c3fSmrg_mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) 72901e04c3fSmrg{ 73001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 731af69d88dSmrg 73201e04c3fSmrg update_array(ctx, VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE, 73301e04c3fSmrg GL_FALSE, GL_FALSE, ptr); 7347117f1b4Smrg} 7357117f1b4Smrg 7367117f1b4Smrg 7377117f1b4Smrgvoid GLAPIENTRY 738af69d88dSmrg_mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 7397117f1b4Smrg{ 7407117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 7417117f1b4Smrg 74201e04c3fSmrg GLenum format = GL_RGBA; 74301e04c3fSmrg const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); 74401e04c3fSmrg 74501e04c3fSmrg if (!validate_array_and_format(ctx, "glFogCoordPointer", 74601e04c3fSmrg VERT_ATTRIB_FOG, legalTypes, 1, 1, 1, 74701e04c3fSmrg type, stride, GL_FALSE, GL_FALSE, 74801e04c3fSmrg GL_FALSE, format, ptr, ctx->Array.VAO)) 74901e04c3fSmrg return; 75001e04c3fSmrg 75101e04c3fSmrg update_array(ctx, VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE, 75201e04c3fSmrg GL_FALSE, GL_FALSE, ptr); 75301e04c3fSmrg} 75401e04c3fSmrg 75501e04c3fSmrg 75601e04c3fSmrgvoid GLAPIENTRY 75701e04c3fSmrg_mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) 75801e04c3fSmrg{ 75901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 760af69d88dSmrg 76101e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride, 76201e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 7637117f1b4Smrg} 7647117f1b4Smrg 7657117f1b4Smrg 7667117f1b4Smrgvoid GLAPIENTRY 7677117f1b4Smrg_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 7687117f1b4Smrg{ 7697117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 7707117f1b4Smrg 77101e04c3fSmrg GLenum format = GL_RGBA; 77201e04c3fSmrg const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | 77301e04c3fSmrg FLOAT_BIT | DOUBLE_BIT); 77401e04c3fSmrg 77501e04c3fSmrg if (!validate_array_and_format(ctx, "glIndexPointer", 77601e04c3fSmrg VERT_ATTRIB_COLOR_INDEX, 77701e04c3fSmrg legalTypes, 1, 1, 1, type, stride, 77801e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, format, 77901e04c3fSmrg ptr, ctx->Array.VAO)) 78001e04c3fSmrg return; 78101e04c3fSmrg 78201e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride, 78301e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 78401e04c3fSmrg} 78501e04c3fSmrg 78601e04c3fSmrg 78701e04c3fSmrgvoid GLAPIENTRY 78801e04c3fSmrg_mesa_SecondaryColorPointer_no_error(GLint size, GLenum type, 78901e04c3fSmrg GLsizei stride, const GLvoid *ptr) 79001e04c3fSmrg{ 79101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 792af69d88dSmrg 79301e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 79401e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, 79501e04c3fSmrg stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 7967117f1b4Smrg} 7977117f1b4Smrg 7987117f1b4Smrg 7997117f1b4Smrgvoid GLAPIENTRY 800af69d88dSmrg_mesa_SecondaryColorPointer(GLint size, GLenum type, 8017117f1b4Smrg GLsizei stride, const GLvoid *ptr) 8027117f1b4Smrg{ 80301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 80401e04c3fSmrg 80501e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 8063464ebd5Sriastradh const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 8073464ebd5Sriastradh SHORT_BIT | UNSIGNED_SHORT_BIT | 8083464ebd5Sriastradh INT_BIT | UNSIGNED_INT_BIT | 809af69d88dSmrg HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 810af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 811af69d88dSmrg INT_2_10_10_10_REV_BIT); 8127117f1b4Smrg 81301e04c3fSmrg if (!validate_array_and_format(ctx, "glSecondaryColorPointer", 81401e04c3fSmrg VERT_ATTRIB_COLOR1, legalTypes, 3, 81501e04c3fSmrg BGRA_OR_4, size, type, stride, 81601e04c3fSmrg GL_TRUE, GL_FALSE, GL_FALSE, format, ptr, 81701e04c3fSmrg ctx->Array.VAO)) 81801e04c3fSmrg return; 81901e04c3fSmrg 82001e04c3fSmrg update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, 82101e04c3fSmrg stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 82201e04c3fSmrg} 82301e04c3fSmrg 82401e04c3fSmrg 82501e04c3fSmrgvoid GLAPIENTRY 82601e04c3fSmrg_mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride, 82701e04c3fSmrg const GLvoid *ptr) 82801e04c3fSmrg{ 82901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 83001e04c3fSmrg const GLuint unit = ctx->Array.ActiveTexture; 831af69d88dSmrg 83201e04c3fSmrg update_array(ctx, VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type, 83301e04c3fSmrg stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); 8347117f1b4Smrg} 8357117f1b4Smrg 8367117f1b4Smrg 8377117f1b4Smrgvoid GLAPIENTRY 8387117f1b4Smrg_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, 8397117f1b4Smrg const GLvoid *ptr) 8407117f1b4Smrg{ 8417117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 84201e04c3fSmrg const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; 84301e04c3fSmrg const GLuint unit = ctx->Array.ActiveTexture; 84401e04c3fSmrg 84501e04c3fSmrg GLenum format = GL_RGBA; 84601e04c3fSmrg const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 847af69d88dSmrg ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 848af69d88dSmrg : (SHORT_BIT | INT_BIT | 849af69d88dSmrg HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 850af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 851af69d88dSmrg INT_2_10_10_10_REV_BIT); 8527117f1b4Smrg 85301e04c3fSmrg if (!validate_array_and_format(ctx, "glTexCoordPointer", 85401e04c3fSmrg VERT_ATTRIB_TEX(unit), legalTypes, 85501e04c3fSmrg sizeMin, 4, size, type, stride, 85601e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, format, ptr, 85701e04c3fSmrg ctx->Array.VAO)) 85801e04c3fSmrg return; 85901e04c3fSmrg 86001e04c3fSmrg update_array(ctx, VERT_ATTRIB_TEX(unit), format, 4, size, type, 86101e04c3fSmrg stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); 86201e04c3fSmrg} 86301e04c3fSmrg 86401e04c3fSmrg 86501e04c3fSmrgvoid GLAPIENTRY 86601e04c3fSmrg_mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr) 86701e04c3fSmrg{ 86801e04c3fSmrg /* this is the same type that glEdgeFlag uses */ 86901e04c3fSmrg const GLboolean integer = GL_FALSE; 87001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 871cdc920a0Smrg 87201e04c3fSmrg update_array(ctx, VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE, 87301e04c3fSmrg stride, GL_FALSE, integer, GL_FALSE, ptr); 8747117f1b4Smrg} 8757117f1b4Smrg 8767117f1b4Smrg 8777117f1b4Smrgvoid GLAPIENTRY 8787117f1b4Smrg_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) 8797117f1b4Smrg{ 880af69d88dSmrg /* this is the same type that glEdgeFlag uses */ 881af69d88dSmrg const GLboolean integer = GL_FALSE; 8827117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 8837117f1b4Smrg 88401e04c3fSmrg GLenum format = GL_RGBA; 88501e04c3fSmrg const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; 88601e04c3fSmrg 88701e04c3fSmrg if (!validate_array_and_format(ctx, "glEdgeFlagPointer", 88801e04c3fSmrg VERT_ATTRIB_EDGEFLAG, legalTypes, 88901e04c3fSmrg 1, 1, 1, GL_UNSIGNED_BYTE, stride, 89001e04c3fSmrg GL_FALSE, integer, GL_FALSE, format, ptr, 89101e04c3fSmrg ctx->Array.VAO)) 89201e04c3fSmrg return; 893af69d88dSmrg 89401e04c3fSmrg update_array(ctx, VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE, 89501e04c3fSmrg stride, GL_FALSE, integer, GL_FALSE, ptr); 8967117f1b4Smrg} 8977117f1b4Smrg 8987117f1b4Smrg 899c1f859d4Smrgvoid GLAPIENTRY 90001e04c3fSmrg_mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride, 90101e04c3fSmrg const GLvoid *ptr) 902c1f859d4Smrg{ 903c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 904af69d88dSmrg 90501e04c3fSmrg update_array(ctx, VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride, 90601e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 90701e04c3fSmrg} 90801e04c3fSmrg 90901e04c3fSmrg 91001e04c3fSmrgvoid GLAPIENTRY 91101e04c3fSmrg_mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr) 91201e04c3fSmrg{ 91301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 914c1f859d4Smrg 91501e04c3fSmrg GLenum format = GL_RGBA; 9163464ebd5Sriastradh if (ctx->API != API_OPENGLES) { 9173464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_OPERATION, 9183464ebd5Sriastradh "glPointSizePointer(ES 1.x only)"); 919c1f859d4Smrg return; 920c1f859d4Smrg } 92101e04c3fSmrg 92201e04c3fSmrg const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT); 92301e04c3fSmrg 92401e04c3fSmrg if (!validate_array_and_format(ctx, "glPointSizePointer", 92501e04c3fSmrg VERT_ATTRIB_POINT_SIZE, legalTypes, 92601e04c3fSmrg 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, 92701e04c3fSmrg GL_FALSE, format, ptr, ctx->Array.VAO)) 92801e04c3fSmrg return; 92901e04c3fSmrg 93001e04c3fSmrg update_array(ctx, VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride, 93101e04c3fSmrg GL_FALSE, GL_FALSE, GL_FALSE, ptr); 93201e04c3fSmrg} 93301e04c3fSmrg 93401e04c3fSmrg 93501e04c3fSmrgvoid GLAPIENTRY 93601e04c3fSmrg_mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type, 93701e04c3fSmrg GLboolean normalized, 93801e04c3fSmrg GLsizei stride, const GLvoid *ptr) 93901e04c3fSmrg{ 94001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 94101e04c3fSmrg 94201e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 94301e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, 94401e04c3fSmrg size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); 945c1f859d4Smrg} 946c1f859d4Smrg 947c1f859d4Smrg 9484a49301eSmrg/** 9494a49301eSmrg * Set a generic vertex attribute array. 9504a49301eSmrg * Note that these arrays DO NOT alias the conventional GL vertex arrays 9514a49301eSmrg * (position, normal, color, fog, texcoord, etc). 9524a49301eSmrg */ 9537117f1b4Smrgvoid GLAPIENTRY 954af69d88dSmrg_mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type, 9557117f1b4Smrg GLboolean normalized, 9567117f1b4Smrg GLsizei stride, const GLvoid *ptr) 9577117f1b4Smrg{ 95801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 95901e04c3fSmrg 96001e04c3fSmrg GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 96101e04c3fSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 96201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)"); 96301e04c3fSmrg return; 96401e04c3fSmrg } 96501e04c3fSmrg 9663464ebd5Sriastradh const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 9673464ebd5Sriastradh SHORT_BIT | UNSIGNED_SHORT_BIT | 9683464ebd5Sriastradh INT_BIT | UNSIGNED_INT_BIT | 9693464ebd5Sriastradh HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 970af69d88dSmrg FIXED_ES_BIT | FIXED_GL_BIT | 971af69d88dSmrg UNSIGNED_INT_2_10_10_10_REV_BIT | 972af69d88dSmrg INT_2_10_10_10_REV_BIT | 973af69d88dSmrg UNSIGNED_INT_10F_11F_11F_REV_BIT); 9747117f1b4Smrg 97501e04c3fSmrg if (!validate_array_and_format(ctx, "glVertexAttribPointer", 97601e04c3fSmrg VERT_ATTRIB_GENERIC(index), legalTypes, 97701e04c3fSmrg 1, BGRA_OR_4, size, type, stride, 97801e04c3fSmrg normalized, GL_FALSE, GL_FALSE, format, 97901e04c3fSmrg ptr, ctx->Array.VAO)) 9807117f1b4Smrg return; 9817117f1b4Smrg 98201e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, 98301e04c3fSmrg size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); 98401e04c3fSmrg} 98501e04c3fSmrg 98601e04c3fSmrg 98701e04c3fSmrgvoid GLAPIENTRY 98801e04c3fSmrg_mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type, 98901e04c3fSmrg GLsizei stride, const GLvoid *ptr) 99001e04c3fSmrg{ 99101e04c3fSmrg const GLboolean normalized = GL_FALSE; 99201e04c3fSmrg const GLboolean integer = GL_TRUE; 99301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 99401e04c3fSmrg 99501e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, 99601e04c3fSmrg stride, normalized, integer, GL_FALSE, ptr); 9973464ebd5Sriastradh} 9983464ebd5Sriastradh 9993464ebd5Sriastradh 10003464ebd5Sriastradh/** 10013464ebd5Sriastradh * GL_EXT_gpu_shader4 / GL 3.0. 10023464ebd5Sriastradh * Set an integer-valued vertex attribute array. 10033464ebd5Sriastradh * Note that these arrays DO NOT alias the conventional GL vertex arrays 10043464ebd5Sriastradh * (position, normal, color, fog, texcoord, etc). 10053464ebd5Sriastradh */ 10063464ebd5Sriastradhvoid GLAPIENTRY 10073464ebd5Sriastradh_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, 10083464ebd5Sriastradh GLsizei stride, const GLvoid *ptr) 10093464ebd5Sriastradh{ 10103464ebd5Sriastradh const GLboolean normalized = GL_FALSE; 10113464ebd5Sriastradh const GLboolean integer = GL_TRUE; 10123464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 10133464ebd5Sriastradh 101401e04c3fSmrg GLenum format = GL_RGBA; 1015af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 10163464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)"); 10173464ebd5Sriastradh return; 10187117f1b4Smrg } 10197117f1b4Smrg 102001e04c3fSmrg const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 102101e04c3fSmrg SHORT_BIT | UNSIGNED_SHORT_BIT | 102201e04c3fSmrg INT_BIT | UNSIGNED_INT_BIT); 102301e04c3fSmrg 102401e04c3fSmrg if (!validate_array_and_format(ctx, "glVertexAttribIPointer", 102501e04c3fSmrg VERT_ATTRIB_GENERIC(index), legalTypes, 102601e04c3fSmrg 1, 4, size, type, stride, 102701e04c3fSmrg normalized, integer, GL_FALSE, format, 102801e04c3fSmrg ptr, ctx->Array.VAO)) 102901e04c3fSmrg return; 103001e04c3fSmrg 103101e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type, 103201e04c3fSmrg stride, normalized, integer, GL_FALSE, ptr); 10333464ebd5Sriastradh} 10343464ebd5Sriastradh 10353464ebd5Sriastradh 103601e04c3fSmrgvoid GLAPIENTRY 103701e04c3fSmrg_mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type, 103801e04c3fSmrg GLsizei stride, const GLvoid *ptr) 103901e04c3fSmrg{ 104001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 104101e04c3fSmrg 104201e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, 104301e04c3fSmrg stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); 104401e04c3fSmrg} 104501e04c3fSmrg 10463464ebd5Sriastradh 10473464ebd5Sriastradhvoid GLAPIENTRY 104801e04c3fSmrg_mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, 104901e04c3fSmrg GLsizei stride, const GLvoid *ptr) 10503464ebd5Sriastradh{ 10513464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 10523464ebd5Sriastradh 105301e04c3fSmrg GLenum format = GL_RGBA; 1054af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 105501e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)"); 10567117f1b4Smrg return; 10577117f1b4Smrg } 10587117f1b4Smrg 105901e04c3fSmrg const GLbitfield legalTypes = DOUBLE_BIT; 106001e04c3fSmrg 106101e04c3fSmrg if (!validate_array_and_format(ctx, "glVertexAttribLPointer", 106201e04c3fSmrg VERT_ATTRIB_GENERIC(index), legalTypes, 106301e04c3fSmrg 1, 4, size, type, stride, 106401e04c3fSmrg GL_FALSE, GL_FALSE, GL_TRUE, format, 106501e04c3fSmrg ptr, ctx->Array.VAO)) 106601e04c3fSmrg return; 106701e04c3fSmrg 106801e04c3fSmrg update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type, 106901e04c3fSmrg stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); 107001e04c3fSmrg} 107101e04c3fSmrg 1072af69d88dSmrg 107301e04c3fSmrgvoid 107401e04c3fSmrg_mesa_enable_vertex_array_attrib(struct gl_context *ctx, 107501e04c3fSmrg struct gl_vertex_array_object *vao, 107601e04c3fSmrg gl_vert_attrib attrib) 107701e04c3fSmrg{ 107801e04c3fSmrg assert(attrib < ARRAY_SIZE(vao->VertexAttrib)); 107901e04c3fSmrg assert(!vao->SharedAndImmutable); 10803464ebd5Sriastradh 108101e04c3fSmrg if (!vao->VertexAttrib[attrib].Enabled) { 1082af69d88dSmrg /* was disabled, now being enabled */ 108301e04c3fSmrg vao->VertexAttrib[attrib].Enabled = GL_TRUE; 108401e04c3fSmrg const GLbitfield array_bit = VERT_BIT(attrib); 108501e04c3fSmrg vao->_Enabled |= array_bit; 108601e04c3fSmrg vao->NewArrays |= array_bit; 108701e04c3fSmrg 108801e04c3fSmrg if (vao == ctx->Array.VAO) 108901e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 109001e04c3fSmrg 109101e04c3fSmrg /* Update the map mode if needed */ 109201e04c3fSmrg if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0)) 109301e04c3fSmrg update_attribute_map_mode(ctx, vao); 109401e04c3fSmrg } 109501e04c3fSmrg} 109601e04c3fSmrg 109701e04c3fSmrgstatic void 109801e04c3fSmrgenable_vertex_array_attrib(struct gl_context *ctx, 109901e04c3fSmrg struct gl_vertex_array_object *vao, 110001e04c3fSmrg GLuint index, 110101e04c3fSmrg const char *func) 110201e04c3fSmrg{ 110301e04c3fSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 110401e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); 110501e04c3fSmrg return; 1106af69d88dSmrg } 110701e04c3fSmrg 110801e04c3fSmrg _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index)); 11093464ebd5Sriastradh} 11103464ebd5Sriastradh 11113464ebd5Sriastradh 11123464ebd5Sriastradhvoid GLAPIENTRY 111301e04c3fSmrg_mesa_EnableVertexAttribArray(GLuint index) 111401e04c3fSmrg{ 111501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 111601e04c3fSmrg enable_vertex_array_attrib(ctx, ctx->Array.VAO, index, 111701e04c3fSmrg "glEnableVertexAttribArray"); 111801e04c3fSmrg} 111901e04c3fSmrg 112001e04c3fSmrg 112101e04c3fSmrgvoid GLAPIENTRY 112201e04c3fSmrg_mesa_EnableVertexAttribArray_no_error(GLuint index) 112301e04c3fSmrg{ 112401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 112501e04c3fSmrg _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO, 112601e04c3fSmrg VERT_ATTRIB_GENERIC(index)); 112701e04c3fSmrg} 112801e04c3fSmrg 112901e04c3fSmrg 113001e04c3fSmrgvoid GLAPIENTRY 113101e04c3fSmrg_mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index) 11323464ebd5Sriastradh{ 113301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 1134af69d88dSmrg struct gl_vertex_array_object *vao; 113501e04c3fSmrg 113601e04c3fSmrg /* The ARB_direct_state_access specification says: 113701e04c3fSmrg * 113801e04c3fSmrg * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib 113901e04c3fSmrg * and DisableVertexArrayAttrib if <vaobj> is not 114001e04c3fSmrg * [compatibility profile: zero or] the name of an existing vertex 114101e04c3fSmrg * array object." 114201e04c3fSmrg */ 114301e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib"); 114401e04c3fSmrg if (!vao) 114501e04c3fSmrg return; 114601e04c3fSmrg 114701e04c3fSmrg enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib"); 114801e04c3fSmrg} 114901e04c3fSmrg 115001e04c3fSmrg 115101e04c3fSmrgvoid GLAPIENTRY 115201e04c3fSmrg_mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index) 115301e04c3fSmrg{ 115401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 115501e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 115601e04c3fSmrg _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index)); 115701e04c3fSmrg} 115801e04c3fSmrg 115901e04c3fSmrg 116001e04c3fSmrgvoid 116101e04c3fSmrg_mesa_disable_vertex_array_attrib(struct gl_context *ctx, 116201e04c3fSmrg struct gl_vertex_array_object *vao, 116301e04c3fSmrg gl_vert_attrib attrib) 116401e04c3fSmrg{ 116501e04c3fSmrg assert(attrib < ARRAY_SIZE(vao->VertexAttrib)); 116601e04c3fSmrg assert(!vao->SharedAndImmutable); 116701e04c3fSmrg 116801e04c3fSmrg if (vao->VertexAttrib[attrib].Enabled) { 116901e04c3fSmrg /* was enabled, now being disabled */ 117001e04c3fSmrg vao->VertexAttrib[attrib].Enabled = GL_FALSE; 117101e04c3fSmrg const GLbitfield array_bit = VERT_BIT(attrib); 117201e04c3fSmrg vao->_Enabled &= ~array_bit; 117301e04c3fSmrg vao->NewArrays |= array_bit; 117401e04c3fSmrg 117501e04c3fSmrg if (vao == ctx->Array.VAO) 117601e04c3fSmrg ctx->NewState |= _NEW_ARRAY; 117701e04c3fSmrg 117801e04c3fSmrg /* Update the map mode if needed */ 117901e04c3fSmrg if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0)) 118001e04c3fSmrg update_attribute_map_mode(ctx, vao); 118101e04c3fSmrg } 118201e04c3fSmrg} 118301e04c3fSmrg 118401e04c3fSmrg 118501e04c3fSmrgvoid GLAPIENTRY 118601e04c3fSmrg_mesa_DisableVertexAttribArray(GLuint index) 118701e04c3fSmrg{ 11883464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 11893464ebd5Sriastradh 1190af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 119101e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)"); 11923464ebd5Sriastradh return; 11933464ebd5Sriastradh } 11943464ebd5Sriastradh 119501e04c3fSmrg const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 119601e04c3fSmrg _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib); 119701e04c3fSmrg} 11983464ebd5Sriastradh 1199af69d88dSmrg 120001e04c3fSmrgvoid GLAPIENTRY 120101e04c3fSmrg_mesa_DisableVertexAttribArray_no_error(GLuint index) 120201e04c3fSmrg{ 120301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 120401e04c3fSmrg const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 120501e04c3fSmrg _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib); 120601e04c3fSmrg} 120701e04c3fSmrg 120801e04c3fSmrg 120901e04c3fSmrgvoid GLAPIENTRY 121001e04c3fSmrg_mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index) 121101e04c3fSmrg{ 121201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 121301e04c3fSmrg struct gl_vertex_array_object *vao; 121401e04c3fSmrg 121501e04c3fSmrg /* The ARB_direct_state_access specification says: 121601e04c3fSmrg * 121701e04c3fSmrg * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib 121801e04c3fSmrg * and DisableVertexArrayAttrib if <vaobj> is not 121901e04c3fSmrg * [compatibility profile: zero or] the name of an existing vertex 122001e04c3fSmrg * array object." 122101e04c3fSmrg */ 122201e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib"); 122301e04c3fSmrg if (!vao) 122401e04c3fSmrg return; 122501e04c3fSmrg 122601e04c3fSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 122701e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)"); 122801e04c3fSmrg return; 1229af69d88dSmrg } 123001e04c3fSmrg 123101e04c3fSmrg const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 123201e04c3fSmrg _mesa_disable_vertex_array_attrib(ctx, vao, attrib); 123301e04c3fSmrg} 123401e04c3fSmrg 123501e04c3fSmrg 123601e04c3fSmrgvoid GLAPIENTRY 123701e04c3fSmrg_mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index) 123801e04c3fSmrg{ 123901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 124001e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 124101e04c3fSmrg const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 124201e04c3fSmrg _mesa_disable_vertex_array_attrib(ctx, vao, attrib); 12433464ebd5Sriastradh} 12443464ebd5Sriastradh 12453464ebd5Sriastradh 12463464ebd5Sriastradh/** 12473464ebd5Sriastradh * Return info for a vertex attribute array (no alias with legacy 12483464ebd5Sriastradh * vertex attributes (pos, normal, color, etc)). This function does 12493464ebd5Sriastradh * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query. 12503464ebd5Sriastradh */ 12513464ebd5Sriastradhstatic GLuint 125201e04c3fSmrgget_vertex_array_attrib(struct gl_context *ctx, 125301e04c3fSmrg const struct gl_vertex_array_object *vao, 125401e04c3fSmrg GLuint index, GLenum pname, 125501e04c3fSmrg const char *caller) 12563464ebd5Sriastradh{ 125701e04c3fSmrg const struct gl_array_attributes *array; 12583464ebd5Sriastradh 1259af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 12603464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); 12613464ebd5Sriastradh return 0; 12623464ebd5Sriastradh } 12633464ebd5Sriastradh 126401e04c3fSmrg assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib)); 12653464ebd5Sriastradh 1266af69d88dSmrg array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; 12673464ebd5Sriastradh 12683464ebd5Sriastradh switch (pname) { 12693464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 12703464ebd5Sriastradh return array->Enabled; 12713464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 1272af69d88dSmrg return (array->Format == GL_BGRA) ? GL_BGRA : array->Size; 12733464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 12743464ebd5Sriastradh return array->Stride; 12753464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 12763464ebd5Sriastradh return array->Type; 12773464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 12783464ebd5Sriastradh return array->Normalized; 12793464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: 128001e04c3fSmrg return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name; 12813464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 1282af69d88dSmrg if ((_mesa_is_desktop_gl(ctx) 1283af69d88dSmrg && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4)) 1284af69d88dSmrg || _mesa_is_gles3(ctx)) { 12853464ebd5Sriastradh return array->Integer; 12864a49301eSmrg } 12873464ebd5Sriastradh goto error; 128801e04c3fSmrg case GL_VERTEX_ATTRIB_ARRAY_LONG: 128901e04c3fSmrg if (_mesa_is_desktop_gl(ctx)) { 129001e04c3fSmrg return array->Doubles; 129101e04c3fSmrg } 129201e04c3fSmrg goto error; 12933464ebd5Sriastradh case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: 1294af69d88dSmrg if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays) 1295af69d88dSmrg || _mesa_is_gles3(ctx)) { 129601e04c3fSmrg return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor; 1297af69d88dSmrg } 1298af69d88dSmrg goto error; 1299af69d88dSmrg case GL_VERTEX_ATTRIB_BINDING: 130001e04c3fSmrg if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { 130101e04c3fSmrg return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0; 1302af69d88dSmrg } 1303af69d88dSmrg goto error; 1304af69d88dSmrg case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: 130501e04c3fSmrg if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { 1306af69d88dSmrg return array->RelativeOffset; 13074a49301eSmrg } 13083464ebd5Sriastradh goto error; 13093464ebd5Sriastradh default: 13103464ebd5Sriastradh ; /* fall-through */ 13113464ebd5Sriastradh } 13124a49301eSmrg 13133464ebd5Sriastradherror: 13143464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); 13153464ebd5Sriastradh return 0; 13163464ebd5Sriastradh} 13173464ebd5Sriastradh 13183464ebd5Sriastradh 13193464ebd5Sriastradhstatic const GLfloat * 13203464ebd5Sriastradhget_current_attrib(struct gl_context *ctx, GLuint index, const char *function) 13213464ebd5Sriastradh{ 13223464ebd5Sriastradh if (index == 0) { 1323af69d88dSmrg if (_mesa_attr_zero_aliases_vertex(ctx)) { 13243464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); 13253464ebd5Sriastradh return NULL; 13263464ebd5Sriastradh } 13273464ebd5Sriastradh } 1328af69d88dSmrg else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 13293464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, 13303464ebd5Sriastradh "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); 13313464ebd5Sriastradh return NULL; 13323464ebd5Sriastradh } 13333464ebd5Sriastradh 133401e04c3fSmrg assert(VERT_ATTRIB_GENERIC(index) < 133501e04c3fSmrg ARRAY_SIZE(ctx->Array.VAO->VertexAttrib)); 1336af69d88dSmrg 13373464ebd5Sriastradh FLUSH_CURRENT(ctx, 0); 1338af69d88dSmrg return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)]; 13393464ebd5Sriastradh} 13403464ebd5Sriastradh 13413464ebd5Sriastradhvoid GLAPIENTRY 1342af69d88dSmrg_mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) 13433464ebd5Sriastradh{ 13443464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 13453464ebd5Sriastradh 13463464ebd5Sriastradh if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 13473464ebd5Sriastradh const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv"); 13483464ebd5Sriastradh if (v != NULL) { 13493464ebd5Sriastradh COPY_4V(params, v); 13503464ebd5Sriastradh } 13514a49301eSmrg } 13524a49301eSmrg else { 135301e04c3fSmrg params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO, 135401e04c3fSmrg index, pname, 13553464ebd5Sriastradh "glGetVertexAttribfv"); 13564a49301eSmrg } 13573464ebd5Sriastradh} 13584a49301eSmrg 13593464ebd5Sriastradh 13603464ebd5Sriastradhvoid GLAPIENTRY 1361af69d88dSmrg_mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) 13623464ebd5Sriastradh{ 13633464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 13643464ebd5Sriastradh 13653464ebd5Sriastradh if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 13663464ebd5Sriastradh const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv"); 13673464ebd5Sriastradh if (v != NULL) { 13683464ebd5Sriastradh params[0] = (GLdouble) v[0]; 13693464ebd5Sriastradh params[1] = (GLdouble) v[1]; 13703464ebd5Sriastradh params[2] = (GLdouble) v[2]; 13713464ebd5Sriastradh params[3] = (GLdouble) v[3]; 13723464ebd5Sriastradh } 13733464ebd5Sriastradh } 13743464ebd5Sriastradh else { 137501e04c3fSmrg params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO, 137601e04c3fSmrg index, pname, 13773464ebd5Sriastradh "glGetVertexAttribdv"); 13787117f1b4Smrg } 13793464ebd5Sriastradh} 13807117f1b4Smrg 138101e04c3fSmrgvoid GLAPIENTRY 138201e04c3fSmrg_mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params) 138301e04c3fSmrg{ 138401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 138501e04c3fSmrg 138601e04c3fSmrg if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 138701e04c3fSmrg const GLdouble *v = 138801e04c3fSmrg (const GLdouble *)get_current_attrib(ctx, index, 138901e04c3fSmrg "glGetVertexAttribLdv"); 139001e04c3fSmrg if (v != NULL) { 139101e04c3fSmrg params[0] = v[0]; 139201e04c3fSmrg params[1] = v[1]; 139301e04c3fSmrg params[2] = v[2]; 139401e04c3fSmrg params[3] = v[3]; 139501e04c3fSmrg } 139601e04c3fSmrg } 139701e04c3fSmrg else { 139801e04c3fSmrg params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO, 139901e04c3fSmrg index, pname, 140001e04c3fSmrg "glGetVertexAttribLdv"); 140101e04c3fSmrg } 140201e04c3fSmrg} 14033464ebd5Sriastradh 14043464ebd5Sriastradhvoid GLAPIENTRY 1405af69d88dSmrg_mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params) 14063464ebd5Sriastradh{ 14073464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 14083464ebd5Sriastradh 14093464ebd5Sriastradh if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 14103464ebd5Sriastradh const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv"); 14113464ebd5Sriastradh if (v != NULL) { 14123464ebd5Sriastradh /* XXX should floats in[0,1] be scaled to full int range? */ 14133464ebd5Sriastradh params[0] = (GLint) v[0]; 14143464ebd5Sriastradh params[1] = (GLint) v[1]; 14153464ebd5Sriastradh params[2] = (GLint) v[2]; 14163464ebd5Sriastradh params[3] = (GLint) v[3]; 14173464ebd5Sriastradh } 14183464ebd5Sriastradh } 14193464ebd5Sriastradh else { 142001e04c3fSmrg params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO, 142101e04c3fSmrg index, pname, 14223464ebd5Sriastradh "glGetVertexAttribiv"); 14233464ebd5Sriastradh } 14243464ebd5Sriastradh} 14253464ebd5Sriastradh 142601e04c3fSmrgvoid GLAPIENTRY 142701e04c3fSmrg_mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params) 142801e04c3fSmrg{ 142901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 143001e04c3fSmrg 143101e04c3fSmrg if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 143201e04c3fSmrg const GLuint64 *v = 143301e04c3fSmrg (const GLuint64 *)get_current_attrib(ctx, index, 143401e04c3fSmrg "glGetVertexAttribLui64vARB"); 143501e04c3fSmrg if (v != NULL) { 143601e04c3fSmrg params[0] = v[0]; 143701e04c3fSmrg params[1] = v[1]; 143801e04c3fSmrg params[2] = v[2]; 143901e04c3fSmrg params[3] = v[3]; 144001e04c3fSmrg } 144101e04c3fSmrg } 144201e04c3fSmrg else { 144301e04c3fSmrg params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO, 144401e04c3fSmrg index, pname, 144501e04c3fSmrg "glGetVertexAttribLui64vARB"); 144601e04c3fSmrg } 144701e04c3fSmrg} 144801e04c3fSmrg 14493464ebd5Sriastradh 14503464ebd5Sriastradh/** GL 3.0 */ 14513464ebd5Sriastradhvoid GLAPIENTRY 14523464ebd5Sriastradh_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) 14533464ebd5Sriastradh{ 14543464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 14553464ebd5Sriastradh 14563464ebd5Sriastradh if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 1457af69d88dSmrg const GLint *v = (const GLint *) 14583464ebd5Sriastradh get_current_attrib(ctx, index, "glGetVertexAttribIiv"); 14593464ebd5Sriastradh if (v != NULL) { 1460af69d88dSmrg COPY_4V(params, v); 14613464ebd5Sriastradh } 14623464ebd5Sriastradh } 14633464ebd5Sriastradh else { 146401e04c3fSmrg params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO, 146501e04c3fSmrg index, pname, 14663464ebd5Sriastradh "glGetVertexAttribIiv"); 14673464ebd5Sriastradh } 14683464ebd5Sriastradh} 14693464ebd5Sriastradh 14703464ebd5Sriastradh 14713464ebd5Sriastradh/** GL 3.0 */ 14723464ebd5Sriastradhvoid GLAPIENTRY 14733464ebd5Sriastradh_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) 14743464ebd5Sriastradh{ 14753464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 14763464ebd5Sriastradh 14773464ebd5Sriastradh if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 1478af69d88dSmrg const GLuint *v = (const GLuint *) 14793464ebd5Sriastradh get_current_attrib(ctx, index, "glGetVertexAttribIuiv"); 14803464ebd5Sriastradh if (v != NULL) { 1481af69d88dSmrg COPY_4V(params, v); 14823464ebd5Sriastradh } 14833464ebd5Sriastradh } 14843464ebd5Sriastradh else { 148501e04c3fSmrg params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO, 148601e04c3fSmrg index, pname, 14873464ebd5Sriastradh "glGetVertexAttribIuiv"); 14883464ebd5Sriastradh } 14893464ebd5Sriastradh} 14903464ebd5Sriastradh 14913464ebd5Sriastradh 14923464ebd5Sriastradhvoid GLAPIENTRY 1493af69d88dSmrg_mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) 14943464ebd5Sriastradh{ 14953464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 14963464ebd5Sriastradh 1497af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 14983464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); 14993464ebd5Sriastradh return; 15003464ebd5Sriastradh } 15013464ebd5Sriastradh 15023464ebd5Sriastradh if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 15033464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); 15043464ebd5Sriastradh return; 15053464ebd5Sriastradh } 15063464ebd5Sriastradh 150701e04c3fSmrg assert(VERT_ATTRIB_GENERIC(index) < 150801e04c3fSmrg ARRAY_SIZE(ctx->Array.VAO->VertexAttrib)); 150901e04c3fSmrg 151001e04c3fSmrg *pointer = (GLvoid *) 151101e04c3fSmrg ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr; 151201e04c3fSmrg} 151301e04c3fSmrg 151401e04c3fSmrg 151501e04c3fSmrg/** ARB_direct_state_access */ 151601e04c3fSmrgvoid GLAPIENTRY 151701e04c3fSmrg_mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index, 151801e04c3fSmrg GLenum pname, GLint *params) 151901e04c3fSmrg{ 152001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 152101e04c3fSmrg struct gl_vertex_array_object *vao; 152201e04c3fSmrg 152301e04c3fSmrg /* The ARB_direct_state_access specification says: 152401e04c3fSmrg * 152501e04c3fSmrg * "An INVALID_OPERATION error is generated if <vaobj> is not 152601e04c3fSmrg * [compatibility profile: zero or] the name of an existing 152701e04c3fSmrg * vertex array object." 152801e04c3fSmrg */ 152901e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv"); 153001e04c3fSmrg if (!vao) 153101e04c3fSmrg return; 153201e04c3fSmrg 153301e04c3fSmrg /* The ARB_direct_state_access specification says: 153401e04c3fSmrg * 153501e04c3fSmrg * "For GetVertexArrayIndexediv, <pname> must be one of 153601e04c3fSmrg * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE, 153701e04c3fSmrg * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE, 153801e04c3fSmrg * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER, 153901e04c3fSmrg * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or 154001e04c3fSmrg * VERTEX_ATTRIB_RELATIVE_OFFSET." 154101e04c3fSmrg * 154201e04c3fSmrg * and: 154301e04c3fSmrg * 154401e04c3fSmrg * "Add GetVertexArrayIndexediv in 'Get Command' for 154501e04c3fSmrg * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 154601e04c3fSmrg * VERTEX_ATTRIB_BINDING, 154701e04c3fSmrg * VERTEX_ATTRIB_RELATIVE_OFFSET, 154801e04c3fSmrg * VERTEX_BINDING_OFFSET, and 154901e04c3fSmrg * VERTEX_BINDING_STRIDE states" 155001e04c3fSmrg * 155101e04c3fSmrg * The only parameter name common to both lists is 155201e04c3fSmrg * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER 155301e04c3fSmrg * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems 155401e04c3fSmrg * pretty clear however that the intent is that it should be possible 155501e04c3fSmrg * to query all vertex attrib and binding states that can be set with 155601e04c3fSmrg * a DSA function. 155701e04c3fSmrg */ 155801e04c3fSmrg switch (pname) { 155901e04c3fSmrg case GL_VERTEX_BINDING_OFFSET: 156001e04c3fSmrg params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset; 156101e04c3fSmrg break; 156201e04c3fSmrg case GL_VERTEX_BINDING_STRIDE: 156301e04c3fSmrg params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride; 156401e04c3fSmrg break; 156501e04c3fSmrg case GL_VERTEX_BINDING_DIVISOR: 156601e04c3fSmrg params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor; 156701e04c3fSmrg break; 156801e04c3fSmrg case GL_VERTEX_BINDING_BUFFER: 156901e04c3fSmrg params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name; 157001e04c3fSmrg break; 157101e04c3fSmrg default: 157201e04c3fSmrg params[0] = get_vertex_array_attrib(ctx, vao, index, pname, 157301e04c3fSmrg "glGetVertexArrayIndexediv"); 157401e04c3fSmrg break; 157501e04c3fSmrg } 157601e04c3fSmrg} 157701e04c3fSmrg 157801e04c3fSmrg 157901e04c3fSmrgvoid GLAPIENTRY 158001e04c3fSmrg_mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, 158101e04c3fSmrg GLenum pname, GLint64 *params) 158201e04c3fSmrg{ 158301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 158401e04c3fSmrg struct gl_vertex_array_object *vao; 158501e04c3fSmrg 158601e04c3fSmrg /* The ARB_direct_state_access specification says: 158701e04c3fSmrg * 158801e04c3fSmrg * "An INVALID_OPERATION error is generated if <vaobj> is not 158901e04c3fSmrg * [compatibility profile: zero or] the name of an existing 159001e04c3fSmrg * vertex array object." 159101e04c3fSmrg */ 159201e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv"); 159301e04c3fSmrg if (!vao) 159401e04c3fSmrg return; 159501e04c3fSmrg 159601e04c3fSmrg /* The ARB_direct_state_access specification says: 159701e04c3fSmrg * 159801e04c3fSmrg * "For GetVertexArrayIndexed64iv, <pname> must be 159901e04c3fSmrg * VERTEX_BINDING_OFFSET." 160001e04c3fSmrg * 160101e04c3fSmrg * and: 160201e04c3fSmrg * 160301e04c3fSmrg * "An INVALID_ENUM error is generated if <pname> is not one of 160401e04c3fSmrg * the valid values listed above for the corresponding command." 160501e04c3fSmrg */ 160601e04c3fSmrg if (pname != GL_VERTEX_BINDING_OFFSET) { 160701e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv(" 160801e04c3fSmrg "pname != GL_VERTEX_BINDING_OFFSET)"); 160901e04c3fSmrg return; 161001e04c3fSmrg } 161101e04c3fSmrg 161201e04c3fSmrg /* The ARB_direct_state_access specification says: 161301e04c3fSmrg * 161401e04c3fSmrg * "An INVALID_VALUE error is generated if <index> is greater than 161501e04c3fSmrg * or equal to the value of MAX_VERTEX_ATTRIBS." 161601e04c3fSmrg * 161701e04c3fSmrg * Since the index refers to a buffer binding in this case, the intended 161801e04c3fSmrg * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently 161901e04c3fSmrg * required to be the same, so in practice this doesn't matter. 162001e04c3fSmrg */ 162101e04c3fSmrg if (index >= ctx->Const.MaxVertexAttribBindings) { 162201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index" 162301e04c3fSmrg "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))", 162401e04c3fSmrg index, ctx->Const.MaxVertexAttribBindings); 162501e04c3fSmrg return; 162601e04c3fSmrg } 16273464ebd5Sriastradh 162801e04c3fSmrg params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset; 16297117f1b4Smrg} 16307117f1b4Smrg 16317117f1b4Smrg 16327117f1b4Smrgvoid GLAPIENTRY 16337117f1b4Smrg_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 16347117f1b4Smrg GLsizei count, const GLvoid *ptr) 16357117f1b4Smrg{ 16367117f1b4Smrg (void) count; 16377117f1b4Smrg _mesa_VertexPointer(size, type, stride, ptr); 16387117f1b4Smrg} 16397117f1b4Smrg 16407117f1b4Smrg 16417117f1b4Smrgvoid GLAPIENTRY 16427117f1b4Smrg_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 16437117f1b4Smrg const GLvoid *ptr) 16447117f1b4Smrg{ 16457117f1b4Smrg (void) count; 16467117f1b4Smrg _mesa_NormalPointer(type, stride, ptr); 16477117f1b4Smrg} 16487117f1b4Smrg 16497117f1b4Smrg 16507117f1b4Smrgvoid GLAPIENTRY 16517117f1b4Smrg_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 16527117f1b4Smrg const GLvoid *ptr) 16537117f1b4Smrg{ 16547117f1b4Smrg (void) count; 16557117f1b4Smrg _mesa_ColorPointer(size, type, stride, ptr); 16567117f1b4Smrg} 16577117f1b4Smrg 16587117f1b4Smrg 16597117f1b4Smrgvoid GLAPIENTRY 16607117f1b4Smrg_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 16617117f1b4Smrg const GLvoid *ptr) 16627117f1b4Smrg{ 16637117f1b4Smrg (void) count; 16647117f1b4Smrg _mesa_IndexPointer(type, stride, ptr); 16657117f1b4Smrg} 16667117f1b4Smrg 16677117f1b4Smrg 16687117f1b4Smrgvoid GLAPIENTRY 16697117f1b4Smrg_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 16707117f1b4Smrg GLsizei count, const GLvoid *ptr) 16717117f1b4Smrg{ 16727117f1b4Smrg (void) count; 16737117f1b4Smrg _mesa_TexCoordPointer(size, type, stride, ptr); 16747117f1b4Smrg} 16757117f1b4Smrg 16767117f1b4Smrg 16777117f1b4Smrgvoid GLAPIENTRY 16787117f1b4Smrg_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 16797117f1b4Smrg{ 16807117f1b4Smrg (void) count; 16817117f1b4Smrg _mesa_EdgeFlagPointer(stride, ptr); 16827117f1b4Smrg} 16837117f1b4Smrg 16847117f1b4Smrg 16857117f1b4Smrgvoid GLAPIENTRY 16867117f1b4Smrg_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 16877117f1b4Smrg{ 16887117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 16897117f1b4Smrg GLboolean tflag, cflag, nflag; /* enable/disable flags */ 16907117f1b4Smrg GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ 16917117f1b4Smrg GLenum ctype = 0; /* color type */ 16927117f1b4Smrg GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ 16937117f1b4Smrg const GLint toffset = 0; /* always zero */ 16947117f1b4Smrg GLint defstride; /* default stride */ 16957117f1b4Smrg GLint c, f; 16967117f1b4Smrg 16977117f1b4Smrg f = sizeof(GLfloat); 16987117f1b4Smrg c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 16997117f1b4Smrg 17007117f1b4Smrg if (stride < 0) { 17017117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 17027117f1b4Smrg return; 17037117f1b4Smrg } 17047117f1b4Smrg 17057117f1b4Smrg switch (format) { 17067117f1b4Smrg case GL_V2F: 17077117f1b4Smrg tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 17087117f1b4Smrg tcomps = 0; ccomps = 0; vcomps = 2; 17097117f1b4Smrg voffset = 0; 17107117f1b4Smrg defstride = 2*f; 17117117f1b4Smrg break; 17127117f1b4Smrg case GL_V3F: 17137117f1b4Smrg tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 17147117f1b4Smrg tcomps = 0; ccomps = 0; vcomps = 3; 17157117f1b4Smrg voffset = 0; 17167117f1b4Smrg defstride = 3*f; 17177117f1b4Smrg break; 17187117f1b4Smrg case GL_C4UB_V2F: 17197117f1b4Smrg tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 17207117f1b4Smrg tcomps = 0; ccomps = 4; vcomps = 2; 17217117f1b4Smrg ctype = GL_UNSIGNED_BYTE; 17227117f1b4Smrg coffset = 0; 17237117f1b4Smrg voffset = c; 17247117f1b4Smrg defstride = c + 2*f; 17257117f1b4Smrg break; 17267117f1b4Smrg case GL_C4UB_V3F: 17277117f1b4Smrg tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 17287117f1b4Smrg tcomps = 0; ccomps = 4; vcomps = 3; 17297117f1b4Smrg ctype = GL_UNSIGNED_BYTE; 17307117f1b4Smrg coffset = 0; 17317117f1b4Smrg voffset = c; 17327117f1b4Smrg defstride = c + 3*f; 17337117f1b4Smrg break; 17347117f1b4Smrg case GL_C3F_V3F: 17357117f1b4Smrg tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 17367117f1b4Smrg tcomps = 0; ccomps = 3; vcomps = 3; 17377117f1b4Smrg ctype = GL_FLOAT; 17387117f1b4Smrg coffset = 0; 17397117f1b4Smrg voffset = 3*f; 17407117f1b4Smrg defstride = 6*f; 17417117f1b4Smrg break; 17427117f1b4Smrg case GL_N3F_V3F: 17437117f1b4Smrg tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; 17447117f1b4Smrg tcomps = 0; ccomps = 0; vcomps = 3; 17457117f1b4Smrg noffset = 0; 17467117f1b4Smrg voffset = 3*f; 17477117f1b4Smrg defstride = 6*f; 17487117f1b4Smrg break; 17497117f1b4Smrg case GL_C4F_N3F_V3F: 17507117f1b4Smrg tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; 17517117f1b4Smrg tcomps = 0; ccomps = 4; vcomps = 3; 17527117f1b4Smrg ctype = GL_FLOAT; 17537117f1b4Smrg coffset = 0; 17547117f1b4Smrg noffset = 4*f; 17557117f1b4Smrg voffset = 7*f; 17567117f1b4Smrg defstride = 10*f; 17577117f1b4Smrg break; 17587117f1b4Smrg case GL_T2F_V3F: 17597117f1b4Smrg tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 17607117f1b4Smrg tcomps = 2; ccomps = 0; vcomps = 3; 17617117f1b4Smrg voffset = 2*f; 17627117f1b4Smrg defstride = 5*f; 17637117f1b4Smrg break; 17647117f1b4Smrg case GL_T4F_V4F: 17657117f1b4Smrg tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 17667117f1b4Smrg tcomps = 4; ccomps = 0; vcomps = 4; 17677117f1b4Smrg voffset = 4*f; 17687117f1b4Smrg defstride = 8*f; 17697117f1b4Smrg break; 17707117f1b4Smrg case GL_T2F_C4UB_V3F: 17717117f1b4Smrg tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 17727117f1b4Smrg tcomps = 2; ccomps = 4; vcomps = 3; 17737117f1b4Smrg ctype = GL_UNSIGNED_BYTE; 17747117f1b4Smrg coffset = 2*f; 17757117f1b4Smrg voffset = c+2*f; 17767117f1b4Smrg defstride = c+5*f; 17777117f1b4Smrg break; 17787117f1b4Smrg case GL_T2F_C3F_V3F: 17797117f1b4Smrg tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 17807117f1b4Smrg tcomps = 2; ccomps = 3; vcomps = 3; 17817117f1b4Smrg ctype = GL_FLOAT; 17827117f1b4Smrg coffset = 2*f; 17837117f1b4Smrg voffset = 5*f; 17847117f1b4Smrg defstride = 8*f; 17857117f1b4Smrg break; 17867117f1b4Smrg case GL_T2F_N3F_V3F: 17877117f1b4Smrg tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; 17887117f1b4Smrg tcomps = 2; ccomps = 0; vcomps = 3; 17897117f1b4Smrg noffset = 2*f; 17907117f1b4Smrg voffset = 5*f; 17917117f1b4Smrg defstride = 8*f; 17927117f1b4Smrg break; 17937117f1b4Smrg case GL_T2F_C4F_N3F_V3F: 17947117f1b4Smrg tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 17957117f1b4Smrg tcomps = 2; ccomps = 4; vcomps = 3; 17967117f1b4Smrg ctype = GL_FLOAT; 17977117f1b4Smrg coffset = 2*f; 17987117f1b4Smrg noffset = 6*f; 17997117f1b4Smrg voffset = 9*f; 18007117f1b4Smrg defstride = 12*f; 18017117f1b4Smrg break; 18027117f1b4Smrg case GL_T4F_C4F_N3F_V4F: 18037117f1b4Smrg tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 18047117f1b4Smrg tcomps = 4; ccomps = 4; vcomps = 4; 18057117f1b4Smrg ctype = GL_FLOAT; 18067117f1b4Smrg coffset = 4*f; 18077117f1b4Smrg noffset = 8*f; 18087117f1b4Smrg voffset = 11*f; 18097117f1b4Smrg defstride = 15*f; 18107117f1b4Smrg break; 18117117f1b4Smrg default: 18127117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 18137117f1b4Smrg return; 18147117f1b4Smrg } 18157117f1b4Smrg 18167117f1b4Smrg if (stride==0) { 18177117f1b4Smrg stride = defstride; 18187117f1b4Smrg } 18197117f1b4Smrg 18207117f1b4Smrg _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 18217117f1b4Smrg _mesa_DisableClientState( GL_INDEX_ARRAY ); 18227117f1b4Smrg /* XXX also disable secondary color and generic arrays? */ 18237117f1b4Smrg 18247117f1b4Smrg /* Texcoords */ 18257117f1b4Smrg if (tflag) { 18267117f1b4Smrg _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 18277117f1b4Smrg _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, 18287117f1b4Smrg (GLubyte *) pointer + toffset ); 18297117f1b4Smrg } 18307117f1b4Smrg else { 18317117f1b4Smrg _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 18327117f1b4Smrg } 18337117f1b4Smrg 18347117f1b4Smrg /* Color */ 18357117f1b4Smrg if (cflag) { 18367117f1b4Smrg _mesa_EnableClientState( GL_COLOR_ARRAY ); 18377117f1b4Smrg _mesa_ColorPointer( ccomps, ctype, stride, 18387117f1b4Smrg (GLubyte *) pointer + coffset ); 18397117f1b4Smrg } 18407117f1b4Smrg else { 18417117f1b4Smrg _mesa_DisableClientState( GL_COLOR_ARRAY ); 18427117f1b4Smrg } 18437117f1b4Smrg 18447117f1b4Smrg 18457117f1b4Smrg /* Normals */ 18467117f1b4Smrg if (nflag) { 18477117f1b4Smrg _mesa_EnableClientState( GL_NORMAL_ARRAY ); 18487117f1b4Smrg _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); 18497117f1b4Smrg } 18507117f1b4Smrg else { 18517117f1b4Smrg _mesa_DisableClientState( GL_NORMAL_ARRAY ); 18527117f1b4Smrg } 18537117f1b4Smrg 18547117f1b4Smrg /* Vertices */ 18557117f1b4Smrg _mesa_EnableClientState( GL_VERTEX_ARRAY ); 18567117f1b4Smrg _mesa_VertexPointer( vcomps, GL_FLOAT, stride, 18577117f1b4Smrg (GLubyte *) pointer + voffset ); 18587117f1b4Smrg} 18597117f1b4Smrg 18607117f1b4Smrg 18617117f1b4Smrgvoid GLAPIENTRY 18627117f1b4Smrg_mesa_LockArraysEXT(GLint first, GLsizei count) 18637117f1b4Smrg{ 18647117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 1865af69d88dSmrg 18667117f1b4Smrg if (MESA_VERBOSE & VERBOSE_API) 18677117f1b4Smrg _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 18687117f1b4Smrg 1869c1f859d4Smrg if (first < 0) { 1870c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 1871c1f859d4Smrg return; 18727117f1b4Smrg } 1873c1f859d4Smrg if (count <= 0) { 1874c1f859d4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 1875c1f859d4Smrg return; 1876c1f859d4Smrg } 1877c1f859d4Smrg if (ctx->Array.LockCount != 0) { 1878c1f859d4Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 1879c1f859d4Smrg return; 18807117f1b4Smrg } 18817117f1b4Smrg 1882c1f859d4Smrg ctx->Array.LockFirst = first; 1883c1f859d4Smrg ctx->Array.LockCount = count; 1884c1f859d4Smrg 18857117f1b4Smrg ctx->NewState |= _NEW_ARRAY; 18867117f1b4Smrg} 18877117f1b4Smrg 18887117f1b4Smrg 18897117f1b4Smrgvoid GLAPIENTRY 18907117f1b4Smrg_mesa_UnlockArraysEXT( void ) 18917117f1b4Smrg{ 18927117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 1893af69d88dSmrg 18947117f1b4Smrg if (MESA_VERBOSE & VERBOSE_API) 18957117f1b4Smrg _mesa_debug(ctx, "glUnlockArrays\n"); 18967117f1b4Smrg 1897c1f859d4Smrg if (ctx->Array.LockCount == 0) { 1898c1f859d4Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 1899c1f859d4Smrg return; 1900c1f859d4Smrg } 1901c1f859d4Smrg 19027117f1b4Smrg ctx->Array.LockFirst = 0; 19037117f1b4Smrg ctx->Array.LockCount = 0; 19047117f1b4Smrg ctx->NewState |= _NEW_ARRAY; 19057117f1b4Smrg} 19067117f1b4Smrg 19077117f1b4Smrg 190801e04c3fSmrgstatic void 190901e04c3fSmrgprimitive_restart_index(struct gl_context *ctx, GLuint index) 19107117f1b4Smrg{ 191101e04c3fSmrg ctx->Array.RestartIndex = index; 19127117f1b4Smrg} 19137117f1b4Smrg 19147117f1b4Smrg 191501e04c3fSmrg/** 191601e04c3fSmrg * GL_NV_primitive_restart and GL 3.1 191701e04c3fSmrg */ 19187117f1b4Smrgvoid GLAPIENTRY 191901e04c3fSmrg_mesa_PrimitiveRestartIndex_no_error(GLuint index) 19207117f1b4Smrg{ 19217117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 192201e04c3fSmrg primitive_restart_index(ctx, index); 19237117f1b4Smrg} 19247117f1b4Smrg 19257117f1b4Smrg 19267117f1b4Smrgvoid GLAPIENTRY 192701e04c3fSmrg_mesa_PrimitiveRestartIndex(GLuint index) 19287117f1b4Smrg{ 19297117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 19307117f1b4Smrg 193101e04c3fSmrg if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) { 193201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()"); 193301e04c3fSmrg return; 19347117f1b4Smrg } 193501e04c3fSmrg 193601e04c3fSmrg primitive_restart_index(ctx, index); 19377117f1b4Smrg} 19387117f1b4Smrg 19397117f1b4Smrg 19403464ebd5Sriastradhvoid GLAPIENTRY 194101e04c3fSmrg_mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor) 19423464ebd5Sriastradh{ 19433464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 19443464ebd5Sriastradh 194501e04c3fSmrg const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); 194601e04c3fSmrg struct gl_vertex_array_object * const vao = ctx->Array.VAO; 19473464ebd5Sriastradh 194801e04c3fSmrg assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); 194901e04c3fSmrg 195001e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 195101e04c3fSmrg * 195201e04c3fSmrg * "The command 195301e04c3fSmrg * 195401e04c3fSmrg * void VertexAttribDivisor(uint index, uint divisor); 195501e04c3fSmrg * 195601e04c3fSmrg * is equivalent to (assuming no errors are generated): 195701e04c3fSmrg * 195801e04c3fSmrg * VertexAttribBinding(index, index); 195901e04c3fSmrg * VertexBindingDivisor(index, divisor);" 196001e04c3fSmrg */ 196101e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); 196201e04c3fSmrg vertex_binding_divisor(ctx, vao, genericIndex, divisor); 19633464ebd5Sriastradh} 19643464ebd5Sriastradh 19653464ebd5Sriastradh 19663464ebd5Sriastradh/** 19673464ebd5Sriastradh * See GL_ARB_instanced_arrays. 19683464ebd5Sriastradh * Note that the instance divisor only applies to generic arrays, not 19693464ebd5Sriastradh * the legacy vertex arrays. 19703464ebd5Sriastradh */ 19713464ebd5Sriastradhvoid GLAPIENTRY 19723464ebd5Sriastradh_mesa_VertexAttribDivisor(GLuint index, GLuint divisor) 19733464ebd5Sriastradh{ 19743464ebd5Sriastradh GET_CURRENT_CONTEXT(ctx); 1975af69d88dSmrg 197601e04c3fSmrg const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); 197701e04c3fSmrg struct gl_vertex_array_object * const vao = ctx->Array.VAO; 19783464ebd5Sriastradh 19793464ebd5Sriastradh if (!ctx->Extensions.ARB_instanced_arrays) { 19803464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()"); 19813464ebd5Sriastradh return; 19823464ebd5Sriastradh } 19833464ebd5Sriastradh 1984af69d88dSmrg if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 198501e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 198601e04c3fSmrg "glVertexAttribDivisor(index = %u)", index); 19873464ebd5Sriastradh return; 19883464ebd5Sriastradh } 19893464ebd5Sriastradh 199001e04c3fSmrg assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); 1991af69d88dSmrg 1992af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 1993af69d88dSmrg * 1994af69d88dSmrg * "The command 1995af69d88dSmrg * 1996af69d88dSmrg * void VertexAttribDivisor(uint index, uint divisor); 1997af69d88dSmrg * 1998af69d88dSmrg * is equivalent to (assuming no errors are generated): 1999af69d88dSmrg * 2000af69d88dSmrg * VertexAttribBinding(index, index); 2001af69d88dSmrg * VertexBindingDivisor(index, divisor);" 2002af69d88dSmrg */ 200301e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); 200401e04c3fSmrg vertex_binding_divisor(ctx, vao, genericIndex, divisor); 2005af69d88dSmrg} 2006af69d88dSmrg 2007af69d88dSmrg 200801e04c3fSmrgstatic ALWAYS_INLINE void 200901e04c3fSmrgvertex_array_vertex_buffer(struct gl_context *ctx, 201001e04c3fSmrg struct gl_vertex_array_object *vao, 201101e04c3fSmrg GLuint bindingIndex, GLuint buffer, GLintptr offset, 201201e04c3fSmrg GLsizei stride, bool no_error, const char *func) 2013af69d88dSmrg{ 2014af69d88dSmrg struct gl_buffer_object *vbo; 201501e04c3fSmrg if (buffer == 201601e04c3fSmrg vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) { 201701e04c3fSmrg vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj; 201801e04c3fSmrg } else if (buffer != 0) { 201901e04c3fSmrg vbo = _mesa_lookup_bufferobj(ctx, buffer); 2020af69d88dSmrg 202101e04c3fSmrg if (!no_error && !vbo && _mesa_is_gles31(ctx)) { 202201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func); 202301e04c3fSmrg return; 202401e04c3fSmrg } 202501e04c3fSmrg /* From the GL_ARB_vertex_attrib_array spec: 202601e04c3fSmrg * 202701e04c3fSmrg * "[Core profile only:] 202801e04c3fSmrg * An INVALID_OPERATION error is generated if buffer is not zero or a 202901e04c3fSmrg * name returned from a previous call to GenBuffers, or if such a name 203001e04c3fSmrg * has since been deleted with DeleteBuffers. 203101e04c3fSmrg * 203201e04c3fSmrg * Otherwise, we fall back to the same compat profile behavior as other 203301e04c3fSmrg * object references (automatically gen it). 203401e04c3fSmrg */ 203501e04c3fSmrg if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func)) 203601e04c3fSmrg return; 203701e04c3fSmrg } else { 203801e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 203901e04c3fSmrg * 204001e04c3fSmrg * "If <buffer> is zero, any buffer object attached to this 204101e04c3fSmrg * bindpoint is detached." 204201e04c3fSmrg */ 204301e04c3fSmrg vbo = ctx->Shared->NullBufferObj; 2044af69d88dSmrg } 2045af69d88dSmrg 204601e04c3fSmrg _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), 204701e04c3fSmrg vbo, offset, stride); 204801e04c3fSmrg} 204901e04c3fSmrg 205001e04c3fSmrg 205101e04c3fSmrg/** 205201e04c3fSmrg * GL_ARB_vertex_attrib_binding 205301e04c3fSmrg */ 205401e04c3fSmrgstatic void 205501e04c3fSmrgvertex_array_vertex_buffer_err(struct gl_context *ctx, 205601e04c3fSmrg struct gl_vertex_array_object *vao, 205701e04c3fSmrg GLuint bindingIndex, GLuint buffer, 205801e04c3fSmrg GLintptr offset, GLsizei stride, 205901e04c3fSmrg const char *func) 206001e04c3fSmrg{ 206101e04c3fSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 206201e04c3fSmrg 2063af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2064af69d88dSmrg * 2065af69d88dSmrg * "An INVALID_VALUE error is generated if <bindingindex> is greater than 2066af69d88dSmrg * the value of MAX_VERTEX_ATTRIB_BINDINGS." 2067af69d88dSmrg */ 2068af69d88dSmrg if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 2069af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 207001e04c3fSmrg "%s(bindingindex=%u > " 2071af69d88dSmrg "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 207201e04c3fSmrg func, bindingIndex); 2073af69d88dSmrg return; 2074af69d88dSmrg } 2075af69d88dSmrg 2076af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2077af69d88dSmrg * 2078af69d88dSmrg * "The error INVALID_VALUE is generated if <stride> or <offset> 2079af69d88dSmrg * are negative." 2080af69d88dSmrg */ 2081af69d88dSmrg if (offset < 0) { 2082af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 208301e04c3fSmrg "%s(offset=%" PRId64 " < 0)", 208401e04c3fSmrg func, (int64_t) offset); 2085af69d88dSmrg return; 2086af69d88dSmrg } 2087af69d88dSmrg 2088af69d88dSmrg if (stride < 0) { 2089af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 209001e04c3fSmrg "%s(stride=%d < 0)", func, stride); 2091af69d88dSmrg return; 2092af69d88dSmrg } 2093af69d88dSmrg 209401e04c3fSmrg if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) && 209501e04c3fSmrg stride > ctx->Const.MaxVertexAttribStride) { 209601e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " 209701e04c3fSmrg "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); 209801e04c3fSmrg return; 2099af69d88dSmrg } 2100af69d88dSmrg 210101e04c3fSmrg vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset, 210201e04c3fSmrg stride, false, func); 2103af69d88dSmrg} 2104af69d88dSmrg 2105af69d88dSmrg 2106af69d88dSmrgvoid GLAPIENTRY 210701e04c3fSmrg_mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer, 210801e04c3fSmrg GLintptr offset, GLsizei stride) 2109af69d88dSmrg{ 2110af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 211101e04c3fSmrg vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex, 211201e04c3fSmrg buffer, offset, stride, true, 211301e04c3fSmrg "glBindVertexBuffer"); 211401e04c3fSmrg} 2115af69d88dSmrg 211601e04c3fSmrg 211701e04c3fSmrgvoid GLAPIENTRY 211801e04c3fSmrg_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, 211901e04c3fSmrg GLsizei stride) 212001e04c3fSmrg{ 212101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 2122af69d88dSmrg 2123af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2124af69d88dSmrg * 212501e04c3fSmrg * "An INVALID_OPERATION error is generated if no vertex array object 212601e04c3fSmrg * is bound." 2127af69d88dSmrg */ 212801e04c3fSmrg if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 2129af69d88dSmrg ctx->Array.VAO == ctx->Array.DefaultVAO) { 2130af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 213101e04c3fSmrg "glBindVertexBuffer(No array object bound)"); 2132af69d88dSmrg return; 2133af69d88dSmrg } 2134af69d88dSmrg 213501e04c3fSmrg vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex, 213601e04c3fSmrg buffer, offset, stride, 213701e04c3fSmrg "glBindVertexBuffer"); 213801e04c3fSmrg} 213901e04c3fSmrg 214001e04c3fSmrg 214101e04c3fSmrgvoid GLAPIENTRY 214201e04c3fSmrg_mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex, 214301e04c3fSmrg GLuint buffer, GLintptr offset, 214401e04c3fSmrg GLsizei stride) 214501e04c3fSmrg{ 214601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 214701e04c3fSmrg 214801e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 214901e04c3fSmrg vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset, 215001e04c3fSmrg stride, true, "glVertexArrayVertexBuffer"); 215101e04c3fSmrg} 215201e04c3fSmrg 215301e04c3fSmrg 215401e04c3fSmrgvoid GLAPIENTRY 215501e04c3fSmrg_mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer, 215601e04c3fSmrg GLintptr offset, GLsizei stride) 215701e04c3fSmrg{ 215801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 215901e04c3fSmrg struct gl_vertex_array_object *vao; 216001e04c3fSmrg 216101e04c3fSmrg /* The ARB_direct_state_access specification says: 2162af69d88dSmrg * 216301e04c3fSmrg * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer 216401e04c3fSmrg * if <vaobj> is not [compatibility profile: zero or] the name of an 216501e04c3fSmrg * existing vertex array object." 2166af69d88dSmrg */ 216701e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer"); 216801e04c3fSmrg if (!vao) 2169af69d88dSmrg return; 217001e04c3fSmrg 217101e04c3fSmrg vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset, 217201e04c3fSmrg stride, "glVertexArrayVertexBuffer"); 217301e04c3fSmrg} 217401e04c3fSmrg 217501e04c3fSmrg 217601e04c3fSmrgstatic ALWAYS_INLINE void 217701e04c3fSmrgvertex_array_vertex_buffers(struct gl_context *ctx, 217801e04c3fSmrg struct gl_vertex_array_object *vao, 217901e04c3fSmrg GLuint first, GLsizei count, const GLuint *buffers, 218001e04c3fSmrg const GLintptr *offsets, const GLsizei *strides, 218101e04c3fSmrg bool no_error, const char *func) 218201e04c3fSmrg{ 218301e04c3fSmrg GLint i; 2184af69d88dSmrg 2185af69d88dSmrg if (!buffers) { 2186af69d88dSmrg /** 2187af69d88dSmrg * The ARB_multi_bind spec says: 2188af69d88dSmrg * 2189af69d88dSmrg * "If <buffers> is NULL, each affected vertex buffer binding point 2190af69d88dSmrg * from <first> through <first>+<count>-1 will be reset to have no 2191af69d88dSmrg * bound buffer object. In this case, the offsets and strides 2192af69d88dSmrg * associated with the binding points are set to default values, 2193af69d88dSmrg * ignoring <offsets> and <strides>." 2194af69d88dSmrg */ 2195af69d88dSmrg struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj; 2196af69d88dSmrg 2197af69d88dSmrg for (i = 0; i < count; i++) 219801e04c3fSmrg _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), 219901e04c3fSmrg vbo, 0, 16); 2200af69d88dSmrg 2201af69d88dSmrg return; 2202af69d88dSmrg } 2203af69d88dSmrg 2204af69d88dSmrg /* Note that the error semantics for multi-bind commands differ from 2205af69d88dSmrg * those of other GL commands. 2206af69d88dSmrg * 2207af69d88dSmrg * The Issues section in the ARB_multi_bind spec says: 2208af69d88dSmrg * 2209af69d88dSmrg * "(11) Typically, OpenGL specifies that if an error is generated by 2210af69d88dSmrg * a command, that command has no effect. This is somewhat 2211af69d88dSmrg * unfortunate for multi-bind commands, because it would require 2212af69d88dSmrg * a first pass to scan the entire list of bound objects for 2213af69d88dSmrg * errors and then a second pass to actually perform the 2214af69d88dSmrg * bindings. Should we have different error semantics? 2215af69d88dSmrg * 2216af69d88dSmrg * RESOLVED: Yes. In this specification, when the parameters for 2217af69d88dSmrg * one of the <count> binding points are invalid, that binding 2218af69d88dSmrg * point is not updated and an error will be generated. However, 2219af69d88dSmrg * other binding points in the same command will be updated if 2220af69d88dSmrg * their parameters are valid and no other error occurs." 2221af69d88dSmrg */ 2222af69d88dSmrg 222301e04c3fSmrg _mesa_HashLockMutex(ctx->Shared->BufferObjects); 2224af69d88dSmrg 2225af69d88dSmrg for (i = 0; i < count; i++) { 2226af69d88dSmrg struct gl_buffer_object *vbo; 2227af69d88dSmrg 222801e04c3fSmrg if (!no_error) { 222901e04c3fSmrg /* The ARB_multi_bind spec says: 223001e04c3fSmrg * 223101e04c3fSmrg * "An INVALID_VALUE error is generated if any value in 223201e04c3fSmrg * <offsets> or <strides> is negative (per binding)." 223301e04c3fSmrg */ 223401e04c3fSmrg if (offsets[i] < 0) { 223501e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 223601e04c3fSmrg "%s(offsets[%u]=%" PRId64 " < 0)", 223701e04c3fSmrg func, i, (int64_t) offsets[i]); 223801e04c3fSmrg continue; 223901e04c3fSmrg } 2240af69d88dSmrg 224101e04c3fSmrg if (strides[i] < 0) { 224201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 224301e04c3fSmrg "%s(strides[%u]=%d < 0)", 224401e04c3fSmrg func, i, strides[i]); 224501e04c3fSmrg continue; 224601e04c3fSmrg } 224701e04c3fSmrg 224801e04c3fSmrg if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && 224901e04c3fSmrg strides[i] > ctx->Const.MaxVertexAttribStride) { 225001e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 225101e04c3fSmrg "%s(strides[%u]=%d > " 225201e04c3fSmrg "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]); 225301e04c3fSmrg continue; 225401e04c3fSmrg } 2255af69d88dSmrg } 2256af69d88dSmrg 2257af69d88dSmrg if (buffers[i]) { 2258af69d88dSmrg struct gl_vertex_buffer_binding *binding = 225901e04c3fSmrg &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)]; 2260af69d88dSmrg 2261af69d88dSmrg if (buffers[i] == binding->BufferObj->Name) 2262af69d88dSmrg vbo = binding->BufferObj; 2263af69d88dSmrg else 226401e04c3fSmrg vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func); 2265af69d88dSmrg 2266af69d88dSmrg if (!vbo) 2267af69d88dSmrg continue; 2268af69d88dSmrg } else { 2269af69d88dSmrg vbo = ctx->Shared->NullBufferObj; 2270af69d88dSmrg } 2271af69d88dSmrg 227201e04c3fSmrg _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), 227301e04c3fSmrg vbo, offsets[i], strides[i]); 2274af69d88dSmrg } 2275af69d88dSmrg 227601e04c3fSmrg _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); 2277af69d88dSmrg} 2278af69d88dSmrg 2279af69d88dSmrg 228001e04c3fSmrgstatic void 228101e04c3fSmrgvertex_array_vertex_buffers_err(struct gl_context *ctx, 228201e04c3fSmrg struct gl_vertex_array_object *vao, 228301e04c3fSmrg GLuint first, GLsizei count, 228401e04c3fSmrg const GLuint *buffers, const GLintptr *offsets, 228501e04c3fSmrg const GLsizei *strides, const char *func) 2286af69d88dSmrg{ 2287af69d88dSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 2288af69d88dSmrg 228901e04c3fSmrg /* The ARB_multi_bind spec says: 2290af69d88dSmrg * 229101e04c3fSmrg * "An INVALID_OPERATION error is generated if <first> + <count> 229201e04c3fSmrg * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS." 2293af69d88dSmrg */ 229401e04c3fSmrg if (first + count > ctx->Const.MaxVertexAttribBindings) { 2295af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 229601e04c3fSmrg "%s(first=%u + count=%d > the value of " 229701e04c3fSmrg "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)", 229801e04c3fSmrg func, first, count, ctx->Const.MaxVertexAttribBindings); 2299af69d88dSmrg return; 2300af69d88dSmrg } 2301af69d88dSmrg 230201e04c3fSmrg vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets, 230301e04c3fSmrg strides, false, func); 230401e04c3fSmrg} 230501e04c3fSmrg 2306af69d88dSmrg 230701e04c3fSmrgvoid GLAPIENTRY 230801e04c3fSmrg_mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count, 230901e04c3fSmrg const GLuint *buffers, const GLintptr *offsets, 231001e04c3fSmrg const GLsizei *strides) 231101e04c3fSmrg{ 231201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 2313af69d88dSmrg 231401e04c3fSmrg vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count, 231501e04c3fSmrg buffers, offsets, strides, true, 231601e04c3fSmrg "glBindVertexBuffers"); 2317af69d88dSmrg} 2318af69d88dSmrg 2319af69d88dSmrg 2320af69d88dSmrgvoid GLAPIENTRY 232101e04c3fSmrg_mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, 232201e04c3fSmrg const GLintptr *offsets, const GLsizei *strides) 2323af69d88dSmrg{ 2324af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 2325af69d88dSmrg 2326af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2327af69d88dSmrg * 232801e04c3fSmrg * "An INVALID_OPERATION error is generated if no 232901e04c3fSmrg * vertex array object is bound." 2330af69d88dSmrg */ 2331af69d88dSmrg if (ctx->API == API_OPENGL_CORE && 2332af69d88dSmrg ctx->Array.VAO == ctx->Array.DefaultVAO) { 2333af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 233401e04c3fSmrg "glBindVertexBuffers(No array object bound)"); 2335af69d88dSmrg return; 2336af69d88dSmrg } 2337af69d88dSmrg 233801e04c3fSmrg vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count, 233901e04c3fSmrg buffers, offsets, strides, 234001e04c3fSmrg "glBindVertexBuffers"); 234101e04c3fSmrg} 234201e04c3fSmrg 234301e04c3fSmrg 234401e04c3fSmrgvoid GLAPIENTRY 234501e04c3fSmrg_mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first, 234601e04c3fSmrg GLsizei count, const GLuint *buffers, 234701e04c3fSmrg const GLintptr *offsets, 234801e04c3fSmrg const GLsizei *strides) 234901e04c3fSmrg{ 235001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 235101e04c3fSmrg 235201e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 235301e04c3fSmrg vertex_array_vertex_buffers(ctx, vao, first, count, 235401e04c3fSmrg buffers, offsets, strides, true, 235501e04c3fSmrg "glVertexArrayVertexBuffers"); 235601e04c3fSmrg} 235701e04c3fSmrg 235801e04c3fSmrg 235901e04c3fSmrgvoid GLAPIENTRY 236001e04c3fSmrg_mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, 236101e04c3fSmrg const GLuint *buffers, 236201e04c3fSmrg const GLintptr *offsets, const GLsizei *strides) 236301e04c3fSmrg{ 236401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 236501e04c3fSmrg struct gl_vertex_array_object *vao; 236601e04c3fSmrg 236701e04c3fSmrg /* The ARB_direct_state_access specification says: 2368af69d88dSmrg * 236901e04c3fSmrg * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer 237001e04c3fSmrg * if <vaobj> is not [compatibility profile: zero or] the name of an 237101e04c3fSmrg * existing vertex array object." 2372af69d88dSmrg */ 237301e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers"); 237401e04c3fSmrg if (!vao) 2375af69d88dSmrg return; 237601e04c3fSmrg 237701e04c3fSmrg vertex_array_vertex_buffers_err(ctx, vao, first, count, 237801e04c3fSmrg buffers, offsets, strides, 237901e04c3fSmrg "glVertexArrayVertexBuffers"); 238001e04c3fSmrg} 238101e04c3fSmrg 238201e04c3fSmrg 238301e04c3fSmrgstatic void 238401e04c3fSmrgvertex_attrib_format(GLuint attribIndex, GLint size, GLenum type, 238501e04c3fSmrg GLboolean normalized, GLboolean integer, 238601e04c3fSmrg GLboolean doubles, GLbitfield legalTypes, 238701e04c3fSmrg GLsizei sizeMax, GLuint relativeOffset, 238801e04c3fSmrg const char *func) 238901e04c3fSmrg{ 239001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 239101e04c3fSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 239201e04c3fSmrg 239301e04c3fSmrg GLenum format = get_array_format(ctx, sizeMax, &size); 239401e04c3fSmrg 239501e04c3fSmrg if (!_mesa_is_no_error_enabled(ctx)) { 239601e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 239701e04c3fSmrg * 239801e04c3fSmrg * "An INVALID_OPERATION error is generated under any of the 239901e04c3fSmrg * following conditions: 240001e04c3fSmrg * - if no vertex array object is currently bound (see section 240101e04c3fSmrg * 2.10); 240201e04c3fSmrg * - ..." 240301e04c3fSmrg * 240401e04c3fSmrg * This error condition only applies to VertexAttribFormat and 240501e04c3fSmrg * VertexAttribIFormat in the extension spec, but we assume that this 240601e04c3fSmrg * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies 240701e04c3fSmrg * to all three functions. 240801e04c3fSmrg */ 240901e04c3fSmrg if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 241001e04c3fSmrg ctx->Array.VAO == ctx->Array.DefaultVAO) { 241101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 241201e04c3fSmrg "%s(No array object bound)", func); 241301e04c3fSmrg return; 241401e04c3fSmrg } 241501e04c3fSmrg 241601e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 241701e04c3fSmrg * 241801e04c3fSmrg * "The error INVALID_VALUE is generated if index is greater than or 241901e04c3fSmrg * equal to the value of MAX_VERTEX_ATTRIBS." 242001e04c3fSmrg */ 242101e04c3fSmrg if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 242201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 242301e04c3fSmrg "%s(attribindex=%u > " 242401e04c3fSmrg "GL_MAX_VERTEX_ATTRIBS)", 242501e04c3fSmrg func, attribIndex); 242601e04c3fSmrg return; 242701e04c3fSmrg } 242801e04c3fSmrg 242901e04c3fSmrg if (!validate_array_format(ctx, func, ctx->Array.VAO, 243001e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), 243101e04c3fSmrg legalTypes, 1, sizeMax, size, type, 243201e04c3fSmrg normalized, integer, doubles, relativeOffset, 243301e04c3fSmrg format)) { 243401e04c3fSmrg return; 243501e04c3fSmrg } 2436af69d88dSmrg } 2437af69d88dSmrg 243801e04c3fSmrg _mesa_update_array_format(ctx, ctx->Array.VAO, 243901e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), size, type, 244001e04c3fSmrg format, normalized, integer, doubles, 244101e04c3fSmrg relativeOffset); 244201e04c3fSmrg} 244301e04c3fSmrg 244401e04c3fSmrg 244501e04c3fSmrgvoid GLAPIENTRY 244601e04c3fSmrg_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, 244701e04c3fSmrg GLboolean normalized, GLuint relativeOffset) 244801e04c3fSmrg{ 244901e04c3fSmrg vertex_attrib_format(attribIndex, size, type, normalized, 245001e04c3fSmrg GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, 245101e04c3fSmrg BGRA_OR_4, relativeOffset, 245201e04c3fSmrg "glVertexAttribFormat"); 245301e04c3fSmrg} 245401e04c3fSmrg 2455af69d88dSmrg 245601e04c3fSmrgvoid GLAPIENTRY 245701e04c3fSmrg_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, 245801e04c3fSmrg GLuint relativeOffset) 245901e04c3fSmrg{ 246001e04c3fSmrg vertex_attrib_format(attribIndex, size, type, GL_FALSE, 246101e04c3fSmrg GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4, 246201e04c3fSmrg relativeOffset, "glVertexAttribIFormat"); 2463af69d88dSmrg} 2464af69d88dSmrg 2465af69d88dSmrg 2466af69d88dSmrgvoid GLAPIENTRY 2467af69d88dSmrg_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type, 2468af69d88dSmrg GLuint relativeOffset) 2469af69d88dSmrg{ 247001e04c3fSmrg vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE, 247101e04c3fSmrg GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4, 247201e04c3fSmrg relativeOffset, "glVertexAttribLFormat"); 247301e04c3fSmrg} 247401e04c3fSmrg 2475af69d88dSmrg 247601e04c3fSmrgstatic void 247701e04c3fSmrgvertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size, 247801e04c3fSmrg GLenum type, GLboolean normalized, 247901e04c3fSmrg GLboolean integer, GLboolean doubles, 248001e04c3fSmrg GLbitfield legalTypes, GLsizei sizeMax, 248101e04c3fSmrg GLuint relativeOffset, const char *func) 248201e04c3fSmrg{ 2483af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 248401e04c3fSmrg struct gl_vertex_array_object *vao; 248501e04c3fSmrg 2486af69d88dSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 2487af69d88dSmrg 248801e04c3fSmrg GLenum format = get_array_format(ctx, sizeMax, &size); 248901e04c3fSmrg 249001e04c3fSmrg if (_mesa_is_no_error_enabled(ctx)) { 249101e04c3fSmrg vao = _mesa_lookup_vao(ctx, vaobj); 249201e04c3fSmrg if (!vao) 249301e04c3fSmrg return; 249401e04c3fSmrg } else { 249501e04c3fSmrg /* The ARB_direct_state_access spec says: 249601e04c3fSmrg * 249701e04c3fSmrg * "An INVALID_OPERATION error is generated by 249801e04c3fSmrg * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile: 249901e04c3fSmrg * zero or] the name of an existing vertex array object." 250001e04c3fSmrg */ 250101e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, func); 250201e04c3fSmrg if (!vao) 250301e04c3fSmrg return; 250401e04c3fSmrg 250501e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 250601e04c3fSmrg * 250701e04c3fSmrg * "The error INVALID_VALUE is generated if index is greater than or 250801e04c3fSmrg * equal to the value of MAX_VERTEX_ATTRIBS." 250901e04c3fSmrg */ 251001e04c3fSmrg if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 251101e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 251201e04c3fSmrg "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)", 251301e04c3fSmrg func, attribIndex); 251401e04c3fSmrg return; 251501e04c3fSmrg } 251601e04c3fSmrg 251701e04c3fSmrg if (!validate_array_format(ctx, func, vao, 251801e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), 251901e04c3fSmrg legalTypes, 1, sizeMax, size, type, 252001e04c3fSmrg normalized, integer, doubles, relativeOffset, 252101e04c3fSmrg format)) { 252201e04c3fSmrg return; 252301e04c3fSmrg } 2524af69d88dSmrg } 2525af69d88dSmrg 252601e04c3fSmrg _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size, 252701e04c3fSmrg type, format, normalized, integer, doubles, 252801e04c3fSmrg relativeOffset); 252901e04c3fSmrg} 253001e04c3fSmrg 253101e04c3fSmrg 253201e04c3fSmrgvoid GLAPIENTRY 253301e04c3fSmrg_mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size, 253401e04c3fSmrg GLenum type, GLboolean normalized, 253501e04c3fSmrg GLuint relativeOffset) 253601e04c3fSmrg{ 253701e04c3fSmrg vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized, 253801e04c3fSmrg GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, 253901e04c3fSmrg BGRA_OR_4, relativeOffset, 254001e04c3fSmrg "glVertexArrayAttribFormat"); 254101e04c3fSmrg} 254201e04c3fSmrg 254301e04c3fSmrg 254401e04c3fSmrgvoid GLAPIENTRY 254501e04c3fSmrg_mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex, 254601e04c3fSmrg GLint size, GLenum type, 254701e04c3fSmrg GLuint relativeOffset) 254801e04c3fSmrg{ 254901e04c3fSmrg vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE, 255001e04c3fSmrg GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 255101e04c3fSmrg 4, relativeOffset, 255201e04c3fSmrg "glVertexArrayAttribIFormat"); 255301e04c3fSmrg} 255401e04c3fSmrg 255501e04c3fSmrg 255601e04c3fSmrgvoid GLAPIENTRY 255701e04c3fSmrg_mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex, 255801e04c3fSmrg GLint size, GLenum type, 255901e04c3fSmrg GLuint relativeOffset) 256001e04c3fSmrg{ 256101e04c3fSmrg vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE, 256201e04c3fSmrg GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 256301e04c3fSmrg 4, relativeOffset, 256401e04c3fSmrg "glVertexArrayAttribLFormat"); 256501e04c3fSmrg} 256601e04c3fSmrg 256701e04c3fSmrg 256801e04c3fSmrgstatic void 256901e04c3fSmrgvertex_array_attrib_binding(struct gl_context *ctx, 257001e04c3fSmrg struct gl_vertex_array_object *vao, 257101e04c3fSmrg GLuint attribIndex, GLuint bindingIndex, 257201e04c3fSmrg const char *func) 257301e04c3fSmrg{ 257401e04c3fSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 257501e04c3fSmrg 2576af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2577af69d88dSmrg * 257801e04c3fSmrg * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and 257901e04c3fSmrg * <bindingindex> must be less than the value of 258001e04c3fSmrg * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE 258101e04c3fSmrg * is generated." 2582af69d88dSmrg */ 2583af69d88dSmrg if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2584af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 258501e04c3fSmrg "%s(attribindex=%u >= " 2586af69d88dSmrg "GL_MAX_VERTEX_ATTRIBS)", 258701e04c3fSmrg func, attribIndex); 258801e04c3fSmrg return; 258901e04c3fSmrg } 259001e04c3fSmrg 259101e04c3fSmrg if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 259201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 259301e04c3fSmrg "%s(bindingindex=%u >= " 259401e04c3fSmrg "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 259501e04c3fSmrg func, bindingIndex); 2596af69d88dSmrg return; 2597af69d88dSmrg } 2598af69d88dSmrg 259901e04c3fSmrg assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib)); 260001e04c3fSmrg 260101e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vao, 260201e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), 260301e04c3fSmrg VERT_ATTRIB_GENERIC(bindingIndex)); 260401e04c3fSmrg} 260501e04c3fSmrg 2606af69d88dSmrg 260701e04c3fSmrgvoid GLAPIENTRY 260801e04c3fSmrg_mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex) 260901e04c3fSmrg{ 261001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 261101e04c3fSmrg _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO, 261201e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), 261301e04c3fSmrg VERT_ATTRIB_GENERIC(bindingIndex)); 2614af69d88dSmrg} 2615af69d88dSmrg 2616af69d88dSmrg 2617af69d88dSmrgvoid GLAPIENTRY 2618af69d88dSmrg_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) 2619af69d88dSmrg{ 2620af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 2621af69d88dSmrg 2622af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2623af69d88dSmrg * 2624af69d88dSmrg * "An INVALID_OPERATION error is generated if no vertex array object 2625af69d88dSmrg * is bound." 2626af69d88dSmrg */ 262701e04c3fSmrg if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 2628af69d88dSmrg ctx->Array.VAO == ctx->Array.DefaultVAO) { 2629af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 2630af69d88dSmrg "glVertexAttribBinding(No array object bound)"); 2631af69d88dSmrg return; 2632af69d88dSmrg } 2633af69d88dSmrg 263401e04c3fSmrg vertex_array_attrib_binding(ctx, ctx->Array.VAO, 263501e04c3fSmrg attribIndex, bindingIndex, 263601e04c3fSmrg "glVertexAttribBinding"); 263701e04c3fSmrg} 263801e04c3fSmrg 263901e04c3fSmrg 264001e04c3fSmrgvoid GLAPIENTRY 264101e04c3fSmrg_mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex, 264201e04c3fSmrg GLuint bindingIndex) 264301e04c3fSmrg{ 264401e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 264501e04c3fSmrg 264601e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 264701e04c3fSmrg _mesa_vertex_attrib_binding(ctx, vao, 264801e04c3fSmrg VERT_ATTRIB_GENERIC(attribIndex), 264901e04c3fSmrg VERT_ATTRIB_GENERIC(bindingIndex)); 265001e04c3fSmrg} 265101e04c3fSmrg 265201e04c3fSmrg 265301e04c3fSmrgvoid GLAPIENTRY 265401e04c3fSmrg_mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex) 265501e04c3fSmrg{ 265601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 265701e04c3fSmrg struct gl_vertex_array_object *vao; 265801e04c3fSmrg 265901e04c3fSmrg /* The ARB_direct_state_access specification says: 2660af69d88dSmrg * 266101e04c3fSmrg * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding 266201e04c3fSmrg * if <vaobj> is not [compatibility profile: zero or] the name of an 266301e04c3fSmrg * existing vertex array object." 2664af69d88dSmrg */ 266501e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding"); 266601e04c3fSmrg if (!vao) 266701e04c3fSmrg return; 266801e04c3fSmrg 266901e04c3fSmrg vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex, 267001e04c3fSmrg "glVertexArrayAttribBinding"); 267101e04c3fSmrg} 267201e04c3fSmrg 267301e04c3fSmrg 267401e04c3fSmrgstatic void 267501e04c3fSmrgvertex_array_binding_divisor(struct gl_context *ctx, 267601e04c3fSmrg struct gl_vertex_array_object *vao, 267701e04c3fSmrg GLuint bindingIndex, GLuint divisor, 267801e04c3fSmrg const char *func) 267901e04c3fSmrg{ 268001e04c3fSmrg ASSERT_OUTSIDE_BEGIN_END(ctx); 268101e04c3fSmrg 268201e04c3fSmrg if (!ctx->Extensions.ARB_instanced_arrays) { 268301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func); 2684af69d88dSmrg return; 2685af69d88dSmrg } 2686af69d88dSmrg 268701e04c3fSmrg /* The ARB_vertex_attrib_binding spec says: 268801e04c3fSmrg * 268901e04c3fSmrg * "An INVALID_VALUE error is generated if <bindingindex> is greater 269001e04c3fSmrg * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS." 269101e04c3fSmrg */ 2692af69d88dSmrg if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 2693af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 269401e04c3fSmrg "%s(bindingindex=%u > " 2695af69d88dSmrg "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 269601e04c3fSmrg func, bindingIndex); 2697af69d88dSmrg return; 2698af69d88dSmrg } 2699af69d88dSmrg 270001e04c3fSmrg vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor); 270101e04c3fSmrg} 270201e04c3fSmrg 2703af69d88dSmrg 270401e04c3fSmrgvoid GLAPIENTRY 270501e04c3fSmrg_mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor) 270601e04c3fSmrg{ 270701e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 270801e04c3fSmrg vertex_binding_divisor(ctx, ctx->Array.VAO, 270901e04c3fSmrg VERT_ATTRIB_GENERIC(bindingIndex), divisor); 2710af69d88dSmrg} 2711af69d88dSmrg 2712af69d88dSmrg 2713af69d88dSmrgvoid GLAPIENTRY 2714af69d88dSmrg_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor) 2715af69d88dSmrg{ 2716af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 2717af69d88dSmrg 2718af69d88dSmrg /* The ARB_vertex_attrib_binding spec says: 2719af69d88dSmrg * 2720af69d88dSmrg * "An INVALID_OPERATION error is generated if no vertex array object 2721af69d88dSmrg * is bound." 2722af69d88dSmrg */ 272301e04c3fSmrg if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 2724af69d88dSmrg ctx->Array.VAO == ctx->Array.DefaultVAO) { 2725af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 2726af69d88dSmrg "glVertexBindingDivisor(No array object bound)"); 2727af69d88dSmrg return; 2728af69d88dSmrg } 2729af69d88dSmrg 273001e04c3fSmrg vertex_array_binding_divisor(ctx, ctx->Array.VAO, 273101e04c3fSmrg bindingIndex, divisor, 273201e04c3fSmrg "glVertexBindingDivisor"); 273301e04c3fSmrg} 273401e04c3fSmrg 273501e04c3fSmrg 273601e04c3fSmrgvoid GLAPIENTRY 273701e04c3fSmrg_mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex, 273801e04c3fSmrg GLuint divisor) 273901e04c3fSmrg{ 274001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 2741af69d88dSmrg 274201e04c3fSmrg struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 274301e04c3fSmrg vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor); 2744af69d88dSmrg} 2745af69d88dSmrg 27463464ebd5Sriastradh 274701e04c3fSmrgvoid GLAPIENTRY 274801e04c3fSmrg_mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, 274901e04c3fSmrg GLuint divisor) 275001e04c3fSmrg{ 275101e04c3fSmrg struct gl_vertex_array_object *vao; 275201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 275301e04c3fSmrg 275401e04c3fSmrg /* The ARB_direct_state_access specification says: 275501e04c3fSmrg * 275601e04c3fSmrg * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor 275701e04c3fSmrg * if <vaobj> is not [compatibility profile: zero or] the name of an 275801e04c3fSmrg * existing vertex array object." 275901e04c3fSmrg */ 276001e04c3fSmrg vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor"); 276101e04c3fSmrg if (!vao) 276201e04c3fSmrg return; 276301e04c3fSmrg 276401e04c3fSmrg vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor, 276501e04c3fSmrg "glVertexArrayBindingDivisor"); 27664a49301eSmrg} 27674a49301eSmrg 276801e04c3fSmrg 2769af69d88dSmrgvoid 2770af69d88dSmrg_mesa_copy_vertex_attrib_array(struct gl_context *ctx, 277101e04c3fSmrg struct gl_array_attributes *dst, 277201e04c3fSmrg const struct gl_array_attributes *src) 2773af69d88dSmrg{ 2774af69d88dSmrg dst->Size = src->Size; 2775af69d88dSmrg dst->Type = src->Type; 2776af69d88dSmrg dst->Format = src->Format; 277701e04c3fSmrg dst->BufferBindingIndex = src->BufferBindingIndex; 2778af69d88dSmrg dst->RelativeOffset = src->RelativeOffset; 2779af69d88dSmrg dst->Format = src->Format; 2780af69d88dSmrg dst->Integer = src->Integer; 278101e04c3fSmrg dst->Doubles = src->Doubles; 2782af69d88dSmrg dst->Normalized = src->Normalized; 2783af69d88dSmrg dst->Ptr = src->Ptr; 2784af69d88dSmrg dst->Enabled = src->Enabled; 2785af69d88dSmrg dst->_ElementSize = src->_ElementSize; 278601e04c3fSmrg dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex; 278701e04c3fSmrg dst->_EffRelativeOffset = src->_EffRelativeOffset; 2788af69d88dSmrg} 2789af69d88dSmrg 2790af69d88dSmrgvoid 2791af69d88dSmrg_mesa_copy_vertex_buffer_binding(struct gl_context *ctx, 2792af69d88dSmrg struct gl_vertex_buffer_binding *dst, 2793af69d88dSmrg const struct gl_vertex_buffer_binding *src) 2794af69d88dSmrg{ 2795af69d88dSmrg dst->Offset = src->Offset; 2796af69d88dSmrg dst->Stride = src->Stride; 2797af69d88dSmrg dst->InstanceDivisor = src->InstanceDivisor; 2798af69d88dSmrg dst->_BoundArrays = src->_BoundArrays; 279901e04c3fSmrg dst->_EffBoundArrays = src->_EffBoundArrays; 280001e04c3fSmrg dst->_EffOffset = src->_EffOffset; 28014a49301eSmrg 2802af69d88dSmrg _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 2803af69d88dSmrg} 28044a49301eSmrg 28054a49301eSmrg/** 28064a49301eSmrg * Print current vertex object/array info. For debug. 28074a49301eSmrg */ 28084a49301eSmrgvoid 28093464ebd5Sriastradh_mesa_print_arrays(struct gl_context *ctx) 28104a49301eSmrg{ 281101e04c3fSmrg const struct gl_vertex_array_object *vao = ctx->Array.VAO; 28124a49301eSmrg 281301e04c3fSmrg fprintf(stderr, "Array Object %u\n", vao->Name); 2814af69d88dSmrg 281501e04c3fSmrg gl_vert_attrib i; 281601e04c3fSmrg for (i = 0; i < VERT_ATTRIB_MAX; ++i) { 281701e04c3fSmrg const struct gl_array_attributes *array = &vao->VertexAttrib[i]; 281801e04c3fSmrg if (!array->Enabled) 281901e04c3fSmrg continue; 282001e04c3fSmrg 282101e04c3fSmrg const struct gl_vertex_buffer_binding *binding = 282201e04c3fSmrg &vao->BufferBinding[array->BufferBindingIndex]; 282301e04c3fSmrg const struct gl_buffer_object *bo = binding->BufferObj; 282401e04c3fSmrg 282501e04c3fSmrg fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, " 282601e04c3fSmrg "Stride=%d, Buffer=%u(Size %lu)\n", 282701e04c3fSmrg gl_vert_attrib_name((gl_vert_attrib)i), 282801e04c3fSmrg array->Ptr, _mesa_enum_to_string(array->Type), array->Size, 282901e04c3fSmrg array->_ElementSize, binding->Stride, bo->Name, 283001e04c3fSmrg (unsigned long) bo->Size); 283101e04c3fSmrg } 28324a49301eSmrg} 28334a49301eSmrg 28344a49301eSmrg 28357117f1b4Smrg/** 28367117f1b4Smrg * Initialize vertex array state for given context. 28377117f1b4Smrg */ 283801e04c3fSmrgvoid 28393464ebd5Sriastradh_mesa_init_varray(struct gl_context *ctx) 28407117f1b4Smrg{ 284101e04c3fSmrg ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0); 2842af69d88dSmrg _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO); 284301e04c3fSmrg ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u); 284401e04c3fSmrg _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO); 28457117f1b4Smrg ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 28464a49301eSmrg 28474a49301eSmrg ctx->Array.Objects = _mesa_NewHashTable(); 28484a49301eSmrg} 28494a49301eSmrg 28504a49301eSmrg 28514a49301eSmrg/** 28524a49301eSmrg * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). 28534a49301eSmrg */ 28544a49301eSmrgstatic void 28554a49301eSmrgdelete_arrayobj_cb(GLuint id, void *data, void *userData) 28564a49301eSmrg{ 2857af69d88dSmrg struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data; 28583464ebd5Sriastradh struct gl_context *ctx = (struct gl_context *) userData; 2859af69d88dSmrg _mesa_delete_vao(ctx, vao); 28604a49301eSmrg} 28614a49301eSmrg 28624a49301eSmrg 28634a49301eSmrg/** 28644a49301eSmrg * Free vertex array state for given context. 28654a49301eSmrg */ 286601e04c3fSmrgvoid 28673464ebd5Sriastradh_mesa_free_varray_data(struct gl_context *ctx) 28684a49301eSmrg{ 28694a49301eSmrg _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); 28704a49301eSmrg _mesa_DeleteHashTable(ctx->Array.Objects); 28717117f1b4Smrg} 2872