X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fvarray.c;h=be1c03cec2a88ac97e93f4bf628d3c256fe32650;hb=73b150c816c46a88e3e5d97f9b73ab0095f2bc60;hp=6bf3c485c73653cc84eb174d3fa78c10bb69ad6d;hpb=54a5ffbfa1f935c46642a9835f08983cc1fdfeed;p=mesa.git diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 6bf3c485c73..be1c03cec2a 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -30,6 +30,7 @@ #include "context.h" #include "enable.h" #include "enums.h" +#include "hash.h" #include "mtypes.h" #include "varray.h" #include "arrayobj.h" @@ -38,6 +39,8 @@ /** * Set the fields of a vertex array. + * Also do an error check for GL_ARB_vertex_array_object: check that + * all arrays reside in VBOs when using a vertex array object. * * \param array the array to update * \param dirtyBit which bit to set in ctx->Array.NewState for this array @@ -48,14 +51,26 @@ * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param ptr the address (or offset inside VBO) of the array data + * \return GL_TRUE if no error, GL_FALSE if error */ -static void +static GLboolean update_array(GLcontext *ctx, struct gl_client_array *array, GLbitfield dirtyBit, GLsizei elementSize, GLint size, GLenum type, GLenum format, GLsizei stride, GLboolean normalized, const GLvoid *ptr) { ASSERT(format == GL_RGBA || format == GL_BGRA); + + if (ctx->Array.ArrayObj->VBOonly && + ctx->Array.ArrayBufferObj->Name == 0) { + /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. + * Generate GL_INVALID_OPERATION if that's not true. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glVertex/Normal/EtcPointer(non-VBO array)"); + return GL_FALSE; + } + array->Size = size; array->Type = type; array->Format = format; @@ -70,6 +85,8 @@ update_array(GLcontext *ctx, struct gl_client_array *array, ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= dirtyBit; + + return GL_TRUE; } @@ -118,12 +135,14 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) break; #endif default: - _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, - elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, + elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr)) + return; if (ctx->Driver.VertexPointer) ctx->Driver.VertexPointer( ctx, size, type, stride, ptr ); @@ -168,12 +187,14 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) break; #endif default: - _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, - elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, + elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr)) + return; if (ctx->Driver.NormalPointer) ctx->Driver.NormalPointer( ctx, type, stride, ptr ); @@ -246,12 +267,14 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) break; #endif default: - _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, - elementSize, size, type, format, stride, GL_TRUE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, + elementSize, size, type, format, stride, GL_TRUE, ptr)) + return; if (ctx->Driver.ColorPointer) ctx->Driver.ColorPointer( ctx, size, type, stride, ptr ); @@ -282,8 +305,9 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) return; } - update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, - elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, + elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr)) + return; if (ctx->Driver.FogCoordPointer) ctx->Driver.FogCoordPointer( ctx, type, stride, ptr ); @@ -323,8 +347,9 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) return; } - update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, - elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, + elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr)) + return; if (ctx->Driver.IndexPointer) ctx->Driver.IndexPointer( ctx, type, stride, ptr ); @@ -393,12 +418,15 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, elementSize = size * sizeof(GLdouble); break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1, - elementSize, size, type, format, stride, GL_TRUE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, + _NEW_ARRAY_COLOR1, elementSize, size, type, + format, stride, GL_TRUE, ptr)) + return; if (ctx->Driver.SecondaryColorPointer) ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr ); @@ -452,13 +480,15 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, break; #endif default: - _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit], - _NEW_ARRAY_TEXCOORD(unit), - elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit], + _NEW_ARRAY_TEXCOORD(unit), + elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr)) + return; if (ctx->Driver.TexCoordPointer) ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); @@ -476,9 +506,10 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) return; } - update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, - sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA, - stride, GL_FALSE, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, + sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA, + stride, GL_FALSE, ptr)) + return; if (ctx->Driver.EdgeFlagPointer) ctx->Driver.EdgeFlagPointer( ctx, stride, ptr ); @@ -529,10 +560,11 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, { GLboolean normalized = GL_FALSE; GLsizei elementSize; + GLenum format; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); return; } @@ -552,6 +584,21 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, return; } + if (size == GL_BGRA) { + if (type != GL_UNSIGNED_BYTE) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glVertexAttribPointerNV(GL_BGRA/type)"); + return; + } + + format = GL_BGRA; + size = 4; + normalized = GL_TRUE; + } + else { + format = GL_RGBA; + } + /* check for valid 'type' and compute StrideB right away */ switch (type) { case GL_UNSIGNED_BYTE: @@ -568,13 +615,15 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, elementSize = size * sizeof(GLdouble); break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)", + _mesa_lookup_enum_by_nr(type)); return; } - update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], - _NEW_ARRAY_ATTRIB(index), - elementSize, size, type, GL_RGBA, stride, normalized, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], + _NEW_ARRAY_ATTRIB(index), + elementSize, size, type, format, stride, normalized, ptr)) + return; if (ctx->Driver.VertexAttribPointer) ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr ); @@ -621,9 +670,14 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, "glVertexAttribPointerARB(GL_BGRA/type)"); return; } + if (normalized != GL_TRUE) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glVertexAttribPointerARB(GL_BGRA/normalized)"); + return; + } + format = GL_BGRA; size = 4; - normalized = GL_TRUE; } else { format = GL_RGBA; @@ -666,9 +720,10 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, return; } - update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], - _NEW_ARRAY_ATTRIB(index), - elementSize, size, type, GL_RGBA, stride, normalized, ptr); + if (!update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], + _NEW_ARRAY_ATTRIB(index), + elementSize, size, type, format, stride, normalized, ptr)) + return; if (ctx->Driver.VertexAttribPointer) ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr); @@ -1043,6 +1098,29 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, } +/** + * Copy one client vertex array to another. + */ +void +_mesa_copy_client_array(GLcontext *ctx, + struct gl_client_array *dst, + struct gl_client_array *src) +{ + dst->Size = src->Size; + dst->Type = src->Type; + dst->Format = src->Format; + dst->Stride = src->Stride; + dst->StrideB = src->StrideB; + dst->Ptr = src->Ptr; + dst->Enabled = src->Enabled; + dst->Normalized = src->Normalized; + dst->_ElementSize = src->_ElementSize; + _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); + dst->_MaxElement = src->_MaxElement; +} + + + /** * Print vertex array's fields. */ @@ -1079,10 +1157,10 @@ _mesa_print_arrays(GLcontext *ctx) print_array("Normal", -1, &arrayObj->Normal); if (arrayObj->Color.Enabled) print_array("Color", -1, &arrayObj->Color); - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) + for (i = 0; i < Elements(arrayObj->TexCoord); i++) if (arrayObj->TexCoord[i].Enabled) print_array("TexCoord", i, &arrayObj->TexCoord[i]); - for (i = 0; i < VERT_ATTRIB_MAX; i++) + for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) if (arrayObj->VertexAttrib[i].Enabled) print_array("Attrib", i, &arrayObj->VertexAttrib[i]); _mesa_printf(" _MaxElement = %u\n", arrayObj->_MaxElement); @@ -1099,4 +1177,29 @@ _mesa_init_varray(GLcontext *ctx) _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, ctx->Array.DefaultArrayObj); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ + + ctx->Array.Objects = _mesa_NewHashTable(); +} + + +/** + * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). + */ +static void +delete_arrayobj_cb(GLuint id, void *data, void *userData) +{ + struct gl_array_object *arrayObj = (struct gl_array_object *) data; + GLcontext *ctx = (GLcontext *) userData; + _mesa_delete_array_object(ctx, arrayObj); +} + + +/** + * Free vertex array state for given context. + */ +void +_mesa_free_varray_data(GLcontext *ctx) +{ + _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); + _mesa_DeleteHashTable(ctx->Array.Objects); }