X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fvarray.c;h=540e8963c814129fbfb8876c132b30c832d0dc37;hb=bda361e0d47a670f318664abcdf0a065bef22883;hp=bcde65adc70107948b6a06f37ffdae56d290b15e;hpb=72e30991559017c16d48569e612dbc0970e3b9ca;p=mesa.git diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index bcde65adc70..540e8963c81 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -57,8 +57,10 @@ #define HALF_BIT 0x80 #define FLOAT_BIT 0x100 #define DOUBLE_BIT 0x200 -#define FIXED_BIT 0x400 - +#define FIXED_ES_BIT 0x400 +#define FIXED_GL_BIT 0x800 +#define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000 +#define INT_2_10_10_10_REV_BIT 0x2000 /** Convert GL datatype enum into a _BIT value seen above */ @@ -90,7 +92,11 @@ type_to_bit(const struct gl_context *ctx, GLenum type) case GL_DOUBLE: return DOUBLE_BIT; case GL_FIXED: - return FIXED_BIT; + return ctx->API == API_OPENGL ? FIXED_GL_BIT : FIXED_ES_BIT; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return UNSIGNED_INT_2_10_10_10_REV_BIT; + case GL_INT_2_10_10_10_REV: + return INT_2_10_10_10_REV_BIT; default: return 0; } @@ -102,8 +108,7 @@ type_to_bit(const struct gl_context *ctx, GLenum type) * functions. * * \param func name of calling function used for error reporting - * \param array the array to update - * \param dirtyBit which bit to set in ctx->Array.NewState for this array + * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value (may also be BGRA_OR_4) @@ -117,20 +122,27 @@ type_to_bit(const struct gl_context *ctx, GLenum type) static void update_array(struct gl_context *ctx, const char *func, - struct gl_client_array *array, - GLbitfield dirtyBit, GLbitfield legalTypesMask, + GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { + struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; GLenum format = GL_RGBA; if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) { /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */ - legalTypesMask &= ~FIXED_BIT; + legalTypesMask &= ~FIXED_ES_BIT; + } + if (!ctx->Extensions.ARB_ES2_compatibility) { + legalTypesMask &= ~FIXED_GL_BIT; + } + if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { + legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); } typeBit = type_to_bit(ctx, type); @@ -147,7 +159,17 @@ update_array(struct gl_context *ctx, if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && size == GL_BGRA) { - if (type != GL_UNSIGNED_BYTE) { + GLboolean bgra_error = GL_FALSE; + + if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { + if (type != GL_UNSIGNED_INT_2_10_10_10_REV && + type != GL_INT_2_10_10_10_REV && + type != GL_UNSIGNED_BYTE) + bgra_error = GL_TRUE; + } else if (type != GL_UNSIGNED_BYTE) + bgra_error = GL_TRUE; + + if (bgra_error) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); return; } @@ -159,6 +181,12 @@ update_array(struct gl_context *ctx, return; } + if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && + (type == GL_UNSIGNED_INT_2_10_10_10_REV || + type == GL_INT_2_10_10_10_REV) && size != 4) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); + } + ASSERT(size <= 4); if (stride < 0) { @@ -167,7 +195,7 @@ update_array(struct gl_context *ctx, } if (ctx->Array.ArrayObj->VBOonly && - ctx->Array.ArrayBufferObj->Name == 0) { + !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. * Generate GL_INVALID_OPERATION if that's not true. */ @@ -177,12 +205,14 @@ update_array(struct gl_context *ctx, elementSize = _mesa_sizeof_type(type) * size; + array = &ctx->Array.ArrayObj->VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Format = format; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; + array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; @@ -190,7 +220,7 @@ update_array(struct gl_context *ctx, ctx->Array.ArrayBufferObj); ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= dirtyBit; + ctx->Array.NewState |= VERT_BIT(attrib); } @@ -198,15 +228,16 @@ void GLAPIENTRY _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GLbitfield legalTypes = (SHORT_BIT | INT_BIT | FLOAT_BIT | - DOUBLE_BIT | HALF_BIT | FIXED_BIT); + DOUBLE_BIT | HALF_BIT | FIXED_ES_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->API == API_OPENGLES) legalTypes |= BYTE_BIT; - update_array(ctx, "glVertexPointer", - &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, + update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS, legalTypes, 2, 4, size, type, stride, GL_FALSE, GL_FALSE, ptr); } @@ -217,12 +248,13 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) { const GLbitfield legalTypes = (BYTE_BIT | SHORT_BIT | INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - FIXED_BIT); + FIXED_ES_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glNormalPointer", - &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, + update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, type, stride, GL_TRUE, GL_FALSE, ptr); } @@ -235,12 +267,13 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) SHORT_BIT | UNSIGNED_SHORT_BIT | INT_BIT | UNSIGNED_INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - FIXED_BIT); + FIXED_ES_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glColorPointer", - &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, + update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0, legalTypes, 3, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, ptr); } @@ -253,8 +286,7 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glFogCoordPointer", - &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, + update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG, legalTypes, 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, ptr); } @@ -268,8 +300,7 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glIndexPointer", - &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, + update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX, legalTypes, 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, ptr); } @@ -282,12 +313,13 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | SHORT_BIT | UNSIGNED_SHORT_BIT | INT_BIT | UNSIGNED_INT_BIT | - HALF_BIT | FLOAT_BIT | DOUBLE_BIT); + HALF_BIT | FLOAT_BIT | DOUBLE_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glSecondaryColorPointer", - &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1, + update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1, legalTypes, 3, BGRA_OR_4, size, type, stride, GL_TRUE, GL_FALSE, ptr); } @@ -299,7 +331,9 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, { GLbitfield legalTypes = (SHORT_BIT | INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - FIXED_BIT); + FIXED_ES_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -307,11 +341,7 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, if (ctx->API == API_OPENGLES) legalTypes |= BYTE_BIT; - ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord)); - - update_array(ctx, "glTexCoordPointer", - &ctx->Array.ArrayObj->TexCoord[unit], - _NEW_ARRAY_TEXCOORD(unit), + update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit), legalTypes, 1, 4, size, type, stride, GL_FALSE, GL_FALSE, ptr); @@ -327,8 +357,7 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - update_array(ctx, "glEdgeFlagPointer", - &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, + update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG, legalTypes, 1, 1, 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr); } @@ -337,7 +366,7 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) void GLAPIENTRY _mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) { - const GLbitfield legalTypes = (FLOAT_BIT | FIXED_BIT); + const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -347,8 +376,7 @@ _mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) return; } - update_array(ctx, "glPointSizePointer", - &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE, + update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE, legalTypes, 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, ptr); } @@ -381,9 +409,7 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, return; } - update_array(ctx, "glVertexAttribPointerNV", - &ctx->Array.ArrayObj->VertexAttrib[index], - _NEW_ARRAY_ATTRIB(index), + update_array(ctx, "glVertexAttribPointerNV", VERT_ATTRIB_GENERIC(index), legalTypes, 1, BGRA_OR_4, size, type, stride, normalized, GL_FALSE, ptr); } @@ -405,7 +431,9 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, SHORT_BIT | UNSIGNED_SHORT_BIT | INT_BIT | UNSIGNED_INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - FIXED_BIT); + FIXED_ES_BIT | FIXED_GL_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -414,9 +442,7 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, return; } - update_array(ctx, "glVertexAttribPointer", - &ctx->Array.ArrayObj->VertexAttrib[index], - _NEW_ARRAY_ATTRIB(index), + update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index), legalTypes, 1, BGRA_OR_4, size, type, stride, normalized, GL_FALSE, ptr); } @@ -446,9 +472,7 @@ _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, return; } - update_array(ctx, "glVertexAttribIPointer", - &ctx->Array.ArrayObj->VertexAttrib[index], - _NEW_ARRAY_ATTRIB(index), + update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index), legalTypes, 1, 4, size, type, stride, normalized, integer, ptr); } @@ -467,12 +491,12 @@ _mesa_EnableVertexAttribArrayARB(GLuint index) return; } - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); FLUSH_VERTICES(ctx, _NEW_ARRAY); - ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE; - ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index); - ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); + ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE; + ctx->Array.ArrayObj->_Enabled |= VERT_BIT_GENERIC(index); + ctx->Array.NewState |= VERT_BIT_GENERIC(index); } @@ -484,16 +508,16 @@ _mesa_DisableVertexAttribArrayARB(GLuint index) if (index >= ctx->Const.VertexProgram.MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, - "glEnableVertexAttribArrayARB(index)"); + "glDisableVertexAttribArrayARB(index)"); return; } - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); FLUSH_VERTICES(ctx, _NEW_ARRAY); - ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE; - ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index); - ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); + ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE; + ctx->Array.ArrayObj->_Enabled &= ~VERT_BIT_GENERIC(index); + ctx->Array.NewState |= VERT_BIT_GENERIC(index); } @@ -508,14 +532,14 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, { const struct gl_client_array *array; - if (index >= MAX_VERTEX_GENERIC_ATTRIBS) { + if (index >= ctx->Const.VertexProgram.MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); return 0; } - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); - array = &ctx->Array.ArrayObj->VertexAttrib[index]; + array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; switch (pname) { case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: @@ -534,14 +558,43 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, if (ctx->Extensions.EXT_gpu_shader4) { return array->Integer; } - /* fall-through */ + goto error; + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: + if (ctx->Extensions.ARB_instanced_arrays) { + return array->InstanceDivisor; + } + goto error; default: - _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); - return 0; + ; /* fall-through */ } + +error: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); + return 0; } +static const GLfloat * +get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) +{ + if (index == 0) { + if (ctx->API != API_OPENGLES2) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); + return NULL; + } + } + else if (index >= ctx->Const.VertexProgram.MaxAttribs) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); + return NULL; + } + + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); + + FLUSH_CURRENT(ctx, 0); + return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)]; +} + void GLAPIENTRY _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) { @@ -549,13 +602,8 @@ _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) ASSERT_OUTSIDE_BEGIN_END(ctx); if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribfv(index==0)"); - } - else { - const GLfloat *v = ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; - FLUSH_CURRENT(ctx, 0); + const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv"); + if (v != NULL) { COPY_4V(params, v); } } @@ -573,13 +621,8 @@ _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) ASSERT_OUTSIDE_BEGIN_END(ctx); if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribdv(index==0)"); - } - else { - const GLfloat *v = ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; - FLUSH_CURRENT(ctx, 0); + const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv"); + if (v != NULL) { params[0] = (GLdouble) v[0]; params[1] = (GLdouble) v[1]; params[2] = (GLdouble) v[2]; @@ -600,13 +643,8 @@ _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) ASSERT_OUTSIDE_BEGIN_END(ctx); if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribiv(index==0)"); - } - else { - const GLfloat *v = ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; - FLUSH_CURRENT(ctx, 0); + const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv"); + if (v != NULL) { /* XXX should floats in[0,1] be scaled to full int range? */ params[0] = (GLint) v[0]; params[1] = (GLint) v[1]; @@ -629,13 +667,9 @@ _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) ASSERT_OUTSIDE_BEGIN_END(ctx); if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribIiv(index==0)"); - } - else { - const GLfloat *v = ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; - FLUSH_CURRENT(ctx, 0); + const GLfloat *v = + get_current_attrib(ctx, index, "glGetVertexAttribIiv"); + if (v != NULL) { /* XXX we don't have true integer-valued vertex attribs yet */ params[0] = (GLint) v[0]; params[1] = (GLint) v[1]; @@ -658,13 +692,9 @@ _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) ASSERT_OUTSIDE_BEGIN_END(ctx); if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribIuiv(index==0)"); - } - else { - const GLfloat *v = ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; - FLUSH_CURRENT(ctx, 0); + const GLfloat *v = + get_current_attrib(ctx, index, "glGetVertexAttribIuiv"); + if (v != NULL) { /* XXX we don't have true integer-valued vertex attribs yet */ params[0] = (GLuint) v[0]; params[1] = (GLuint) v[1]; @@ -695,9 +725,9 @@ _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) return; } - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); - *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; + *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr; } @@ -958,7 +988,7 @@ _mesa_LockArraysEXT(GLint first, GLsizei count) ctx->Array.LockCount = count; ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; + ctx->Array.NewState |= VERT_BIT_ALL; } @@ -979,7 +1009,7 @@ _mesa_UnlockArraysEXT( void ) ctx->Array.LockFirst = 0; ctx->Array.LockCount = 0; ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; + ctx->Array.NewState |= VERT_BIT_ALL; } @@ -1065,6 +1095,35 @@ _mesa_PrimitiveRestartIndex(GLuint index) } +/** + * See GL_ARB_instanced_arrays. + * Note that the instance divisor only applies to generic arrays, not + * the legacy vertex arrays. + */ +void GLAPIENTRY +_mesa_VertexAttribDivisor(GLuint index, GLuint divisor) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (!ctx->Extensions.ARB_instanced_arrays) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()"); + return; + } + + if (index >= ctx->Const.VertexProgram.MaxAttribs) { + _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)", + index); + return; + } + + ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); + + ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].InstanceDivisor = divisor; +} + + + /** * Copy one client vertex array to another. */ @@ -1082,6 +1141,7 @@ _mesa_copy_client_array(struct gl_context *ctx, dst->Enabled = src->Enabled; dst->Normalized = src->Normalized; dst->Integer = src->Integer; + dst->InstanceDivisor = src->InstanceDivisor; dst->_ElementSize = src->_ElementSize; _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); dst->_MaxElement = src->_MaxElement; @@ -1119,18 +1179,18 @@ _mesa_print_arrays(struct gl_context *ctx) _mesa_update_array_object_max_element(ctx, arrayObj); printf("Array Object %u\n", arrayObj->Name); - if (arrayObj->Vertex.Enabled) - print_array("Vertex", -1, &arrayObj->Vertex); - if (arrayObj->Normal.Enabled) - print_array("Normal", -1, &arrayObj->Normal); - if (arrayObj->Color.Enabled) - print_array("Color", -1, &arrayObj->Color); - for (i = 0; i < Elements(arrayObj->TexCoord); i++) - if (arrayObj->TexCoord[i].Enabled) - print_array("TexCoord", i, &arrayObj->TexCoord[i]); - for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) - if (arrayObj->VertexAttrib[i].Enabled) - print_array("Attrib", i, &arrayObj->VertexAttrib[i]); + if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) + print_array("Vertex", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); + if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) + print_array("Normal", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); + if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) + print_array("Color", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) + if (arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) + print_array("TexCoord", i, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]); + for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) + if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) + print_array("Attrib", i, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]); printf(" _MaxElement = %u\n", arrayObj->_MaxElement); }