X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Farrayobj.c;h=46010223370398ab9cc9f33e25190b4a9f5d4406;hb=cfaf217135d8a8e903b3fbf380f18170df018f0c;hp=c03353b78f523db0e14987e4cb385f88c3f3ca52;hpb=bedf7fa49f549541fde2e19d2fbb6b8fe57ec124;p=mesa.git diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index c03353b78f5..46010223370 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -43,12 +43,14 @@ #include "hash.h" #include "imports.h" #include "context.h" +#include "mfeatures.h" #if FEATURE_ARB_vertex_buffer_object #include "bufferobj.h" #endif #include "arrayobj.h" #include "macros.h" -#include "glapi/dispatch.h" +#include "mtypes.h" +#include "main/dispatch.h" /** @@ -61,12 +63,13 @@ */ static INLINE struct gl_array_object * -lookup_arrayobj(GLcontext *ctx, GLuint id) +lookup_arrayobj(struct gl_context *ctx, GLuint id) { - return (id == 0) - ? NULL - : (struct gl_array_object *) _mesa_HashLookup(ctx->Shared->ArrayObjects, - id); + if (id == 0) + return NULL; + else + return (struct gl_array_object *) + _mesa_HashLookup(ctx->Array.Objects, id); } @@ -76,7 +79,7 @@ lookup_arrayobj(GLcontext *ctx, GLuint id) * This is done just prior to array object destruction. */ static void -unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) +unbind_array_object_vbos(struct gl_context *ctx, struct gl_array_object *obj) { GLuint i; @@ -94,6 +97,10 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) 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 } @@ -104,7 +111,7 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) * \c dd_function_table::NewArrayObject. */ struct gl_array_object * -_mesa_new_array_object( GLcontext *ctx, GLuint name ) +_mesa_new_array_object( struct gl_context *ctx, GLuint name ) { struct gl_array_object *obj = CALLOC_STRUCT(gl_array_object); if (obj) @@ -120,12 +127,12 @@ _mesa_new_array_object( GLcontext *ctx, GLuint name ) * \c dd_function_table::DeleteArrayObject. */ void -_mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) +_mesa_delete_array_object( struct gl_context *ctx, struct gl_array_object *obj ) { (void) ctx; unbind_array_object_vbos(ctx, obj); _glthread_DESTROY_MUTEX(obj->Mutex); - _mesa_free(obj); + free(obj); } @@ -133,7 +140,7 @@ _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) * Set ptr to arrayObj w/ reference counting. */ void -_mesa_reference_array_object(GLcontext *ctx, +_mesa_reference_array_object(struct gl_context *ctx, struct gl_array_object **ptr, struct gl_array_object *arrayObj) { @@ -188,7 +195,7 @@ _mesa_reference_array_object(GLcontext *ctx, static void -init_array(GLcontext *ctx, +init_array(struct gl_context *ctx, struct gl_client_array *array, GLint size, GLint type) { array->Size = size; @@ -211,7 +218,7 @@ init_array(GLcontext *ctx, * Initialize a gl_array_object's arrays. */ void -_mesa_initialize_array_object( GLcontext *ctx, +_mesa_initialize_array_object( struct gl_context *ctx, struct gl_array_object *obj, GLuint name ) { @@ -227,7 +234,7 @@ _mesa_initialize_array_object( GLcontext *ctx, 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->SecondaryColor, 3, 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++) { @@ -248,11 +255,11 @@ _mesa_initialize_array_object( GLcontext *ctx, * Add the given array object to the array object pool. */ static void -save_array_object( GLcontext *ctx, struct gl_array_object *obj ) +save_array_object( struct gl_context *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* insert into hash table */ - _mesa_HashInsert(ctx->Shared->ArrayObjects, obj->Name, obj); + _mesa_HashInsert(ctx->Array.Objects, obj->Name, obj); } } @@ -262,11 +269,11 @@ save_array_object( GLcontext *ctx, struct gl_array_object *obj ) * Do not deallocate the array object though. */ static void -remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) +remove_array_object( struct gl_context *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* remove from hash table */ - _mesa_HashRemove(ctx->Shared->ArrayObjects, obj->Name); + _mesa_HashRemove(ctx->Array.Objects, obj->Name); } } @@ -290,11 +297,11 @@ compute_max_element(struct gl_client_array *array) - (GLsizeiptrARB) array->Ptr + array->StrideB - array->_ElementSize) / array->StrideB; if (0) - _mesa_printf("%s Object %u Size %u MaxElement %u\n", - __FUNCTION__, - array->BufferObj->Name, - (GLuint) array->BufferObj->Size, - array->_MaxElement); + 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 */ @@ -322,7 +329,7 @@ update_min(GLuint min, struct gl_client_array *array) * Examine vertex arrays to update the gl_array_object::_MaxElement field. */ void -_mesa_update_array_object_max_element(GLcontext *ctx, +_mesa_update_array_object_max_element(struct gl_context *ctx, struct gl_array_object *arrayObj) { GLuint i, min = ~0; @@ -352,18 +359,15 @@ _mesa_update_array_object_max_element(GLcontext *ctx, /* API Functions */ /**********************************************************************/ + /** - * Bind a new array. - * - * \todo - * The binding could be done more efficiently by comparing the non-NULL - * pointers in the old and new objects. The only arrays that are "dirty" are - * the ones that are non-NULL in either object. + * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE(). + * \param genRequired specifies behavour when id was not generated with + * glGenVertexArrays(). */ -void GLAPIENTRY -_mesa_BindVertexArrayAPPLE( GLuint id ) +static void +bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired) { - GET_CURRENT_CONTEXT(ctx); struct gl_array_object * const oldObj = ctx->Array.ArrayObj; struct gl_array_object *newObj = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -386,8 +390,12 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) /* non-default array object */ newObj = lookup_arrayobj(ctx, id); if (!newObj) { - /* If this is a new array object id, allocate an array object now. - */ + if (genRequired) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexArray(id)"); + return; + } + + /* For APPLE version, generate a new array object now */ newObj = (*ctx->Driver.NewArrayObject)(ctx, id); if (!newObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); @@ -403,7 +411,37 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) /* Pass BindVertexArray call to device driver */ if (ctx->Driver.BindArrayObject && newObj) - (*ctx->Driver.BindArrayObject)( ctx, newObj ); + ctx->Driver.BindArrayObject(ctx, newObj); +} + + +/** + * ARB version of glBindVertexArray() + * This function behaves differently from glBindVertexArrayAPPLE() in + * that this function requires all ids to have been previously generated + * by glGenVertexArrays[APPLE](). + */ +void GLAPIENTRY +_mesa_BindVertexArray( GLuint id ) +{ + GET_CURRENT_CONTEXT(ctx); + bind_vertex_array(ctx, id, GL_TRUE); +} + + +/** + * Bind a new array. + * + * \todo + * The binding could be done more efficiently by comparing the non-NULL + * pointers in the old and new objects. The only arrays that are "dirty" are + * the ones that are non-NULL in either object. + */ +void GLAPIENTRY +_mesa_BindVertexArrayAPPLE( GLuint id ) +{ + GET_CURRENT_CONTEXT(ctx); + bind_vertex_array(ctx, id, GL_FALSE); } @@ -425,8 +463,6 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) return; } - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - for (i = 0; i < n; i++) { struct gl_array_object *obj = lookup_arrayobj(ctx, ids[i]); @@ -450,21 +486,19 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) _mesa_reference_array_object(ctx, &obj, NULL); } } - - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); } /** * Generate a set of unique array object IDs and store them in \c arrays. - * + * Helper for _mesa_GenVertexArrays[APPLE]() functions below. * \param n Number of IDs to generate. * \param arrays Array of \c n locations to store the IDs. + * \param vboOnly Will arrays have to reside in VBOs? */ -void GLAPIENTRY -_mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) +static void +gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, GLboolean vboOnly) { - GET_CURRENT_CONTEXT(ctx); GLuint first; GLint i; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -478,12 +512,7 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) return; } - /* - * This must be atomic (generation and allocation of array object IDs) - */ - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - - first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ArrayObjects, n); + first = _mesa_HashFindFreeKeyBlock(ctx->Array.Objects, n); /* Allocate new, empty array objects and return identifiers */ for (i = 0; i < n; i++) { @@ -492,15 +521,37 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) obj = (*ctx->Driver.NewArrayObject)( ctx, name ); if (!obj) { - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE"); return; } + obj->VBOonly = vboOnly; save_array_object(ctx, obj); arrays[i] = first + i; } +} + - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); +/** + * ARB version of glGenVertexArrays() + * All arrays will be required to live in VBOs. + */ +void GLAPIENTRY +_mesa_GenVertexArrays(GLsizei n, GLuint *arrays) +{ + GET_CURRENT_CONTEXT(ctx); + gen_vertex_arrays(ctx, n, arrays, GL_TRUE); +} + + +/** + * APPLE version of glGenVertexArraysAPPLE() + * Arrays may live in VBOs or ordinary memory. + */ +void GLAPIENTRY +_mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) +{ + GET_CURRENT_CONTEXT(ctx); + gen_vertex_arrays(ctx, n, arrays, GL_FALSE); } @@ -521,9 +572,7 @@ _mesa_IsVertexArrayAPPLE( GLuint id ) if (id == 0) return GL_FALSE; - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); obj = lookup_arrayobj(ctx, id); - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); return (obj != NULL) ? GL_TRUE : GL_FALSE; }