X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Farrayobj.c;h=46010223370398ab9cc9f33e25190b4a9f5d4406;hb=cfaf217135d8a8e903b3fbf380f18170df018f0c;hp=e078f69ff9561cc406508da852b48e386672b1d6;hpb=12cf98f5fc5eaa4743134387ce3f8e584aa20bc4;p=mesa.git diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index e078f69ff95..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,7 +63,7 @@ */ static INLINE struct gl_array_object * -lookup_arrayobj(GLcontext *ctx, GLuint id) +lookup_arrayobj(struct gl_context *ctx, GLuint id) { if (id == 0) return NULL; @@ -77,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; @@ -95,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 } @@ -105,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) @@ -121,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); } @@ -134,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) { @@ -189,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; @@ -212,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 ) { @@ -228,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++) { @@ -249,7 +255,7 @@ _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 */ @@ -263,7 +269,7 @@ 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 */ @@ -291,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 */ @@ -323,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; @@ -353,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); @@ -387,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"); @@ -404,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); } @@ -454,14 +491,14 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) /** * 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); @@ -487,12 +524,37 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE"); return; } + obj->VBOonly = vboOnly; save_array_object(ctx, obj); arrays[i] = first + i; } } +/** + * 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); +} + + /** * Determine if ID is the name of an array object. *