X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Farrayobj.c;h=5959260c27f9473f2e6c6b8799941b05e07de39d;hb=aab0ea935290cdbf6c74e4d001d4bbc8178fc14a;hp=0d64b7de8dd9e4c66b86d97d690914d4a7c1009a;hpb=f9995b30756140724f41daf963fa06167912be7f;p=mesa.git diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 0d64b7de8dd..5959260c27f 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -41,13 +41,15 @@ #include "glheader.h" #include "hash.h" +#include "image.h" #include "imports.h" #include "context.h" -#if FEATURE_ARB_vertex_buffer_object +#include "mfeatures.h" #include "bufferobj.h" -#endif #include "arrayobj.h" #include "macros.h" +#include "mtypes.h" +#include "varray.h" #include "main/dispatch.h" @@ -60,7 +62,7 @@ * non-existent. */ -static INLINE struct gl_array_object * +static inline struct gl_array_object * lookup_arrayobj(struct gl_context *ctx, GLuint id) { if (id == 0) @@ -81,24 +83,8 @@ unbind_array_object_vbos(struct gl_context *ctx, struct gl_array_object *obj) { GLuint i; - _mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->Weight.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->FogCoord.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL); - - for (i = 0; i < Elements(obj->TexCoord); i++) - _mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL); - for (i = 0; i < Elements(obj->VertexAttrib); i++) - _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL); - -#if FEATURE_point_size_array - _mesa_reference_buffer_object(ctx, &obj->PointSize.BufferObj, NULL); -#endif + _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj, NULL); } @@ -129,6 +115,7 @@ _mesa_delete_array_object( struct gl_context *ctx, struct gl_array_object *obj ) { (void) ctx; unbind_array_object_vbos(ctx, obj); + _mesa_reference_buffer_object(ctx, &obj->ElementArrayBufferObj, NULL); _glthread_DESTROY_MUTEX(obj->Mutex); free(obj); } @@ -136,14 +123,15 @@ _mesa_delete_array_object( struct gl_context *ctx, struct gl_array_object *obj ) /** * Set ptr to arrayObj w/ reference counting. + * Note: this should only be called from the _mesa_reference_array_object() + * inline function. */ void -_mesa_reference_array_object(struct gl_context *ctx, - struct gl_array_object **ptr, - struct gl_array_object *arrayObj) +_mesa_reference_array_object_(struct gl_context *ctx, + struct gl_array_object **ptr, + struct gl_array_object *arrayObj) { - if (*ptr == arrayObj) - return; + assert(*ptr != arrayObj); if (*ptr) { /* Unreference the old array object */ @@ -204,11 +192,11 @@ init_array(struct gl_context *ctx, array->Ptr = NULL; array->Enabled = GL_FALSE; array->Normalized = GL_FALSE; -#if FEATURE_ARB_vertex_buffer_object + array->Integer = GL_FALSE; + array->_ElementSize = size * _mesa_sizeof_type(type); /* Vertex array buffers */ _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Shared->NullBufferObj); -#endif } @@ -228,24 +216,37 @@ _mesa_initialize_array_object( struct gl_context *ctx, obj->RefCount = 1; /* Init the individual arrays */ - init_array(ctx, &obj->Vertex, 4, GL_FLOAT); - init_array(ctx, &obj->Weight, 1, GL_FLOAT); - init_array(ctx, &obj->Normal, 3, GL_FLOAT); - init_array(ctx, &obj->Color, 4, GL_FLOAT); - init_array(ctx, &obj->SecondaryColor, 4, GL_FLOAT); - init_array(ctx, &obj->FogCoord, 1, GL_FLOAT); - init_array(ctx, &obj->Index, 1, GL_FLOAT); - for (i = 0; i < Elements(obj->TexCoord); i++) { - init_array(ctx, &obj->TexCoord[i], 4, GL_FLOAT); - } - init_array(ctx, &obj->EdgeFlag, 1, GL_BOOL); for (i = 0; i < Elements(obj->VertexAttrib); i++) { - init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT); + switch (i) { + case VERT_ATTRIB_WEIGHT: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_WEIGHT], 1, GL_FLOAT); + break; + case VERT_ATTRIB_NORMAL: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_NORMAL], 3, GL_FLOAT); + break; + case VERT_ATTRIB_COLOR1: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR1], 3, GL_FLOAT); + break; + case VERT_ATTRIB_FOG: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_FOG], 1, GL_FLOAT); + break; + case VERT_ATTRIB_COLOR_INDEX: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX], 1, GL_FLOAT); + break; + case VERT_ATTRIB_EDGEFLAG: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_EDGEFLAG], 1, GL_BOOL); + break; + case VERT_ATTRIB_POINT_SIZE: + init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_POINT_SIZE], 1, GL_FLOAT); + break; + default: + init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT); + break; + } } -#if FEATURE_point_size_array - init_array(ctx, &obj->PointSize, 1, GL_FLOAT); -#endif + _mesa_reference_buffer_object(ctx, &obj->ElementArrayBufferObj, + ctx->Shared->NullBufferObj); } @@ -278,48 +279,26 @@ remove_array_object( struct gl_context *ctx, struct gl_array_object *obj ) /** - * Compute the index of the last array element that can be safely accessed - * in a vertex array. We can really only do this when the array lives in - * a VBO. - * The array->_MaxElement field will be updated. - * Later in glDrawArrays/Elements/etc we can do some bounds checking. - */ -static void -compute_max_element(struct gl_client_array *array) -{ - if (array->BufferObj->Name) { - /* Compute the max element we can access in the VBO without going - * out of bounds. - */ - array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - - (GLsizeiptrARB) array->Ptr + array->StrideB - - array->_ElementSize) / array->StrideB; - if (0) - printf("%s Object %u Size %u MaxElement %u\n", - __FUNCTION__, - array->BufferObj->Name, - (GLuint) array->BufferObj->Size, - array->_MaxElement); - } - else { - /* user-space array, no idea how big it is */ - array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ - } -} - - -/** - * Helper for update_arrays(). - * \return min(current min, array->_MaxElement). + * Helper for _mesa_update_array_object_max_element(). + * \return min(arrayObj->VertexAttrib[*]._MaxElement). */ static GLuint -update_min(GLuint min, struct gl_client_array *array) +compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled) { - compute_max_element(array); - if (array->Enabled) - return MIN2(min, array->_MaxElement); - else - return min; + GLuint min = ~((GLuint)0); + + while (enabled) { + struct gl_client_array *client_array; + GLint attrib = ffsll(enabled) - 1; + enabled ^= BITFIELD64_BIT(attrib); + + client_array = &arrayObj->VertexAttrib[attrib]; + assert(client_array->Enabled); + _mesa_update_array_max_element(client_array); + min = MIN2(min, client_array->_MaxElement); + } + + return min; } @@ -330,26 +309,17 @@ void _mesa_update_array_object_max_element(struct gl_context *ctx, struct gl_array_object *arrayObj) { - GLuint i, min = ~0; - - min = update_min(min, &arrayObj->Vertex); - min = update_min(min, &arrayObj->Weight); - min = update_min(min, &arrayObj->Normal); - min = update_min(min, &arrayObj->Color); - min = update_min(min, &arrayObj->SecondaryColor); - min = update_min(min, &arrayObj->FogCoord); - min = update_min(min, &arrayObj->Index); - min = update_min(min, &arrayObj->EdgeFlag); -#if FEATURE_point_size_array - min = update_min(min, &arrayObj->PointSize); -#endif - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) - min = update_min(min, &arrayObj->TexCoord[i]); - for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) - min = update_min(min, &arrayObj->VertexAttrib[i]); + GLbitfield64 enabled; + + if (!ctx->VertexProgram._Current || + ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { + enabled = _mesa_array_object_get_enabled_ff(arrayObj); + } else { + enabled = _mesa_array_object_get_enabled_arb(arrayObj); + } /* _MaxElement is one past the last legal array element */ - arrayObj->_MaxElement = min; + arrayObj->_MaxElement = compute_max_element(arrayObj, enabled); } @@ -399,12 +369,23 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); return; } + save_array_object(ctx, newObj); } + + if (!newObj->_Used) { + /* The "Interactions with APPLE_vertex_array_object" section of the + * GL_ARB_vertex_array_object spec says: + * + * "The first bind call, either BindVertexArray or + * BindVertexArrayAPPLE, determines the semantic of the object." + */ + newObj->ARBsemantics = genRequired; + newObj->_Used = GL_TRUE; + } } ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj); /* Pass BindVertexArray call to device driver */ @@ -472,7 +453,7 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) * becomes current." */ if ( obj == ctx->Array.ArrayObj ) { - CALL_BindVertexArrayAPPLE( ctx->Exec, (0) ); + _mesa_BindVertexArray(0); } /* The ID is immediately freed for re-use */ @@ -495,7 +476,7 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) * \param vboOnly Will arrays have to reside in VBOs? */ static void -gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, GLboolean vboOnly) +gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays) { GLuint first; GLint i; @@ -522,7 +503,6 @@ gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, GLboolean v _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE"); return; } - obj->VBOonly = vboOnly; save_array_object(ctx, obj); arrays[i] = first + i; } @@ -537,7 +517,7 @@ void GLAPIENTRY _mesa_GenVertexArrays(GLsizei n, GLuint *arrays) { GET_CURRENT_CONTEXT(ctx); - gen_vertex_arrays(ctx, n, arrays, GL_TRUE); + gen_vertex_arrays(ctx, n, arrays); } @@ -549,7 +529,7 @@ void GLAPIENTRY _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) { GET_CURRENT_CONTEXT(ctx); - gen_vertex_arrays(ctx, n, arrays, GL_FALSE); + gen_vertex_arrays(ctx, n, arrays); }